在 nix 的 libxml2 中包含一个目录

Include directory off-by one in libxml2 for nix

我正在捆绑依赖于 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 的解决方案来解决这个问题。来源不是我的,所以更改它们是我最不想做的事情。我看到另外两个选项。

首先,我可以在 buildPhase 期间触发的 makefile 中添加路径。但是,我不确定如何简单地抓住那条路。例如,当我需要 libxml2-2.9.9-dev 时,在我的派生中继承 libxml2 使 libxm2-2.9.9-bin 目录可用。我想我可以在 NIX_CFLAGS_COMPILE 路径上 grepsed,但我不想这样做。

我的首选解决方案是根据 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 实用程序并确保适当的环境来使其在 Nix 中工作设置变量以便它可以找到 libxml2。 Nix 可能有一堆 shell 脚本或其他东西可以帮助您以这种方式设置环境,因为这是一种常见的需求。

我通过在我的推导中定义一个 libxml 属性并将其添加到我的 buildInputs 来解决这个问题。新库只是旧库的 link,但路径已更正。这是推导的相关部分:

{ 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
      ''; };
}