我正在捆绑一个依赖于libxml
的.cpp
程序,但g++
找不到它。我已经完成了适当的步骤来使libxml
可用,但是目录结构与源预期的略有不同。我想了解这个问题的基于 nix 的解决方案。
编译器(来自 nix-shell 会话(说libxml
不在我的系统路径中:
fatal error: libxml/encoding.h: No such file or directory
#include <libxml/encoding.h>
但是,应该是。在我的 .nix 文件中,我确保包含libxml2
buildInputs = [ ... libxml2 ...];
我的nix-shell
环境确认该库存在:
NIX_CFLAGS_COMPILE= [...] -isystem /nix/store/zf1nyqyx2zd6y944ln2rxnhd5m4265n4-libxml2-2.9.9-dev/include [...]
如果我查看该目录,我发现搜索路径已关闭。文件的路径实际上是(相对于NIX_CFLAGS_COMPILE路径(:
libxml2/libxml/encoding.h
我发现我可以通过在编译命令中添加以下选项来补偿这个逐个路径错误:
-isystem /nix/store/zf1nyqyx2zd6y944ln2rxnhd5m4265n4-libxml2-2.9.9-dev/include/libxml2
(与NIX_CFLAGS_COMPILE
相同的路径,但从libxml2
目录开始。
鉴于这些信息,我想知道这个问题的基于 nix 的解决方案。来源不是我的,所以改变它们是我最不想做的事情。我看到另外两个选项。
首先,我可以在 makefile 中添加在buildPhase
期间触发的路径。但是,我不确定如何简单地抓住这条道路。例如,在我的派生中继承libxml2
使libxm2-2.9.9-bin
目录可用,当我需要libxml2-2.9.9-dev
时。我想我可以grep
或sed
NIX_CFLAGS_COMPILE
的道路上,但我宁愿不这样做。
我的首选解决方案是基于libxml2
进行一个简单的libxml
派生,并将其添加到我的 buildInputs 中,但这似乎也不简单。
尝试运行pkg-config --cflags libxml-2.0
以获取相应的编译器选项。
如果一切都配置正确,它将在您的计算机上找到相应的/nix/store/*-libxml2-2.9.9-dev/lib/pkgconfig/libxml-2.0.pc
文件,并从中提取所需的编译器选项。
您可以使用如下所示的单行代码调用 GCC:
g++ program.cpp $(pkg-config --libs --cflags libxml-2.0) -o program
这是一个通用的解决方案,不仅适用于 Nix,但你应该能够通过确保 PATH 上有pkg-config
实用程序并确保设置正确的环境变量以便它可以找到 libxml2 来让它在 Nix 中工作。 Nix 可能有一堆 shell 脚本或其他东西来帮助你以这种方式设置你的环境,因为这是一个常见的需求。
我通过在派生中定义一个libxml
属性并将其添加到我的buildInputs
中来解决这个问题。新库只是旧库的链接,但路径已更正。以下是派生的相关部分:
{ stdenv, libxml2, ... } : stdenv.mkDerivation
rec
{ buildInputs = [ libxml ];
libxml = stdenv.mkDerivation {
name = "libxml" ;
system = builtins.currentSystem;
outputs = [ "bin" "dev" "out" ];
phases = ["buildPhase"];
buildPhase =
''echo "my command out = $out"
echo ${libxml2.dev}
mkdir -p $out
mkdir -p $dev
mkdir -p $bin
ln -s ${libxml2.dev}/include/libxml2 $dev/include
ln -s ${libxml2.dev}/lib $dev/lib
''; };
}