[Haskell-cafe] OSX, ghci, dylib, what is the correct way?

Jason Dagit dagitj at gmail.com
Sun Jun 12 20:31:02 CEST 2011


I also asked this question on SO:

I wonder where I'll get more/better answers?

Read on for the question.  Thanks!

I need to build some C code and then reference that C code via the
FFI.  I would like to use my binding from inside ghci on osx.  On of
my constraints is that I cannot just hand the C sources to ghc in the
.cabal file.  This is due to a limitation with ghc/cabal that may be
fixed in the next release of ghc (but I want my code to work now and
on older releases).  See this [bug for details][1].

The gist of that bug is that the C code needs to be compiled with some
Objective-C modules and ghc misinterprets those as linker scripts.
I've tried many things and building the files myself with a makefile
is the only thing that has worked.  Really, this shouldn't be an issue
though because it should be the same as if I decided to use a external
C library that I didn't build myself.  For the sake of this issue,
let's pretend it's a separate C library that I can easily rebuild with
different options.

If I build the C library as a .a, then ghci comlains that it cannot
open the .dylib.  My first question is: Why does ghci need a .dylib
and does it really use it?

When I build a dylib I get a [segfault when loading the code into ghci][2].

Keep in mind, this binding works already on other platforms, both
linux and windows, and the binding works fine on osx when I'm
compiling instead of using ghci.  This problem specific to the
osx/ghci combo.

In that trace above, I'm using gdb but it crashes regardless of
whether I use gdb.  I tracked it down to the lines that cause the

    void _glfwClearWindowHints( void )
        memset( &_glfwLibrary.hints, 0, sizeof( _glfwLibrary.hints ) );

The trouble maker is that memset line, well actually the problem is
that when running inside ghci writing to the hints structure of
`_glfwLibrary` is a memory access violation.  The hints struct is
simply a bunch of ints.  It's very flat and simple, and thus I think
the problem is an issue either with how I'm linking things or with the
way ghci is loading the code.

Here are the bits of my makefile that I use to build the dylib and the .a:

    GCCFLAGS  := $(shell ghc --info | ghc -e "fmap read getContents >>=   \
                 putStrLn . unwords . read . Data.Maybe.fromJust . lookup \
                 \"Gcc Linker flags\"")
    FRAMEWORK := -framework Cocoa -framework OpenGL
    GLFW_FLAG := $(GCCFLAGS) -O2 -fno-common -Iglfw/include -Iglfw/lib    \
                 -Iglfw/lib/cocoa $(CFLAGS)

    all: $(BUILD_DIR)/static/libglfw.a $(BUILD_DIR)/dynamic/libglfw.dylib

    $(BUILD_DIR)/dynamic/libglfw.dylib: $(OBJS)
      $(CC) -dynamiclib -Wl,-single_module -compatibility_version 1       \
            -current_version 1                                            \
            $(GLFW_FLAG) -o $@ $(OBJS) $(GLFW_SRC) $(FRAMEWORK)

    $(BUILD_DIR)/static/libglfw.a: $(OBJS)
      ar -rcs $@ $(OBJS)

Most of the flags are taken straight from the GLFW Makefile so I think
they should be correct for that library.

The first line looks a bit weird but it's the solution I used for this

Platform details:

 - OSX 10.6.6
 - x86_64
 - 4 cores
 - GHC version 7.0.3 installed via Haskell Platform installer
 - Source repo: https://github.com/dagit/GLFW-b

  [1]: http://hackage.haskell.org/trac/ghc/ticket/5025
  [2]: http://hpaste.org/47457/segfault_in_ghci
  [3]: http://stackoverflow.com/questions/6217406/how-can-i-detect-if-ghc-is-set-to-generate-32bit-or-64bit-code-by-default

More information about the Haskell-Cafe mailing list