0

I'm trying to get an executable to work by just copying it directly from one Nixos host to another. It works/executes on only one of the hosts.

On old host (where it works):

[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)

On new host it's not finding the shared library:

[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


I do see a libpq.so file in the postgresql-lib directory on the new host though:

[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

I've got the [glibc gmp5 postgresql postgresql.lib zlib.dev zlib.out] packages installed in my environment.systemPackages.

  • Did you add the directory where libpq.so.5 is located to the LD_LIBRARY_PATH and start a new shell session? – Nasir Riley Jun 9 '19 at 19:46
  • Are you able to compile the executable from source, or is it only available in binary form? – Emmanuel Rosa Jun 10 '19 at 9:35
  • I have the source to recompile yes, I would hope that it would be portable none the less as long as the shared libraries are present? – Chris Stryczynski Jun 10 '19 at 9:39
1

Packages built by Nix usually rely on DT_RUNPATH entry in ELF files to locate shared libraries. You can use for example nix run -f . patchelf -c patchelf --print-rpath app to view the entries. In your case it will return something like this:

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

Since these are absolute paths, you will need to have the relevant paths in Nix store for the libraries to be found.

If you know the nixpkgs commit you used to build the program, you can run nix-build -f https://github.com/NixOS/nixpkgs/archive/${commit}.tar.gz -A postgresql.lib on the second computer to add the library to the store. But beware that unless you add it to GC root, it can be cleared by a garbage collector.

If you built your program as a Nix expression, it is pretty easy to export the whole closure and import it to another computer.

  • Thanks for the info! Not that I have the knowledge to understand what it means. But I think the conclusion is - executable are not necessarily portable if managed 'outside of' the Nix store. – Chris Stryczynski Aug 23 '19 at 23:25
  • Yeah. Unless you use static linking, you will need to have the libraries in the paths they are looked for. I tried elaborating on the issue some more. – Jan Tojnar Aug 24 '19 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.