问题
I am trying to build an internal Haskell project on NixOS using cabal2nix. It wraps (and thus depends on) a foreign library which on Ubuntu one would build by wget
ting the source, then running make && make install && ldconfig
. Thus when cabal goes to build the program, it is apparently able to find the appropriate header files (which are in /usr/local/include/ta-lib
or /usr/include/ta-lib
).
On Nix, the process as I understand is to setup a .nix file to specify how to get and build the source, and then Nix sets up the isolated build environments. When I do this, the foreign library is fetched and built appropriately.
When Nix runs the configure step, it looks alright:
configureFlags: --verbose --prefix=/nix/store/fwpw03bd0c2m5yb7v2wc7g6f0qj912ra-talib-0.1.0.0 --libdir=$prefix/lib/$compiler --libsubdir=$pkgid --with-gcc=gcc --package-db=/tmp/nix-build-talib-0.1.0.0.drv-0/package.conf.d --ghc-option=-optl=-Wl,-rpath=/nix/store/fwpw03bd0c2m5yb7v2wc7g6f0qj912ra-talib-0.1.0.0/lib/ghc-7.10.2/talib-0.1.0.0 --enable-split-objs --disable-library-profiling --disable-executable-profiling --enable-shared --enable-library-vanilla --enable-executable-dynamic --enable-tests --extra-include-dirs=/nix/store/gvglncjgd5yif9bc03qalmp2mrjp524n-ta-lib-0.4.0/include --extra-lib-dirs=/nix/store/gvglncjgd5yif9bc03qalmp2mrjp524n-ta-lib-0.4.0/lib
With --extra-include-dirs
and --extra-lib-dirs
set to the correct paths in the Nix store. However, when it goes to build it complains with,
Setup: Missing dependency on a foreign library:
* Missing C library: ta_lib
Unfortunately I don't understand how cabal is determining whether the foreign library is present. I read here (Haskell how to resolve cabal error: Missing dependencies on foreign libraries?) that cabal will try to build and link a C program that consists of for each header it finds. So, somehow it is not finding the correct library.
What is wrong? Does this have to do with the step in Ubuntu of running ldconfig?
回答1:
The problem is that ta_lib
depends on the system math library m
, but that library isn't linked by default. You can check that by creating a stub C program
echo "int main() { return 0; }" >test.c
and trying to link that with ta_lib
:
$ nix-shell -p ta_lib --run "gcc test.c -lta_lib"
/nix/store/ghinzmxfm2s41nz8y873jlywwmcbw38l-ta-lib-0.4.0/lib/libta_lib.so: undefined reference to `sinh'
/nix/store/ghinzmxfm2s41nz8y873jlywwmcbw38l-ta-lib-0.4.0/lib/libta_lib.so: undefined reference to `sincos'
[...]
collect2: error: ld returned 1 exit status
Now, when Cabal tries to determine whether the library is available, it will attempt to link it to a stub test program, but that attempt will fail because of all those undefined symbol. Hence, Cabal complains that the library cannot be linked (even though its paths are configured and set-up correctly).
To remedy that issue, add the m
library to the extra-libraries
attribute in your project's Cabal file, like so:
extra-libraries: ta_lib, m
That should make the Cabal configure phase succeed.
来源:https://stackoverflow.com/questions/34457141/cabal-cant-find-foreign-library-when-building-on-nixos