Saturday, June 06, 2009

Loading object files into ghci

On Haskell-Cafe, Murray asked about loading objects associated with FFI imports in ghci.

FFI is Haskell's Foreign Function Interface and allows interoperability with other languages, e.g., calling into a C library from Haskell or using your Haskell module from a C program. For more examples, see the FFI cookbook.

GHC's interactive environment, invoked with ghci, evaluates Haskell code in a REPL, loads and runs compiled modules, and provides familiar debugger functionality such as stepping, tracing, and catching exceptions.

Consider the following simple Haskell program that comprises two modules: Even though our program is split into multiple modules, we need point ghci at the main module, and it will follow the other dependencies:

$ ghci hello.hs 
GHCi, version 6.10.1:  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 2] Compiling Message          ( Message.hs, interpreted )
[2 of 2] Compiling Main             ( hello.hs, interpreted )
Ok, modules loaded: Main, Message.
*Main> main
Hello, world!
(If you're invoking ghci from Cygwin, you'll want to use

With FFI, you have to hold ghci's hand a little. Consider the following shell script: The environment variable PREFIX is the path to the parent of the lib directory where your library lives. In my case, I ran ./configure --prefix=$PREFIX to ultimately install mylib in a non-standard location.

We might look for a directory named dist if building with Cabal.

The FFI gateway between my Haskell code and my C library is in a file named mylib.hs and compiles to mylib.o, whose path ghci needs to know in order to load all dependencies.

Finally, we invoke ghci. This particular program used hxt, the Haskell XML Toolbox, and mylib links against HDF5, the expat XML parser, and the single-precision FFTW.

For projects built with Cabal, the build system already knows all this information. With cabal-install, it's already possible to configure, build, test, and install Haskell packages. It'd be sweet to be able to easily load complex packages in ghci instead of having to resort to such hackery!

No comments: