This is a minimal example
This repos featues a cargo project with a:
- build.rs (which generates rust code: foobar.rs)
- src/main.rs (this includes the foobar.rs and executes it)
After compiling and running, one sees something like:
./result/bin/build_rs_example
1111hi from foobar.rs
In particular we look at OUT_DIR which is used in two compiles:
- build_script_run (build.rs) execution
- compile of (src/main.rs)
'cargo build', the legacy/official backend to build rust programs splits the build of this example crate into 3 program invocations, each having an individual set of environment variables:
- build the build.rs into build_script_build binary
- execution of build_script_build
- build of build_rs_example (src/main.rs)
so we end up with 3 distinct steps to build the binary.
This project is compiled by 4 different nix abstractions:
- cargo2nix 0.12.0
- crate2nix 0.14.1
- crane 0.23.0
- naersk 8d97452673640eb7fabe428e8b6a425bc355008b (Jan 2026)
Each directory contains a flake and you can simply run:
nix build .
A special role has the cargo (nix-backend) because it wants to be as close to cargo legacy as possible
- https://github.com/nixcloud/cargo (libnix branch, 0.89 rustc)
A key problem is that if we also split the build in 3 phases the nix guarantee of a 'clean build' becomes really hard.
- 3 of the 4 implementations outsource this problem by calling
cargo buildand - only
crate2nixbuilds build.rs into build_script_build but runs it inside the same mkDerivation (in the configurePhase) and later uses it in the buildPhase