可执行文件是否可以在引用不同 nixpkg 提交的不同 Nixos 主机之间移植?

可执行文件是否可以在引用不同 nixpkg 提交的不同 Nixos 主机之间移植?

我试图通过将可执行文件直接从一台 Nixos 主机复制到另一台主机来使其工作。它仅在一台主机上工作/执行。

在旧主机上(它可以工作的地方):

[root@XenonKiloCranberry:~/blog]# ldd app
    linux-vdso.so.1 (0x00007fffd68fb000)
    libm.so.6 => /nix/store/7gx4kiv5m0i7d7qkixq2cwzbr10lvxwc-glibc-2.27/lib/libm.so.6 (0x00007f591bf32000)
    libpq.so.5 => /nix/store/sf3jq8d81gx6fmxsi0mhagpgsgpnxf6m-postgresql-9.6.12-lib/lib/libpq.so.5 (0x00007f591bd03000)

在新主机上找不到共享库:

[root@XenonKiloCranberry:~/blog]# ldd /root/blog/app
    linux-vdso.so.1 (0x00007fff6cb89000)
    libm.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libm.so.6 (0x00007f927e00f000)
    libpq.so.5 => not found


不过,我确实libpq.so在新主机上的 postgresql-lib 目录中看到了一个文件:

[root@XenonKiloCranberry:~/blog]# ll /nix/store/1m0kd7v8yvf5vdmd2jm16w4aal234114-postgresql-9.6.13-lib/lib/libpq.so
lrwxrwxrwx 1 root root 12 Jan  1  1970 /nix/store/1m0kd7v8yvf5vdmd2jm16w4aal234114-postgresql-9.6.13-lib/lib/libpq.so -> libpq.so.5.9
[root@XenonKiloCranberry:~/blog]# ll /nix/var/nix/profiles/system/sw/lib/libpq.so.5
lrwxrwxrwx 1 root root 80 Jan  1  1970 /nix/var/nix/profiles/system/sw/lib/libpq.so.5 -> /nix/store/1m0kd7v8yvf5vdmd2jm16w4aal234114-postgresql-9.6.13-lib/lib/libpq.so.5

我已经将[glibc gmp5 postgresql postgresql.lib zlib.dev zlib.out]软件包安装在我的environment.systemPackages.

答案1

Nix 构建的包通常依赖DT_RUNPATHELF 文件中的条目来定位共享库。您可以使用例如nix run -f . patchelf -c patchelf --print-rpath app来查看条目。在你的情况下,它将返回类似这样的内容:

/nix/store/7gx4kiv5m0i7d7qkixq2cwzbr10lvxwc-glibc-2.27/lib:/nix/store/sf3jq8d81gx6fmxsi0mhagpgsgpnxf6m-postgresql-9.6.12-lib/lib

由于这些是绝对路径,因此您需要在 Nix 存储中拥有相关路径才能找到库。

如果您知道nixpkgs用于构建程序的提交,则可以nix-build -f https://github.com/NixOS/nixpkgs/archive/${commit}.tar.gz -A postgresql.lib在第二台计算机上运行以将库添加到存储中。但要注意,除非将其添加到 GC root,否则它可能会被垃圾收集器清除。

如果您将程序构建为 Nix 表达式,则很容易导出整个闭包并将其导入到另一台计算机上。

相关内容