Setting DYLD_LIBRARY_PATH in nix-shell

Hello :slight_smile:

I’m trying to make a shell.nix for my Haskell library (on macOS) which loads a DLL at runtime, but am confused about how paths happen. Here’s my shell.nix:

{ pkgs ? import <nixpkgs> {} }:
let
  qtlzma = pkgs.callPackage ./qtlzma.nix {};
  buildInputs = with pkgs; [ cabal-install pkgconfig qtlzma ];
in
pkgs.mkShell {
  inherit buildInputs;
}

The DLL is in the qtlzma package. On my system it lives at /nix/store/jhfi6nq7rnqn83ivs52dvclmh890awzw-QtLZMA-master/lib/libqtlzma.dylib.

My cabal file has extra-libraries: qtlzma, and within nix-shell, cabal new-build successfully builds the library. How did cabal know where to find libqtlzma.dylib?

Within the same nix-shell cabal new-repl fails because it can’t find libqtlzma.dylib. Interestingly, it lists ~/.nix-profile/lib as a search directory (how did it know to look there?). But if I try:

pkgs.mkShell {
  inherit buildInputs;
  DYLD_LIBRARY_PATH = "${qtlzma}/lib";
}

DYLD_LIBRARY_PATH remains unset inside the nix-shell! Why?

Moreover, in Nix, what is the best way to develop projects depending on shared libraries?

Thanks in advance!

Firstly, DYLD_LIBRARY_PATH is almost never used on darwin. I suspect that the install_name of libqtlzma.dylib is incorrect resulting in problems when linking against it, make sure it’s the absolute path to the library and not relative or @rpath.

otool -D $qtlzma/lib/libqtlzma.dylib
/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-QtLZMA-master/lib/libqtlzma.dylib:
/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-QtLZMA-master/lib/libqtlzma.dylib

Libraries are linked using their absolute path and buildInputs is what will take care of setting up the build environment so it knows where to find the libraries without having to add flags explicilty. You can think of buildInputs = [ qtlzma ] it as the equivalent of eg.

$CXX -I $qtlzma/include -L $qtlzma/lib ...

That said, setting an environment variable like that should work fine.

{ pkgs ? import <nixpkgs> {} }
pkgs.mkShell {
  DYLD_LIBRARY_PATH = "/foo";
}
$ nix-shell --pure --run 'echo $DYLD_LIBRARY_PATH'
/foo
1 Like