Skip to content

nix-community/nix-ld-rs

Repository files navigation

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 (on x86_64-linux and aarch64-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.