Skip to content

Instantly share code, notes, and snippets.

@mtolly
Created July 29, 2015 01:22
Show Gist options
  • Save mtolly/f17dac71b80adc1e8ce9 to your computer and use it in GitHub Desktop.
Save mtolly/f17dac71b80adc1e8ce9 to your computer and use it in GitHub Desktop.
Small example of compiling a Haskell Mac .dylib to be used from C
{-# LANGUAGE ForeignFunctionInterface #-}
module Adder where
import Foreign.C
adder :: CInt -> CInt -> IO CInt
adder x y = return $ x + y
foreign export ccall adder :: CInt -> CInt -> IO CInt
#!/bin/bash
ghc -o libadder.dylib -shared -static -fPIC Adder.hs StartEnd.c -lHSrts -lCffi
# -shared means to make a dylib.
# -static means use the static versions of ghc stuff.
# -lCffi links the static libCffi.a; -lffi would link the dynamic libffi.dylib
# ^ look inside $(ghc --print-libdir)/rts for details
gcc -o main main.c libadder.dylib -I"$(ghc --print-libdir)/include"
# alternatively, you can copy the headers into here like so:
# cp -R "$(ghc --print-libdir)/include"/* .
# gcc -o main main.c libadder.dylib
install_name_tool -change "@rpath/libadder.dylib" "@executable_path/libadder.dylib" main
#include "Adder_stub.h"
#include <stdio.h>
void HsStart(void);
void HsEnd(void);
int main()
{
HsStart();
printf("12 + 5 = %i\n", adder(12,5));
HsEnd();
return 0;
}
#include <stdlib.h>
#include "HsFFI.h"
void HsStart(void) {
hs_init(NULL, NULL);
}
void HsEnd(void) {
hs_exit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment