Recently had some trouble with nix. I was trying to write a Haskell ffi wrap around the micro-ecc lib. After doing this successfully, I wanted my library to work if micro-ecc was correctly installed somewhere on your system. I had the following two directories:
$ ls
micro-ecc
hs-micro-ecc
In micro-ecc I had a fairly vanilla nix expression that looked like:
stdenv.mkDerivation {
name = "micro-ecc";
buildPhase = ''gcc stuff'';
installPhase = ''
mkdir -p $out/micro-ecc/{lib,include}
cp uECC.h $out/micro-ecc/include
cp libmicro-ecc.so $out/micro-ecc/include
'';
}
In hs-micro-ecc had a standard haskell ffi setup. I was getting all kinds of issues. Turns out it was the following:
- "installing" a library on your system means having the
.sofiles in a/libsubdirectory in your package, in addition to any.hfiles in a/includesub directory. This is standard faire and not necessarily nix related. - For haskell ffi setups that assume a library is installed somewhere, you need to put the name of the library in the
extra-librariesdirective of your.cabalfile. The name of this library should correspond to the name of the.sofile withlibprepended. So, for themicro-ecclibrary you needlibmicro-ecc.soinstalled somewhere. - Nix will ensure
libmicro-ecc.sois installed and provided to cabal if you use thecabal.mkDerivationand in there specifymicro-eccalaextraLibraries = [ micro-ecc ];. By doing this the/includeand/libdirectories will be included during linking via-Iand-L.
With the above, I was able to write my ffi wrappers with #include <micro-ecc/uECC.h> and foreign import ccall "uECC.h uECC_make_key" and everything worked fine.