about summary refs log tree commit diff
path: root/pkgs/stdenv
diff options
context:
space:
mode:
authorGergely Risko <errge@nilcons.com>2014-08-23 21:26:37 +0200
committerGergely Risko <errge@nilcons.com>2014-08-24 17:10:50 +0200
commit350022247a0b59abf42228d1d3fbb4222974b130 (patch)
treee670e4d51e3222c06c1ae88c270eccc39e37f19a /pkgs/stdenv
parent142970b9eb1925d67b4b9b41d060533fe249f2ec (diff)
Refactor stage handling in stdenvLinux
Make stages explicit and generalize the pattern of having an stdenv and
a pkgs collection for all stages to a common stage generating function
called stageFun.

Rewrite all stage handling with this new function.

This commit doesn't change the outhash (or drvhash) of the stdenv.
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r--pkgs/stdenv/linux/default.nix187
1 files changed, 80 insertions, 107 deletions
diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix
index d2c36b9dc0dbc..6c910c284a5c5 100644
--- a/pkgs/stdenv/linux/default.nix
+++ b/pkgs/stdenv/linux/default.nix
@@ -35,8 +35,8 @@ rec {
   # The bootstrap process proceeds in several steps.
 
 
-  # 1) Create a standard environment by downloading pre-built binaries
-  # of coreutils, GCC, etc.
+  # Create a standard environment by downloading pre-built binaries of
+  # coreutils, GCC, etc.
 
 
   # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...).
@@ -67,11 +67,13 @@ rec {
 
 
   # This function builds the various standard environments used during
-  # the bootstrap.
-  stdenvBootFun =
+  # the bootstrap.  In all stages, we build an stdenv and the package
+  # set that can be built with that stdenv.
+  stageFun =
     {gcc, extraAttrs ? {}, overrides ? (pkgs: {}), extraPath ? []}:
 
-    let thisStdenv = import ../generic {
+    let
+    thisStdenv = import ../generic {
       inherit system config;
       name = "stdenv-linux-boot";
       preHook =
@@ -84,7 +86,7 @@ rec {
       shell = "${bootstrapTools}/bin/sh";
       initialPath = [bootstrapTools] ++ extraPath;
       fetchurlBoot = import ../../build-support/fetchurl {
-        stdenv = stdenvLinuxBoot0;
+        stdenv = stage0.stdenv;
         curl = bootstrapTools;
       };
       inherit gcc;
@@ -93,26 +95,32 @@ rec {
       extraAttrs = extraAttrs // { inherit platform; };
       overrides = pkgs: (overrides pkgs) // { fetchurl = thisStdenv.fetchurlBoot; };
     };
-    in thisStdenv;
+    thisPkgs = allPackages {
+      inherit system platform;
+      bootStdenv = thisStdenv;
+    };
+    in { stdenv = thisStdenv; pkgs = thisPkgs; };
 
   # Build a dummy stdenv with no GCC or working fetchurl.  This is
   # because we need a stdenv to build the GCC wrapper and fetchurl.
-  stdenvLinuxBoot0 = stdenvBootFun {
+  stage0 = stageFun {
     gcc = "/no-such-path";
-  };
 
-
-  # The Glibc include directory cannot have the same prefix as the GCC
-  # include directory, since GCC gets confused otherwise (it will
-  # search the Glibc headers before the GCC headers).  So create a
-  # dummy Glibc.
-  bootstrapGlibc = stdenvLinuxBoot0.mkDerivation {
-    name = "bootstrap-glibc";
-    buildCommand = ''
-      mkdir -p $out
-      ln -s ${bootstrapTools}/lib $out/lib
-      ln -s ${bootstrapTools}/include-glibc $out/include
-    '';
+    overrides = pkgs: {
+      # The Glibc include directory cannot have the same prefix as the
+      # GCC include directory, since GCC gets confused otherwise (it
+      # will search the Glibc headers before the GCC headers).  So
+      # create a dummy Glibc here, which will be used in the stdenv of
+      # stage1.
+      glibc = stage0.stdenv.mkDerivation {
+        name = "bootstrap-glibc";
+        buildCommand = ''
+          mkdir -p $out
+          ln -s ${bootstrapTools}/lib $out/lib
+          ln -s ${bootstrapTools}/include-glibc $out/include
+        '';
+      };
+    };
   };
 
 
@@ -124,78 +132,58 @@ rec {
       nativeTools = false;
       nativeLibc = false;
       inherit gcc binutils coreutils libc name;
-      stdenv = stdenvLinuxBoot0;
+      stdenv = stage0.stdenv;
     };
 
 
   # Create the first "real" standard environment.  This one consists
   # of bootstrap tools only, and a minimal Glibc to keep the GCC
   # configure script happy.
-  stdenvLinuxBoot1 = stdenvBootFun {
+  stage1 = stageFun {
     gcc = wrapGCC {
       gcc = bootstrapTools;
-      libc = bootstrapGlibc;
+      libc = stage0.pkgs.glibc;
       binutils = bootstrapTools;
       coreutils = bootstrapTools;
       name = "bootstrap-gcc-wrapper";
     };
+    # Rebuild binutils to use from stage2 onwards.
+    overrides = pkgs: {
+      binutils = pkgs.binutils.override { gold = false; };
+    };
   };
 
 
-  # 2) These are the packages that we can build with the first
-  #    stdenv.  We only need binutils, because recent Glibcs
-  #    require recent Binutils, and those in bootstrap-tools may
-  #    be too old.
-  stdenvLinuxBoot1Pkgs = allPackages {
-    inherit system platform;
-    bootStdenv = stdenvLinuxBoot1;
-  };
-
-  binutils1 = stdenvLinuxBoot1Pkgs.binutils.override { gold = false; };
-
-
-  # 3) 2nd stdenv that we will use to build only Glibc.
-  stdenvLinuxBoot2 = stdenvBootFun {
+  # 2nd stdenv that contains our own rebuilt binutils and is used for
+  # compiling our own Glibc.
+  stage2 = stageFun {
     gcc = wrapGCC {
       gcc = bootstrapTools;
-      libc = bootstrapGlibc;
-      binutils = binutils1;
+      libc = stage0.pkgs.glibc;
+      binutils = stage1.pkgs.binutils;
       coreutils = bootstrapTools;
       name = "bootstrap-gcc-wrapper";
     };
     overrides = pkgs: {
-      inherit (stdenvLinuxBoot1Pkgs) perl;
+      inherit (stage1.pkgs) perl;
+      # This also contains the full, dynamically linked, final Glibc.
     };
   };
 
 
-  # 4) These are the packages that we can build with the 2nd
-  #    stdenv.
-  stdenvLinuxBoot2Pkgs = allPackages {
-    inherit system platform;
-    bootStdenv = stdenvLinuxBoot2;
-  };
-
-
-  # 5) Build Glibc with the bootstrap tools.  The result is the full,
-  #    dynamically linked, final Glibc.
-  stdenvLinuxGlibc = stdenvLinuxBoot2Pkgs.glibc;
-
-
-  # 6) Construct a third stdenv identical to the 2nd, except that this
-  #    one uses the Glibc built in step 5.  It still uses the recent
-  #    binutils and rest of the bootstrap tools, including GCC.
-  stdenvLinuxBoot3 = stdenvBootFun {
+  # 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.
+  stage3 = stageFun {
     gcc = wrapGCC {
       gcc = bootstrapTools;
-      libc = stdenvLinuxGlibc;
-      binutils = binutils1;
+      libc = stage2.pkgs.glibc;
+      binutils = stage1.pkgs.binutils;
       coreutils = bootstrapTools;
       name = "bootstrap-gcc-wrapper";
     };
     overrides = pkgs: {
-      glibc = stdenvLinuxGlibc;
-      inherit (stdenvLinuxBoot1Pkgs) perl;
+      inherit (stage2.pkgs) glibc perl;
       # Link GCC statically against GMP etc.  This makes sense because
       # these builds of the libraries are only used by GCC, so it
       # reduces the size of the stdenv closure.
@@ -207,52 +195,37 @@ rec {
       ppl = pkgs.ppl.override { stdenv = pkgs.makeStaticLibraries pkgs.stdenv; };
     };
     extraAttrs = {
-      glibc = stdenvLinuxGlibc;   # Required by gcc47 build
+      glibc = stage2.pkgs.glibc;  # Required by gcc47 build
     };
-    extraPath = [ stdenvLinuxBoot1Pkgs.paxctl ];
+    extraPath = [ stage1.pkgs.paxctl ];
   };
 
 
-  # 7) The packages that can be built using the third stdenv.
-  stdenvLinuxBoot3Pkgs = allPackages {
-    inherit system platform;
-    bootStdenv = stdenvLinuxBoot3;
-  };
-
-
-  # 8) Construct a fourth stdenv identical to the second, except that
-  #    this one uses the new GCC from step 7.  The other tools
-  #    (e.g. coreutils) are still from the bootstrap tools.
-  stdenvLinuxBoot4 = stdenvBootFun {
-    gcc = wrapGCC rec {
-      gcc = stdenvLinuxBoot3Pkgs.gcc.gcc;
-      libc = stdenvLinuxGlibc;
-      binutils = binutils1;
+  # Construct a fourth stdenv that uses the new GCC.  But coreutils is
+  # still from the bootstrap tools.
+  stage4 = stageFun {
+    gcc = wrapGCC {
+      gcc = stage3.pkgs.gcc.gcc;
+      libc = stage2.pkgs.glibc;
+      binutils = stage1.pkgs.binutils;
       coreutils = bootstrapTools;
       name = "";
     };
-    extraPath = [ stdenvLinuxBoot3Pkgs.xz ];
+    extraPath = [ stage3.pkgs.xz ];
     overrides = pkgs: {
-      inherit (stdenvLinuxBoot1Pkgs) perl;
-      inherit (stdenvLinuxBoot3Pkgs) gettext gnum4 gmp;
+      inherit (stage1.pkgs) perl;
+      inherit (stage3.pkgs) gettext gnum4 gmp glibc;
     };
   };
 
 
-  # 9) The packages that can be built using the fourth stdenv.
-  stdenvLinuxBoot4Pkgs = allPackages {
-    inherit system platform;
-    bootStdenv = stdenvLinuxBoot4;
-  };
-
-
-  # 10) Construct the final stdenv.  It uses the Glibc and GCC, and
-  #     adds in a new binutils that doesn't depend on bootstrap-tools,
-  #     as well as dynamically linked versions of all other tools.
+  # Construct the final stdenv.  It uses the Glibc and GCC, and adds
+  # in a new binutils that doesn't depend on bootstrap-tools, as well
+  # as dynamically linked versions of all other tools.
   #
-  #     When updating stdenvLinux, make sure that the result has no
-  #     dependency (`nix-store -qR') on bootstrapTools or the
-  #     first binutils built.
+  # When updating stdenvLinux, make sure that the result has no
+  # dependency (`nix-store -qR') on bootstrapTools or the first
+  # binutils built.
   stdenvLinux = import ../generic rec {
     inherit system config;
 
@@ -265,31 +238,31 @@ rec {
       '';
 
     initialPath =
-      ((import ../common-path.nix) {pkgs = stdenvLinuxBoot4Pkgs;})
-      ++ [stdenvLinuxBoot4Pkgs.patchelf stdenvLinuxBoot4Pkgs.paxctl ];
+      ((import ../common-path.nix) {pkgs = stage4.pkgs;})
+      ++ [stage4.pkgs.patchelf stage4.pkgs.paxctl ];
 
-    shell = stdenvLinuxBoot4Pkgs.bash + "/bin/bash";
+    shell = stage4.pkgs.bash + "/bin/bash";
 
     gcc = (wrapGCC rec {
-      gcc = stdenvLinuxBoot4.gcc.gcc;
-      libc = stdenvLinuxGlibc;
-      inherit (stdenvLinuxBoot4Pkgs) binutils coreutils;
+      gcc = stage4.stdenv.gcc.gcc;
+      libc = stage4.pkgs.glibc;
+      inherit (stage4.pkgs) binutils coreutils;
       name = "";
     }).override { inherit shell; };
 
-    fetchurlBoot = stdenvLinuxBoot0.fetchurlBoot;
+    fetchurlBoot = stage4.stdenv.fetchurl;
 
     extraAttrs = {
-      inherit (stdenvLinuxBoot3Pkgs) glibc;
+      inherit (stage4.pkgs) glibc;
       inherit platform bootstrapTools;
-      shellPackage = stdenvLinuxBoot4Pkgs.bash;
+      shellPackage = stage4.pkgs.bash;
     };
 
     overrides = pkgs: {
       inherit gcc;
-      inherit (stdenvLinuxBoot3Pkgs) glibc;
-      inherit (stdenvLinuxBoot4Pkgs) binutils;
-      inherit (stdenvLinuxBoot4Pkgs)
+      inherit (stage3.pkgs) glibc;
+      inherit (stage4.pkgs) binutils;
+      inherit (stage4.pkgs)
         gzip bzip2 xz bash coreutils diffutils findutils gawk
         gnumake gnused gnutar gnugrep gnupatch patchelf
         attr acl paxctl;