在 NixOS 上构建时,Cabal 找不到外部库
Cabal can't find foreign library when building on NixOS
我正在尝试使用 cabal2nix 在 NixOS 上构建一个内部 Haskell 项目。它包装(并因此依赖于)一个外部库,该库在 Ubuntu 上可以通过 wget
源构建,然后 运行 make && make install && ldconfig
。因此,当 cabal 开始构建程序时,它显然能够找到合适的 header 文件(在 /usr/local/include/ta-lib
或 /usr/include/ta-lib
中)。
在 Nix 上,我理解的过程是设置一个 .nix 文件来指定如何获取和构建源代码,然后 Nix 设置隔离的构建环境。当我这样做时,外部库被适当地获取和构建。
当 Nix 运行配置步骤时,它看起来没问题:
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
将 --extra-include-dirs
和 --extra-lib-dirs
设置为 Nix 商店中的正确路径。但是,当它开始构建时,它会抱怨,
Setup: Missing dependency on a foreign library:
* Missing C library: ta_lib
不幸的是,我不明白 cabal 如何确定外国图书馆是否存在。我在这里 (Haskell how to resolve cabal error: Missing dependencies on foreign libraries?) 读到 cabal 将尝试构建和 link 一个 C 程序,该程序由它找到的每个 header 组成。所以,不知何故,它没有找到正确的库。
怎么了?这是否与 运行 ldconfig 的 Ubuntu 中的步骤有关?
问题是 ta_lib
依赖于系统数学库 m
,但默认情况下 link 并未编辑该库。您可以通过创建存根 C 程序来检查
echo "int main() { return 0; }" >test.c
并尝试 link 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
现在,当 Cabal 尝试确定库是否可用时,它会尝试 link 将其添加到存根测试程序,但由于所有这些未定义的符号,该尝试将失败。因此,Cabal 抱怨该库无法 linked(即使其路径已配置且 set-up 正确)。
要解决该问题,请将 m
库添加到项目的 Cabal 文件中的 extra-libraries
属性,如下所示:
extra-libraries: ta_lib, m
这应该使 Cabal 配置阶段成功。
我正在尝试使用 cabal2nix 在 NixOS 上构建一个内部 Haskell 项目。它包装(并因此依赖于)一个外部库,该库在 Ubuntu 上可以通过 wget
源构建,然后 运行 make && make install && ldconfig
。因此,当 cabal 开始构建程序时,它显然能够找到合适的 header 文件(在 /usr/local/include/ta-lib
或 /usr/include/ta-lib
中)。
在 Nix 上,我理解的过程是设置一个 .nix 文件来指定如何获取和构建源代码,然后 Nix 设置隔离的构建环境。当我这样做时,外部库被适当地获取和构建。
当 Nix 运行配置步骤时,它看起来没问题:
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
将 --extra-include-dirs
和 --extra-lib-dirs
设置为 Nix 商店中的正确路径。但是,当它开始构建时,它会抱怨,
Setup: Missing dependency on a foreign library:
* Missing C library: ta_lib
不幸的是,我不明白 cabal 如何确定外国图书馆是否存在。我在这里 (Haskell how to resolve cabal error: Missing dependencies on foreign libraries?) 读到 cabal 将尝试构建和 link 一个 C 程序,该程序由它找到的每个 header 组成。所以,不知何故,它没有找到正确的库。
怎么了?这是否与 运行 ldconfig 的 Ubuntu 中的步骤有关?
问题是 ta_lib
依赖于系统数学库 m
,但默认情况下 link 并未编辑该库。您可以通过创建存根 C 程序来检查
echo "int main() { return 0; }" >test.c
并尝试 link 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
现在,当 Cabal 尝试确定库是否可用时,它会尝试 link 将其添加到存根测试程序,但由于所有这些未定义的符号,该尝试将失败。因此,Cabal 抱怨该库无法 linked(即使其路径已配置且 set-up 正确)。
要解决该问题,请将 m
库添加到项目的 Cabal 文件中的 extra-libraries
属性,如下所示:
extra-libraries: ta_lib, m
这应该使 Cabal 配置阶段成功。