136

I was hoping to embed a Haskell interpreter using hint so that I could write plugins in Haskell to use with my program. I don't want to have to ship the entire Haskell platform for my executables.

Normally, Haskell executables are pretty self-contained. For example, erasing the PATH does not cause a problem:

$ PATH=. Hello
Hello world

However, a simple test program using runInterpreter bombs if I erase the 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"

What libraries or executables have to be available in the environment for it to work?

otool doesn't give much guidance:

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)

The test code for TryHint does not do much:

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]

It just binds f to a function in Test.hs to be interpreted at run-time. Test.hs looks like this:

module Test where
f :: Int -> Int
f x = x + 1
Machavity
  • 30,841
  • 27
  • 92
  • 100
Michael Fox
  • 3,632
  • 1
  • 17
  • 27
  • 6
    I can't reproduce this problem. When I run `PATH= ./TryHint` everything goes smoothly: it prints a few numbers, then exits. I'm also using GHC 7.8.3. How are you building `TryHint`? – Daniel Wagner Jan 29 '15 at 02:44
  • 1
    What about `PATH=. TryHint` (note where the space is)? The executable `TryHint` should be in the current working directory. – ErikR Jan 29 '15 at 04:18
  • @user5402 I tried both. They're exactly the same. – Daniel Wagner Jan 29 '15 at 04:43
  • 1
    @DanielWagner I'm just compiling the normal way with ghc. Starting to suspect it's actually an OSX-specific issue. Dynamic linking works differently from Linux in ways I don't understand. – Michael Fox Jan 29 '15 at 04:54
  • 7
    I also believe it's likely to be specific to OSX. You might want to open a ticket at GHC's [tracker](https://ghc.haskell.org/trac/ghc/report) as mentioned in the error message (after all, the impossible *did* just happen). – MasterMastic Jan 29 '15 at 17:51
  • 5
    I have no idea what is going on with that error, but in any case GHC depends on a lot of resources which you are not hiding from it with `PATH=.`, such as the interface files for Prelude and everything it transitively imports, the actual library files for base and ghc-prim and integer-gmp, and the GHC `settings` file. (Basically, everything installed under `/usr/lib/ghc` or the equivalent directory for your installation.) – Reid Barton Jan 30 '15 at 18:51
  • 1
    @ReidBarton I couldn't think of how to test it before but with `mv /usr/local/Cellar/ghc /usr/local/Cellar/ghc.bak` I get `/usr/local/Cellar/ghc/7.8.4/lib/ghc-7.8.4/settings: openFile: does not exist (No such file or directory)`. I was hoping everything would be statically linked but it's not looking good. – Michael Fox Jan 30 '15 at 19:02
  • 2
    @MichaelFox statically linking the GHC API doesn't work with the new dynamic linker introduced in GHC 7.8, I think :| (interactive code execution now requires dynamic libraries) – bennofs Feb 13 '15 at 23:25
  • 2
    @bennofs it looks like your comment is almost an answer if you slightly reword it! – sclv Feb 20 '15 at 03:53
  • have you tried looking at the trace of system calls? It might help you find out where it hangs. In linux I would use strace, in OS X dtruss seems to be the equivalent. – Goens Jun 19 '15 at 14:50

1 Answers1

2

Shipping an executable with Language.Haskell.Interpreter seems to go perfect with the way you have shown. You have to set your PATH to the script you want to execute.

And as of side note, as mentioned by @bennofs in comments, Statically linking the GHC API doesn't work with the new dynamic linker introduced in GHC 7.8, (interactive code execution now requires dynamic libraries).

Himanshu Mishra
  • 8,510
  • 12
  • 37
  • 74