Commit 062e14b5 authored by Sergei Trofimovich's avatar Sergei Trofimovich
Browse files

stdenv/linux: document some tips in debugging stdenv bootstrap tower



Just a few comments added:

- added a few one-liners to explore which tools are rebuilt at each
  stdenv iteration during bootstrap
- explicitly listed available toolchains and their sources for on each
  bootstrap step: glibc, binutils, gcc, coreutils.
- added mention of static libraries linked into gcc

Co-authored-by: default avatarAdam Joseph <54836058+amjoseph-nixpkgs@users.noreply.github.com>
parent 3d7270ab
Loading
Loading
Loading
Loading
+90 −1
Original line number Diff line number Diff line
# 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 {