Demonstration
Repository: https://gitlab.com/sampointon/crate2nix-cross-missing-target
Run nix build -f default.nix.
Build log showing the failure:
Running phase: unpackPhase
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking source archive /nix/store/xlsjn3anddd5jxzjs2bk3ifgbckqj3az-getrandom-0.3.3.tar.gz
source root is getrandom-0.3.3
setting SOURCE_DATE_EPOCH to timestamp 1153704088 of file "getrandom-0.3.3/tests/mod.rs"
Running phase: patchPhase
@nix { "action": "setPhase", "phase": "patchPhase" }
Running phase: updateAutotoolsGnuConfigScriptsPhase
@nix { "action": "setPhase", "phase": "updateAutotoolsGnuConfigScriptsPhase" }
Running phase: updateAutotoolsGnuConfigScriptsPhase
@nix { "action": "setPhase", "phase": "updateAutotoolsGnuConfigScriptsPhase" }
Running phase: configurePhase
@nix { "action": "setPhase", "phase": "configurePhase" }
Running cd .
Building build.rs (getrandom)
Running rustc --crate-name build_script_build build.rs --crate-type bin -C opt-level=3 -C codegen-units=1 --edition 2021 --cfg feature="default" --out-dir target/build/getrandom --emit=dep-info,link -L dependency=target/buildDeps --cap-lints allow --color always
cargo:rerun-if-changed=build.rs
Running phase: buildPhase
@nix { "action": "setPhase", "phase": "buildPhase" }
Building src/lib.rs (getrandom)
Running rustc --crate-name getrandom src/lib.rs --out-dir target/lib -L dependency=target/deps --cap-lints allow -C opt-level=3 -C codegen-units=1 --remap-path-prefix=/build=/ --extern cfg_if=/nix/store/d8va8c8kwbz66ppz5h0j4xabz0x48233-rust_cfg-if-1.0.3-wasm32-wasi-lib/lib/libcfg_if-a0f22aa586.rlib --cfg feature="default" --target wasm32-wasip2 --edition 2021 -C metadata=d5632c2b3e -C extra-filename=-d5632c2b3e --crate-type lib -L /build/getrandom-0.3.3/target/build/getrandom.out --color always
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `wasi`
--> src/backends/wasi_p2.rs:4:5
|
4 | use wasi::random::random::get_random_u64;
| ^^^^ use of unresolved module or unlinked crate `wasi`
|
= help: you might be missing a crate named `wasi`
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `wasi`
--> src/backends/wasi_p2.rs:20:9
|
20 | use wasi::random::random::get_random_u64;
| ^^^^ use of unresolved module or unlinked crate `wasi`
|
= help: you might be missing a crate named `wasi`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0433`.
Analysis
rustc has received --target wasm32-wasip2 and knows that that means os = wasi and env = p2, so it evaluates the guarded expressions (entirely correctly!). However, the target information being used for feature/dependency selection in Cargo.nix (which has been produced by the generated makeDefaultTarget function) has env = "gnu" hard-coded in it, rather than being inherited from stdenv.hostPlatform.rust.platform, which means that the platform guard checking for env = p2 in getrandom's Cargo.toml evaluates negatively (incorrectly!) and keeps the necessary deps from being added.
#362 may come from the same root cause manifesting differently (env being ignored leading to hostPlatform and buildPlatform appearing the same and so buildRustCrate decides not to add --target), though I'm not really sure about it - I was having difficulty following the thread of how platform information was flowing through the code before it got there, and hardcoding env is certainly (a) wrong and (b) explains the failure I saw, so I stopped trying to figure out any further.
Fixing
Not hardcoding env = "gnu", but of course that's a negative rather than a positive fix. I would guess that env ought to be inherited from platform.rust.platform similarly to arch and os, but I really don't know how this stuff works or how platforms are specified. It's not helped by wasm32-wasip2 being new and under-supported in Nixpkgs (see NixOS/nixpkgs#435954).
Demonstration
Repository: https://gitlab.com/sampointon/crate2nix-cross-missing-target
Run
nix build -f default.nix.Build log showing the failure:
Analysis
rustc has received
--target wasm32-wasip2and knows that that meansos=wasiandenv=p2, so it evaluates the guarded expressions (entirely correctly!). However, the target information being used for feature/dependency selection inCargo.nix(which has been produced by the generatedmakeDefaultTargetfunction) hasenv = "gnu"hard-coded in it, rather than being inherited fromstdenv.hostPlatform.rust.platform, which means that the platform guard checking forenv=p2ingetrandom'sCargo.tomlevaluates negatively (incorrectly!) and keeps the necessary deps from being added.#362 may come from the same root cause manifesting differently (
envbeing ignored leading tohostPlatformandbuildPlatformappearing the same and sobuildRustCratedecides not to add--target), though I'm not really sure about it - I was having difficulty following the thread of how platform information was flowing through the code before it got there, and hardcodingenvis certainly (a) wrong and (b) explains the failure I saw, so I stopped trying to figure out any further.Fixing
Not hardcoding
env = "gnu", but of course that's a negative rather than a positive fix. I would guess thatenvought to be inherited fromplatform.rust.platformsimilarly toarchandos, but I really don't know how this stuff works or how platforms are specified. It's not helped bywasm32-wasip2being new and under-supported in Nixpkgs (see NixOS/nixpkgs#435954).