buildRustCrate: remap crate source root to /<crateName>-<version>
buildRustCrate passes `--remap-path-prefix=$NIX_BUILD_TOP=/` so the sandbox build directory is not embedded in compiled artifacts. The resulting source path is `/$sourceRoot/src/...` — which works out to `/<crateName>-<version>/src/...` only because fetchCrate happens to unpack to a directory named after the crate. When `src` is supplied directly — `lib.fileset.toSource` (always `source`), `lib.cleanSource ./.`, a flake's `self`, or any `<hash>-source` store path — stdenv unpacks to `$NIX_BUILD_TOP/source/`, so every such crate ends up with `/source/src/lib.rs`. The crate identity is gone from panic backtraces, `file!()` expansions, debuginfo, and llvm-cov coverage maps. Workspace builds via crate2nix that source each member with a fileset see all members collapse to the same prefix, making per-crate coverage and backtrace attribution impossible without a per-crate remap override. Add a second, more specific remap of `$NIX_BUILD_TOP/$sourceRoot` to `/<crateName>-<version>`. rustc applies `--remap-path-prefix` flags last-match-wins, so this prefix wins for everything under the source root — which in a buildRustCrate build is effectively everything that would otherwise embed a sandbox path, including `OUT_DIR` (placed at `$sourceRoot/target/build/` by configure-crate.nix). The broader `$NIX_BUILD_TOP=/` remap stays as a fallback for any path outside `$sourceRoot`. This is safe with respect to the original remap's purpose: - Reproducibility: still maps the per-build sandbox path to a fixed, build-independent string. `crateName` and `version` are already derivation inputs, so the result is deterministic. - Closure size: still no store paths in the embedded strings. - fetchCrate sources: `$sourceRoot` is `<crateName>-<version>` there, so the new remap rewrites `/<crateName>-<version>` to itself — the output is byte-for-byte identical. Only custom-`src` crates change, and they change from a degenerate `/source/...` to the same shape fetchCrate crates already had. - The remap only affects path *strings* embedded in output (DWARF `DW_AT_comp_dir`/`DW_AT_name`, `file!()`, `Location::file()`, LLVM coverage filename tables). It does not change which files are read or compiled. Users who depend on the old `/source/...` prefix can restore it via `extraRustcOpts`, which is appended after these flags and therefore wins under last-match-wins.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
{
|
||||
crateName,
|
||||
version,
|
||||
dependencies,
|
||||
crateFeatures,
|
||||
crateRenames,
|
||||
@@ -32,6 +33,20 @@ let
|
||||
(if release then "-C opt-level=3" else "-C debuginfo=2")
|
||||
"-C codegen-units=${toString codegenUnits}"
|
||||
"--remap-path-prefix=$NIX_BUILD_TOP=/"
|
||||
# Map the unpacked source root to a stable, crate-identifying path.
|
||||
# Sources from fetchCrate unpack to $NIX_BUILD_TOP/<crateName>-<version>,
|
||||
# so the prefix above already yields /<crateName>-<version>/src/... and
|
||||
# this remap is a no-op for them. Sources supplied via a custom `src`
|
||||
# (lib.fileset.toSource, lib.cleanSource, a flake's `self`) all unpack to
|
||||
# a fixed basename like `source`, so without this every such crate
|
||||
# collapses to /source/src/... — losing crate identity in panic
|
||||
# backtraces, file!() expansions, debuginfo, and coverage maps. rustc
|
||||
# applies remaps last-match-wins, so this more-specific prefix wins
|
||||
# for everything under the source root (including OUT_DIR, which
|
||||
# configure-crate.nix places at $sourceRoot/target/build/); the
|
||||
# broader $NIX_BUILD_TOP remap above remains as a fallback for any
|
||||
# path that happens to fall outside $sourceRoot.
|
||||
"--remap-path-prefix=$NIX_BUILD_TOP/$sourceRoot=/${crateName}-${version}"
|
||||
# When the rust-src component is present (common with rust-overlay
|
||||
# toolchains), rustc unvirtualises libstd source paths. Panic
|
||||
# locations from monomorphised generic std code then embed the
|
||||
|
||||
@@ -543,6 +543,7 @@ lib.makeOverridable
|
||||
buildPhase = buildCrate {
|
||||
inherit
|
||||
crateName
|
||||
version
|
||||
dependencies
|
||||
crateFeatures
|
||||
crateRenames
|
||||
|
||||
Reference in New Issue
Block a user