Jak wysłać plik wykonywalny z Language.Haskell.Interpreter?

136

Miałem nadzieję, że wykorzystam interpreter Haskell, hintaby 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 PATHpliku nie powoduje problemu:

$ PATH=. Hello
Hello world

Jednak prosty program testowy z użyciem runInterpreterbomb, 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 TryHintniewiele 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 fsię z funkcją w, Test.hsktóra ma być interpretowana w czasie wykonywania. Test.hswygląda tak:

module Test where
f :: Int -> Int
f x = x + 1
Michael Fox
źródło
6
Nie mogę odtworzyć tego problemu. Kiedy uruchamiam, PATH= ./TryHintwszystko idzie gładko: drukuje kilka liczb, a następnie wychodzi. Używam też GHC 7.8.3. Jak budujesz TryHint?
Daniel Wagner,
7
Uważam również, że prawdopodobnie będzie to specyficzne dla OSX. Może chcesz otworzyć bilet na GHC za trackera jak wspomniano w komunikacie o błędzie (wszak niemożliwe było akurat).
MasterMastic
5
Nie mam pojęcia, co się dzieje z tym błędem, ale w każdym razie GHC zależy od wielu zasobów, którymi się przed nim nie ukrywasz PATH=., takich jak pliki interfejsu dla Prelude i wszystko, co przejściowo importuje, rzeczywiste pliki bibliotek base i ghc-prim i integer-gmp oraz settingsplik GHC . (Zasadniczo wszystko jest zainstalowane w /usr/lib/ghckatalogu lub w równoważnym katalogu instalacji).
Reid Barton
2
@MichaelFox statyczne łączenie interfejsu API GHC nie działa z nowym dynamicznym linkerem wprowadzonym w GHC 7.8, myślę, że: | (interaktywne wykonanie kodu wymaga teraz dynamicznych bibliotek)
bennofs
2
@bennofs, wygląda na to, że Twój komentarz jest prawie odpowiedzią, jeśli nieznacznie go przeredagujesz!
sclv

Odpowiedzi:

2

Wysyłanie pliku wykonywalnego za pomocą Language.Haskell.Interpreterwydaje się być idealne ze sposobem, który pokazałeś. Musisz ustawić PATHskrypt, 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).

Himanshu Mishra
źródło