I recently had some trouble getting ctypes working, so I thought I’d share my solution.
I found the Real World OCaml chapter on FFIs, and I tried following their advice first. They suggest:
brew install libffi opam install ctypes
But it doesn’t quite work. For one, you also need to install ctypes-foreign. For two, the brew installation of libffi doesn’t automatically install itself globally, so ctypes can’t find it.
Here’s the right incantation:
brew install libffi cd /usr/lib/ sudo mv libffi.dylib libffi.dylib.orig sudo ln -s /usr/local/opt/libffi/lib/libffi.dylib LIBFFI_CFLAGS=-I/usr/include/ffi CFLAGS=-I/usr/include/ffi opam install ctypes ctypes-foreign
Now, this is merely a good start. Once I had this much working, I still couldn’t get OCaml to call C functions! It came down to a bear of a linking issue… no combination of LD_PATH and LD_LIBRARY_PATH and LD_PRELOAD would help, nor would -lflags -cclib,-L. I just couldn’t get ctypes to see my shared library! I finally found an option to ld that does the trick: -force_load. Here’s my build line:
ocamlbuild -no-hygiene -pkg ctypes.foreign -lflags "-cclib -force_load /path/to/libfoo.a" bar.native
I imagine you can get away without -no-hygiene; I couldn’t get corebuild to work at all.
In any case, special thanks to Arjun Narayan for helping me debug this, and to Spiros Eliopolous for
mockery absolutely nothing.