cc-wrapper: Don't force outPath comparisons during metadata evaluation

Operations like `nix eval --file '<nixpkgs>' hello.name` are supposed
to be lazy in the sense that they shouldn't cause any derivations to
be instantiated. However, this was not the case anymore, e.g.

  $ time nix eval --file '<nixpkgs>' hello.name -vvvvvvv 2>&1 | grep -c 'copying.*to the store\|^instantiated'
  1145
  real    0m0.359s

In fact, even evaluating `lib.version` triggers 1145 paths to be
copied to the store. (Why `lib` causes a bunch of derivations to be
evaluated is another issue...)

The reason for this is that cc-wrapper has assertions like

  assert libc_bin == bintools.libc_bin

which which Nix implements by comparing their outPaths. Computing an
outPath calls derivationStrict, causing the .drv closure of the
bootstrap libc to be written to the store. Since these asserts ran
whenever a cc-wrapper derivation was forced to WHNF (which the stdenv
bootstrap stage assertions do on every evaluation of the Nixpkgs top
level), merely evaluating e.g. 'hello.name' wrote over a thousand .drv
files.

Now the asserts are (arbitrarily) moved under `unpackPhase`, which is
only forced when the derivation is actually instantiated, so
evaluating metadata attributes stays free of store writes:

  $ time nix eval --file '<nixpkgs>' hello.name -vvvvvvv 2>&1 | grep -c 'copying.*to the store\|^instantiated'
  0
  real    0m0.113s

Assisted-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eelco Dolstra
2026-07-08 15:16:05 +02:00
parent 7f2d7036b2
commit 3dc7da509f

View File

@@ -392,14 +392,6 @@ in
assert includeFortifyHeaders' -> fortify-headers != null;
# Ensure bintools matches
assert libc_bin == bintools.libc_bin;
assert libc_dev == bintools.libc_dev;
assert libc_lib == bintools.libc_lib;
assert nativeTools == bintools.nativeTools;
assert nativeLibc == bintools.nativeLibc;
assert nativePrefix == bintools.nativePrefix;
stdenvNoCC.mkDerivation {
pname = targetPrefix + (if name != "" then name else "${ccName}-wrapper");
version = optionalString (cc != null) ccVersion;
@@ -469,9 +461,21 @@ stdenvNoCC.mkDerivation {
# This is a quick fix unblock builds broken by https://github.com/NixOS/nixpkgs/pull/370750.
dontCheckForBrokenSymlinks = true;
unpackPhase = ''
src=$PWD
'';
# Ensure bintools matches. This is done here rather than at top level
# so that evaluating the derivation's metadata (such as `name`)
# doesn't force the comparisons, which cause the outPaths of the
# compared derivations to be computed and thus .drv files to be
# written to the store.
unpackPhase =
assert libc_bin == bintools.libc_bin;
assert libc_dev == bintools.libc_dev;
assert libc_lib == bintools.libc_lib;
assert nativeTools == bintools.nativeTools;
assert nativeLibc == bintools.nativeLibc;
assert nativePrefix == bintools.nativePrefix;
''
src=$PWD
'';
wrapper = ./cc-wrapper.sh;