Probably, the standard user-installation script of nix modifies .bash_profile to add its bin/ into PATH, but does not do something analogous for libraries.

My nix setup:

The only thing I have asked the root to do for me was: mkdir -m 0755 /nix && chown ivan /nix, otherwise I've followed the standard simple nix installation procedure. So now I can use custom programs from nix packages. I couldn't do this nicely without any help from the root at all, i.e., without /nix/, because /nix/ was not available for me; I could of course use another directory, but then the pre-built binary packages wouldn't be valid and all packages would have to be rebuilt, according to the nix documentation. In my case, it was simpler to ask for /nix/ for me.

Another thing I've done is adding to ~/.bash_profile:

export NIX_CONF_DIR=/nix/etc/nix

so that I can edit nix.conf. (It was supposed to be in the root-controlled /etc/ otherwise. I did it because I wanted to build-max-jobs and build-cores settings in it.)

I've never heard of nix-env, not to mention nix.conf. What OS is this? Also, what do you repeated references to nix mean? I've only ever heard it used as an abbreviation to Unix, but it seems you are using it in a more specific context.
– Faheem MithaMar 31 '15 at 19:43

3

@FaheemMitha I thought the tag had some description so I don't need to explain this in the post. But apparently the tag has no description. Oh, well, so I have to put in some links. nix is a modern package manager, and nixOS is a distro, and Hydra is a system for constantly rebuilding nix packages, and nixOps is a tool to manage an infrastructure (a network of several hosts) declaratively, and disNix to manage a set of services declaratively (on top of an infrastructure). guix is a GNU offspring of nix, with a distro (promoted as 100%libre IIC
– imz -- Ivan ZakharyaschevMar 31 '15 at 20:56

1

I see. Thanks for the information. I have heard of none of those except guix.
– Faheem MithaMar 31 '15 at 20:59

So, it seems to be not an easy job if you want to load libraries from nix when running your own binaries...

For now, I'm commenting out

export LD_LIBRARY_PATH="$NIX_LINK"/lib

and doing in the shell session:

$ unset LD_LIBRARY_PATH
$ export LD_LIBRARY_PATH

Need to think more. (Read about __vdso_time: invalid mode for dlopen(): having another glibc in LD_LIBRARY_PATH is expected to crash, because your ld-linux-x86-64.so.2 will not match your libc.so.6. Having multiple versions of glibc on a single system is possible, but slightly tricky, as explained in this answer.)

The needed solution: patchelf

So, the path to the dynamic linker is hard-coded in the binary. And the dynamic linker being used is from the system (from the host glibc), not from nix. And because the dynamic linker doesn't match the glibc which we want and need to use, it doesn't work.

If--like in my imperfect case--some of the libraries are taken from nix, but some are taken from the host system (because I haven't installed them with nix-env -i), you have to specify both the path to the nix libs, and to your host system libs in LD_LIBRARY_PATH (it completely overrides the default search path).

additional step: patchelf for the library search path

(from the patchelf page)

Likewise, you can change the RPATH, the linker search path embedded into executables and dynamic libraries:

patchelf --set-rpath /opt/my-libs/lib:/foo/lib program

This causes the dynamic linker to search in /opt/my-libs/lib and /foo/lib for the shared libraries needed by program. Of course, you could also set the environment variable LD_LIBRARY_PATH, but that’s often inconvenient as it requires a wrapper script to set up the environment.

If you install packages locally using nix-env -i, all your .so files are stored in ~/.nix-profile/lib/.

If you install packages globally by specifying them in /etc/nixos/configuration.nix, your corresponding .so files can be found in /nix/var/nix/profiles/system/sw/lib/. More correctly, only symlinks to corresponding files somewhere in /nix/store/ are in that directory.

I'm not sure how to find a corresponding package for a missing file in general, but you can google the name of the .so file and install the corresponding package and try to run your executable with a custom LD_LIBRARY_PATH again.