Setting environment variables required during `buildPhase`


What is the correct way of setting buildPhase environment variables?

The gory details

It works in a nix-shell

I have a shell.nix which I used to provide dependencies while hacking on some Rust code. It contains (among much other noise)

pkgs.stdenv.mkDerivation {

  buildInputs = [

  LD_LIBRARY_PATH = "${pkgs.stdenv.lib.makeLibraryPath buildInputs}";
  HDF5_DIR = pkgs.symlinkJoin { name = "hdf5"; paths = [ pkgs.hdf5 ]; };

  # Needed if using bindgen to wrap C libraries in Rust
  LIBCLANG_PATH = "${pkgs.llvmPackages_11.libclang}/lib";


This allowed me to run a nix-shell in which I successfully compiled the code by hand with cargo, giving me executables which successfully used HDF5 and the bindgen-generated bindings at runtime.

It works in nix develop

I am trying to transition this to a flake.

By specifying the above environment variables inside devShell = pkgs.mkShell rec { ... }, in exactly the same way as above, I can successfully compile and run with cargo build/run inside a nix develop shell.

I can’t get the flake to build successfully

nix build and friends fail with errors like

builder for '/nix/store/nxpqj6kllc5c1nmzk6ipk1idj0frxk36-hmm.drv' failed with exit code 101; last 10 log lines:
  no configure script, doing nothing
  error: failed to get `hdf5` as a dependency of package `hmm v0.1.0 (/build/source)`
  Caused by:
    failed to create directory `/homeless-shelter/.cargo/registry/index/`
  Caused by:
    Permission denied (os error 13)

where the buildPhase is set to cargo build --release.


What is the best way to make these environment variables available during buildPhase?

How can I minimize code duplication between package.whatever and devShell, when setting these variables?

Setting environment variables that way should work in buildPhase just fine (try echoing them there).

I suspect your issue is rather

Which is probably caused by $HOME being set to non-existing /homeless-shelter by default for reproducibility reasons and cargo cannot write there.

Try calling export HOME=$TEMPDIR before running cargo build.


That explains a lot. Thank you.

It leaves me with a copypasta of the lines setting those variables, between my package and my devShell. Can that be mitigated?

It now fails, persistently, with

builder for '/nix/store/fvs7vi7ypk3m5ii7k2fw729q0rh50k0g-hmm.drv' failed with exit code 101; last 10 log lines:
  Caused by:
    failed to fetch ``
  Caused by:
    network failure seems to have happened
    if a proxy or similar is necessary `net.git-fetch-with-cli` may help here
  Caused by:
    failed to resolve address for Name or service not known; class=Net (12)
  • Pinging succeeeds.
  • wgeting the URL which failed to fetch also works.
  • I’ve been watching the builds fetch all day.

You can probably just use your package as devShell, potentially using overrideAttrs if you need to change something for the devShell.

As for the network failure, Nix builds are running in a sandbox without network access (this has been the case long before flakes). You will need to use rustPlatform.buildRustPackage or naersk.

I had naersk set aside in my too-much-magic-for-now box, but after seeing how much hassle it is to get rustPlatform to use a non-prehistoric version of the rust toolchain, I decided to give naersk a go.

I was trying to use the stable 1.50.0 channel of rustOverlay, which errored with

error: the `--out-dir` flag is unstable, and only available on the nightly channel of Cargo, but this is the `stable` channel

while the naersk docs state that

Note: naersk relies on the --out-dir out option 

So, would it be correct to conclude that naersk simply can’t be used with a stable rustOverlay?

At this point, you should probably start a new thread since this one is resolved.

But I would expect naersk to work in stable rust since we are able to use it with rust 1.49 from nixpkgs: