diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index dbaff342fb1af..5116de9803487 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -1,8 +1,61 @@ # This file constructs the standard build environment for the -# Linux/i686 platform. It's completely pure; that is, it relies on no +# Linux platform. It's completely pure; that is, it relies on no # external (non-Nix) tools, such as /usr/bin/gcc, and it contains a C # compiler and linker that do not search in default locations, # ensuring purity of components produced by it. +# +# It starts from prebuilt seed bootstrapFiles and creates a series of +# nixpkgs instances (stages) to gradually rebuild stdenv, which +# is used to build all other packages (including the bootstrapFiles). +# +# Goals of the bootstrap process: +# 1. final stdenv must not reference any of the bootstrap files. +# 2. final stdenv must not contain any of the bootstrap files +# (the only current violation is libgcc_s.so in glibc). +# 3. final stdenv must not contain any of the files directly +# generated by the bootstrap code generators (assembler, linker, +# compiler). The only current violations are: libgcc_s.so in glibc, +# the lib{mpfr,mpc,gmp,isl} which are statically linked +# into the final gcc). +# +# These goals ensure that final packages and final stdenv are built +# exclusively using nixpkgs package definitions and don't depend +# on bootstrapTools (via direct references, inclusion +# of copied code, or code compiled directly by bootstrapTools). +# +# Stages are described below along with their definitions. +# +# Debugging stdenv dependency graph: +# An useful tool to explore dependencies across stages is to use +# '__bootPackages' attribute of 'stdenv. Examples of last 3 stages: +# - stdenv +# - stdenv.__bootPackages.stdenv +# - stdenv.__bootPackages.stdenv.__bootPackages.stdenv +# - ... and so on. +# +# To explore build-time dependencies in graphical form one can use +# the following: +# $ nix-store --query --graph $(nix-instantiate -A stdenv) | +# grep -P -v '[.]sh|[.]patch|bash|[.]tar' | # avoid clutter +# dot -Tsvg > stdenv-final.svg +# +# To find all the packages built by a particular stdenv instance: +# $ for stage in 0 1 2 3 4; do +# echo "stage${stage} used in:" +# nix-store --query --graph $(nix-instantiate -A stdenv) | +# grep -P ".*bootstrap-stage${stage}-stdenv.*->.*" | +# sed 's/"[0-9a-z]\{32\}-/"/g' +# done +# +# To verify which stdenv was used to build a given final package: +# $ nix-store --query --graph $(nix-instantiate -A stdenv) | +# grep -P -v '[.]sh|[.]patch|bash|[.]tar' | +# grep -P '.*stdenv.*->.*glibc-2' +# "...-bootstrap-stage2-stdenv-linux.drv" -> "...-glibc-2.35-224.drv"; +# +# For a TUI (rather than CLI) view, you can use: +# +# $ nix-tree --derivation $(nix-instantiate -A stdenv) { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] @@ -147,6 +200,9 @@ 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"; @@ -202,6 +258,9 @@ 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 { name = "bootstrap-stage1"; @@ -228,6 +287,10 @@ 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 { name = "bootstrap-stage2"; @@ -296,6 +359,10 @@ 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 { name = "bootstrap-stage3"; @@ -332,6 +399,17 @@ 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 { name = "bootstrap-stage4"; @@ -388,6 +466,17 @@ in # When updating stdenvLinux, make sure that the result has no # 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: { inherit config overlays; stdenv = import ../generic rec {