Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating Haskell shared libraries on OS X

I'm trying to create a shared library from Haskell source code.

I've tried following the instruction here: http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/ but I'm just not having any luck.

When I compile with Haskell 64-bit (ghc 7.0.4 from 2011.4.0.0) I get the following error:

ld: pointer in read-only segment not allowed in slidable image, used in 
                 ___gmpn_modexact_1c_odd 

As an alternative I also tried the 32-bit version, and depending on the exact flags I use to link get errors such as:

Library not loaded: /usr/local/lib/ghc-7.0.4/base-4.3.1.0/libHSbase-4.3.1.0-ghc7.0.4.dylib

I did manage to get a little further by adding -lHSrts to the linker line. This got me to the point of successfully linking and loading the library, but I'm then unable to find the function name using dlsym (or manually using nm | grep)

Any hints would be greatly appreciated, an example make file, or build line that has successfully built (and used) a shared library on OS X would be appreciated. I'm quite new to Haskell and don't know if I should keep banging my head assuming that the problem is on my end, or for various reasons I shouldn't expect this to work on OS X.

A git repo with all the combinations I've tried is available here: https://github.com/bennoleslie/haskell-shared-example I did manage to get something working for 32-bit ghc, but not 64-bit yet.

like image 679
benno Avatar asked Mar 24 '12 06:03

benno


2 Answers

It is possible to create working shared libraries on 64-bit OS X, with the latest Haskell Platform release (2012.4 64bit)

The invocation line works for me:

ghc -O2 --make \
-no-hs-main -optl '-shared' -optc '-DMODULE=Test' \
-o libTest.so Test.hs module_init.c

module_init.c should be something like:

#define CAT(a,b) XCAT(a,b)
#define XCAT(a,b) a ## b
#define STR(a) XSTR(a)
#define XSTR(a) #a

#include <HsFFI.h>

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();
}

This git repo: https://github.com/bennoleslie/haskell-shared-example contains a working example.

All credit goes to this original source: http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/

like image 182
benno Avatar answered Nov 03 '22 18:11

benno


You might want to try the ghc port in Homebrew -- https://github.com/mxcl/homebrew/blob/master/Library/Formula/ghc.rb

like image 1
hd1 Avatar answered Nov 03 '22 18:11

hd1