Это не полный ответ, но это большая часть пути.Это не слишком сложно:
Среда выполнения Haskell - это просто библиотека, которую вы можете найти в вашей установке GHC.На моем Mac он находится в $PREFIX/lib/ghc-$VERSION/rts
, где $PREFIX
- это префикс установки GHC (например, /
, /usr
, /usr/local
и т. Д. - исполняемый файл компилятора должен быть $PREFIX/bin/ghc
).Вам нужно использовать одну из разделяемых библиотек (для меня они называются .dylib
s).Однако ни среда выполнения Haskell, ни скомпилированный код Haskell не содержат main
.GHC создает файл-заглушку C:
#include "Rts.h"
extern StgClosure ZCMain_main_closure;
int main(int argc, char *argv[])
{
RtsConfig __conf = defaultRtsConfig;
__conf.rts_opts_enabled = RtsOptsSafeOnly;
__conf.rts_opts_suggestions = true;
__conf.rts_hs_main = true;
return hs_main(argc,argv,&ZCMain_main_closure,__conf);
}
, где ZCMain_main_closure
относится к действию main
, написанному на Haskell, а hs_main
относится к символу из RTS.Вам нужно будет скомпилировать это в битовый код с clang
, скомпилировать код Haskell с ghc
, llvm-link
их в один большой .bc
, а затем передать его в GraalVM lli
.С учетом вышеприведенного в c_main.c
, поместите пример программы в Main.hs
:
main = putStrLn "Hello, World!"
Компиляция и ссылка:
$ clang -emit-llvm -I/usr/local/lib/ghc-8.6.5/include -c c_main.c
# Change -I path as needed
$ ghc -fllvm -keep-llvm-files -S Main.hs
$ llvm-link Main.ll c_main.bc -o prog.bc
Теперь, в идеальном мире, будет работать следующее:
$ lli --lib /usr/local/lib/ghc-8.6.5/rts/libHSrts-ghc8.6.5.dylib \
--lib /usr/local/lib/ghc-8.6.5/base-4.12.0.0/libHSbase-4.12.0.0-ghc8.6.5.dylib \
prog.bc
# Maybe you need more of the base libraries
# It's kind of hard to test because it doesn't work, anyway
Однако это не работает, потому что библиотеки имеют взаимные зависимости.base
, написанный в основном на Хаскеле, нуждается в RTS.RTS подключается к base
для связи с Haskell (например, с исключениями).GraalVM пытается dlopen
их по одному с RTLD_NOW
, который пытается и не может строго разрешить символы.Для этого нужно будет использовать RTLD_LAZY
.Это должно быть легко исправимо в GraalVM.