Shared Haskell .so library with GHC 6.10.4 and Cabal

I wanted to extend an app written in ANSI C with a functionality written in Haskell. This can be somewhat complicated process. If you use GHC 6.12.1 or newer it can supposedly be easily done with -shared flag. Well, I’m not sure how it works there, but installing GHC 6.12.1 is a painful process. Instead I wanted to do the same with GHC 6.10.4. Turns out it can be done with a simple Makefile like this:

shared:
      ghc -O --make \
           -no-hs-main -optl '-shared' -optc '-DMODULE=HaskellExts' \
           -o HaskellExts.so src/HaskellExts.hs src/module_init.c

module_init.c is also pretty simple and generic:
#define CAT(a,b) XCAT(a,b)
#define XCAT(a,b) a ## b
#define STR(a) XSTR(a)
#define XSTR(a) #a

#include

extern void CAT (__stginit_, MODULE) (void);

static void library_init (void) __attribute__ ((constructor));
static void
library_init (void)
{
      /* This seems to be a no-op, but it makes the GHCRTS envvar work. */
      static char *argv[] = { STR (MODULE) ".so", 0 }, **argv_ = argv;
      static int argc = 1;
     
      hs_init (&argc, &argv_);
      hs_add_root (CAT (__stginit_, MODULE));
}

static void library_exit (void) __attribute__ ((destructor));
static void
library_exit (void)
{
hs_exit ();
}

I took both from http://wiki.python.org/moin/PythonVsHaskell.

Now, this method works in general. However, I wanted to make a .cabal package description, because cabal-install handles some common tasks (like pulling dependencies and cleaning) automatically. This turned out to be little tricky. I had to cheat: the shared library is actually build as executable. Here is the core part of .cabal:

executable HaskellExts.so
      build-depends: base == 4.*, directory == 1.0.* , filepath == 1.1.*, edit-distance == 0.1.2.*
      hs-source-dirs: src
      ghc-options: -optl-shared -optc-DMODULE=HaskellExts -no-hs-main
      main-is: HaskellExts.hs
      c-sources: src/module_init.c
      include-dirs: src
      install-includes: HaskellExts.h
      cc-options: -DMODULE=HaskellExts -shared
      ld-options: -shared

I’m not sure it is the minimal configuration that works. But it works for me so I’m happy with it. The whole code is available here: http://dl.dropbox.com/u/1479187/blog/killer-haskell-exts.7z

About these ads

~ by Tener on 03/01/2010.

2 Responses to “Shared Haskell .so library with GHC 6.10.4 and Cabal”

  1. This will work on Windows and Linux, but not MacOs X. You need to build the development version of ghc for the latter.

    • Frankly speaking, I didn’t even know it’ll work on Windows. It worked for me on Linux tough.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: