summary refs log tree commit diff
path: root/pkgs/stdenv/linux
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2023-01-10 02:19:17 -0800
committerAdam Joseph <adam@westernsemico.com>2023-02-20 23:20:30 -0800
commitd7aad245314ef6b026707bf41c36461d450ef3ab (patch)
tree1138415977ff2210b56df9ce7acea0d61e649599 /pkgs/stdenv/linux
parentfa169bb239d7b2d860af851573569182ee5e0127 (diff)
downloadnixpkgs-d7aad245314ef6b026707bf41c36461d450ef3ab.tar
nixpkgs-d7aad245314ef6b026707bf41c36461d450ef3ab.tar.gz
nixpkgs-d7aad245314ef6b026707bf41c36461d450ef3ab.tar.bz2
nixpkgs-d7aad245314ef6b026707bf41c36461d450ef3ab.tar.lz
nixpkgs-d7aad245314ef6b026707bf41c36461d450ef3ab.tar.xz
nixpkgs-d7aad245314ef6b026707bf41c36461d450ef3ab.tar.zst
nixpkgs-d7aad245314ef6b026707bf41c36461d450ef3ab.zip
express #208478 as assertions
PR #208478 added a lot of documentation about which packages were
rebuilt in each stage of the stdenv bootstrap.  However nothing
checks that these comments agree with reality; they can bitrot over
time.  This PR rewrites those comments as assertions, so they cannot
bitrot.

This conversion did expose some ambiguity in our scheme for naming
the stages.   Suppose that `pkgs.stdenv.name=="stdenv-stage4", then
which of these is "the stage4 coreutils"?

```
pkgs.coreutils
pkgs.stdenv.__bootPackages.coreutils
```

The choice is arbitrary, and both choices have confusing corner
cases.  We should revisit this at some point.
Diffstat (limited to 'pkgs/stdenv/linux')
-rw-r--r--pkgs/stdenv/linux/default.nix124
1 files changed, 76 insertions, 48 deletions
diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix
index 5c7dfcceec6..46eac56cc00 100644
--- a/pkgs/stdenv/linux/default.nix
+++ b/pkgs/stdenv/linux/default.nix
@@ -100,6 +100,14 @@ assert crossSystem == localSystem;
 let
   inherit (localSystem) system;
 
+  isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg);
+  isFromBootstrapFiles =
+    pkg: pkg.passthru.isFromBootstrapFiles or false;
+  isBuiltByNixpkgsCompiler =
+    pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc;
+  isBuiltByBootstrapFilesCompiler =
+    pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc;
+
   commonPreHook =
     ''
       export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
@@ -117,16 +125,14 @@ let
 
 
   # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...).
-  bootstrapTools = import (if localSystem.libc == "musl" then ./bootstrap-tools-musl else ./bootstrap-tools) {
+  bootstrapTools = (import (if localSystem.libc == "musl" then ./bootstrap-tools-musl else ./bootstrap-tools) {
     inherit system bootstrapFiles;
-    extraAttrs = lib.optionalAttrs
-      config.contentAddressedByDefault
-      {
-        __contentAddressed = true;
-        outputHashAlgo = "sha256";
-        outputHashMode = "recursive";
-      };
-  };
+    extraAttrs = lib.optionalAttrs config.contentAddressedByDefault {
+      __contentAddressed = true;
+      outputHashAlgo = "sha256";
+      outputHashMode = "recursive";
+    };
+  }) // { passthru.isFromBootstrapFiles = true; };
 
   getLibc = stage: stage.${localSystem.libc};
 
@@ -186,7 +192,7 @@ let
     };
 
 in
-
+  assert bootstrapTools.passthru.isFromBootstrapFiles or false;  # sanity check
 [
 
   ({}: {
@@ -200,9 +206,6 @@ in
 
   # Build a dummy stdenv with no GCC or working fetchurl.  This is
   # because we need a stdenv to build the GCC wrapper and fetchurl.
-  #
-  # resulting stage0 stdenv:
-  # - coreutils, binutils, glibc, gcc: from bootstrapFiles
   (prevStage: stageFun prevStage {
     name = "bootstrap-stage0";
 
@@ -230,6 +233,7 @@ in
         '' + lib.optionalString (localSystem.libc == "musl") ''
           ln -s ${bootstrapTools}/include-libc $out/include
         '';
+        passthru.isFromBootstrapFiles = true;
       };
       gcc-unwrapped = bootstrapTools;
       binutils = import ../../build-support/bintools-wrapper {
@@ -258,10 +262,14 @@ in
   # If we ever need to use a package from more than one stage back, we
   # simply re-export those packages in the middle stage(s) using the
   # overrides attribute and the inherit syntax.
-  #
-  # resulting stage1 stdenv:
-  # - coreutils, binutils, glibc, gcc: from bootstrapFiles
-  (prevStage: stageFun prevStage {
+  (prevStage:
+    # previous stage0 stdenv:
+    assert isFromBootstrapFiles prevStage.binutils.bintools;
+    assert isFromBootstrapFiles prevStage."${localSystem.libc}";
+    assert isFromBootstrapFiles prevStage.gcc-unwrapped;
+    assert isFromBootstrapFiles prevStage.coreutils;
+    assert isFromBootstrapFiles prevStage.gnugrep;
+    stageFun prevStage {
     name = "bootstrap-stage1";
 
     # Rebuild binutils to use from stage2 onwards.
@@ -288,10 +296,14 @@ in
   # 2nd stdenv that contains our own rebuilt binutils and is used for
   # compiling our own Glibc.
   #
-  # resulting stage2 stdenv:
-  # - coreutils, glibc, gcc: from bootstrapFiles
-  # - binutils: from nixpkgs, built by bootstrapFiles toolchain
-  (prevStage: stageFun prevStage {
+  (prevStage:
+    # previous stage1 stdenv:
+    assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
+    assert            isFromBootstrapFiles prevStage."${localSystem.libc}";
+    assert            isFromBootstrapFiles prevStage.gcc-unwrapped;
+    assert            isFromBootstrapFiles prevStage.coreutils;
+    assert            isFromBootstrapFiles prevStage.gnugrep;
+    stageFun prevStage {
     name = "bootstrap-stage2";
 
     overrides = self: super: {
@@ -334,6 +346,7 @@ in
         bintools = self.stdenvNoCC.mkDerivation {
           pname = prevStage.bintools.bintools.pname + "-patchelfed-ld";
           inherit (prevStage.bintools.bintools) version;
+          passthru = { inherit (prevStage.bintools.passthru) isFromBootstrapFiles; };
           enableParallelBuilding = true;
           dontUnpack = true;
           dontBuild = true;
@@ -360,11 +373,14 @@ in
   # Construct a third stdenv identical to the 2nd, except that this
   # one uses the rebuilt Glibc from stage2.  It still uses the recent
   # binutils and rest of the bootstrap tools, including GCC.
-  #
-  # resulting stage3 stdenv:
-  # - coreutils, gcc: from bootstrapFiles
-  # - glibc, binutils: from nixpkgs, built by bootstrapFiles toolchain
-  (prevStage: stageFun prevStage {
+  (prevStage:
+    # previous stage2 stdenv:
+    assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
+    assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
+    assert            isFromBootstrapFiles prevStage.gcc-unwrapped;
+    assert            isFromBootstrapFiles prevStage.coreutils;
+    assert            isFromBootstrapFiles prevStage.gnugrep;
+    stageFun prevStage {
     name = "bootstrap-stage3";
 
     overrides = self: super: rec {
@@ -401,17 +417,21 @@ in
   # Construct a fourth stdenv that uses the new GCC.  But coreutils is
   # still from the bootstrap tools.
   #
-  # resulting stage4 stdenv:
-  # - coreutils: from bootstrapFiles
-  # - glibc, binutils: from nixpkgs, built by bootstrapFiles toolchain
-  # - gcc: from nixpkgs, built by bootstrapFiles toolchain. Can assume
-  #        it has almost no code from bootstrapTools as gcc bootstraps
-  #        internally. The only exceptions are crt files from glibc
-  #        built by bootstrapTools used to link executables and libraries,
-  #        and the bootstrapTools-built, statically-linked
-  #        lib{mpfr,mpc,gmp,isl}.a which are linked into the final gcc
-  #        (see commit cfde88976ba4cddd01b1bb28b40afd12ea93a11d).
-  (prevStage: stageFun prevStage {
+  (prevStage:
+    # previous stage3 stdenv:
+    assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
+    assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
+    assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
+    assert            isFromBootstrapFiles prevStage.coreutils;
+    assert            isFromBootstrapFiles prevStage.gnugrep;
+    # Can assume prevStage.gcc-unwrapped has almost no code from
+    # bootstrapTools as gcc bootstraps internally. The only
+    # exceptions are crt files from glibc built bybootstrapTools
+    # used to link executables and libraries, and the
+    # bootstrapTools-built, statically-linked
+    # lib{mpfr,mpc,gmp,isl}.a which are linked into the final gcc
+    # (see commit cfde88976ba4cddd01b1bb28b40afd12ea93a11d).
+    stageFun prevStage {
     name = "bootstrap-stage4";
 
     overrides = self: super: {
@@ -468,17 +488,15 @@ in
   # dependency (`nix-store -qR') on bootstrapTools or the first
   # binutils built.
   #
-  # resulting stage5 (final) stdenv:
-  # - coreutils, binutils: from nixpkgs, built by nixpkgs toolchain
-  # - glibc: from nixpkgs, built by bootstrapFiles toolchain
-  # - gcc: from nixpkgs, built by bootstrapFiles toolchain. Can assume
-  #        it has almost no code from bootstrapTools as gcc bootstraps
-  #        internally. The only exceptions are crt files from glibc
-  #        built by bootstrapTools used to link executables and libraries,
-  #        and the bootstrapTools-built, statically-linked
-  #        lib{mpfr,mpc,gmp,isl}.a which are linked into the final gcc
-  #        (see commit cfde88976ba4cddd01b1bb28b40afd12ea93a11d).
-  (prevStage: {
+  (prevStage:
+    # previous stage4 stdenv; see stage3 comment regarding gcc,
+    # which applies here as well.
+    assert        isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
+    assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
+    assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
+    assert        isBuiltByNixpkgsCompiler prevStage.coreutils;
+    assert        isBuiltByNixpkgsCompiler prevStage.gnugrep;
+    {
     inherit config overlays;
     stdenv = import ../generic rec {
       name = "stdenv-linux";
@@ -554,4 +572,14 @@ in
     };
   })
 
+  # This "no-op" stage is just a place to put the assertions about stage5.
+  (prevStage:
+    # previous stage5 stdenv; see stage3 comment regarding gcc,
+    # which applies here as well.
+    assert        isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
+    assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
+    assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
+    assert        isBuiltByNixpkgsCompiler prevStage.coreutils;
+    assert        isBuiltByNixpkgsCompiler prevStage.gnugrep;
+    { inherit (prevStage) config overlays stdenv; })
 ]