Miałem nadzieję, że wykorzystam interpreter Haskell, hint
aby móc pisać wtyczki w Haskell do wykorzystania w moim programie. Nie chcę wysyłać całej platformy Haskell dla moich plików wykonywalnych.
Zwykle pliki wykonywalne Haskella są dość niezależne. Na przykład usunięcie PATH
pliku nie powoduje problemu:
$ PATH=. Hello
Hello world
Jednak prosty program testowy z użyciem runInterpreter
bomb, jeśli skasuję PATH
:
$ PATH=. TryHint
GhcException "panic! (the 'impossible' happened)\n (GHC version 7.8.3 for x86_64-apple-darwin):\n\tDynamic linker not initialised\n\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\n"
Jakie biblioteki lub pliki wykonywalne muszą być dostępne w środowisku, aby działało?
otool
nie daje wielu wskazówek:
otool -L TryHint
TryHint:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
/usr/local/lib/libgmp.10.dylib (compatibility version 13.0.0, current version 13.0.0)
Kod testowy dla TryHint
niewiele robi:
import Control.Monad
import Language.Haskell.Interpreter
main = do
f <- runInterpreter $ loadModules ["Test"] >> setTopLevelModules ["Test"] >> interpret "f" (as :: Int -> Int)
case f of
Left e -> print e
Right r -> mapM_ (print . r) [1..10]
Po prostu wiąże f
się z funkcją w, Test.hs
która ma być interpretowana w czasie wykonywania. Test.hs
wygląda tak:
module Test where
f :: Int -> Int
f x = x + 1
PATH= ./TryHint
wszystko idzie gładko: drukuje kilka liczb, a następnie wychodzi. Używam też GHC 7.8.3. Jak budujeszTryHint
?PATH=.
, takich jak pliki interfejsu dla Prelude i wszystko, co przejściowo importuje, rzeczywiste pliki bibliotek base i ghc-prim i integer-gmp orazsettings
plik GHC . (Zasadniczo wszystko jest zainstalowane w/usr/lib/ghc
katalogu lub w równoważnym katalogu instalacji).Odpowiedzi:
Wysyłanie pliku wykonywalnego za pomocą
Language.Haskell.Interpreter
wydaje się być idealne ze sposobem, który pokazałeś. Musisz ustawićPATH
skrypt, który chcesz wykonać.Na marginesie, jak wspomniał @bennofs w komentarzach, statyczne łączenie interfejsu API GHC nie działa z nowym dynamicznym linkerem wprowadzonym w GHC 7.8 (interaktywne wykonanie kodu wymaga teraz bibliotek dynamicznych).
źródło