nix-ld-rs
Run unpatched dynamic binaries on NixOS. This is a rewrite of nix-ld in Rust, with extra functionalities. It's intended to be upstreamed at some point.
Usage
nix-ld-rs
is a drop-in replacement for nix-ld
.
It honors the following environment variables:
NIX_LD
NIX_LD_{system}
NIX_LD_LIBRARY_PATH
NIX_LD_LIBRARY_PATH_{system}
NIX_LD_LOG
(error, warn, info, debug, trace)
Here {system}
is the value of the Nix system
with dashes replaced with underscores, like x86_64_linux
. You can also run nix-ld-rs
directly for a list.
Extra functionalities
NIX_LD_LIBRARY_PATH
doesn't affect child processes (onx86_64-linux
andaarch64-linux
)- For example, shell environments spawned by the binary VSCode Server no longer get polluted
Development
The included devShell
provides all dependencies required to build the project. It's recommended to set up transparent emulation using binfmt-misc so you can run tests on all supported platforms:
{
# x86_64-linux, i686-linux, aarch64-linux
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
}
Run cargo test
or cargo nextest run
to run the integration tests, and just test
to run them on all supported platforms (binfmt required).
Current behavior
Launch | Seen by ld.so | Seen by getenv() and children (a) | ||||
---|---|---|---|---|---|---|
NIX_LD_LIBRARY_PATH | LD_LIBRARY_PATH | NIX_LD_LIBRARY_PATH | LD_LIBRARY_PATH | NIX_LD_LIBRARY_PATH | LD_LIBRARY_PATH | |
1 | (unset) | (unset) | (unset) | "/run/current-system/sw/share/nix-ld/lib" | (unset) | "" (b) |
2 | (unset) | "/some/lib" | (unset) | "/some/lib:/run/current-system/sw/share/nix-ld/lib" | (unset) | "/some/lib" |
3 | "/some/nix/ld/lib" | (unset) | (unset) | "/some/nix/ld/lib" | "/some/nix/ld/lib" | (unset) |
4 | "/some/nix/ld/lib" | "/some/lib" | "/some/nix/ld/lib" | "/some/lib:/some/nix/ld/lib" | "/some/nix/ld/lib" | "/some/lib" |
(a) On X86-64 and AArch64 only (see src/arch.rs
). On other platforms, the "Seen by ld.so" state will persist.
(b) The variable will be present but set to an empty string.