diff --git a/pkgs/stdenv/nix-linux-static/default.nix b/pkgs/stdenv/nix-linux-static/default.nix index 7d5ad4c3bb0..f202f0ad7c7 100644 --- a/pkgs/stdenv/nix-linux-static/default.nix +++ b/pkgs/stdenv/nix-linux-static/default.nix @@ -1,5 +1,20 @@ +# This file constructs the standard build environment for the +# Linux/i686 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. + +{allPackages}: + rec { + # The bootstrap process proceeds in several steps. + + # 1) Create a standard environment by downloading pre-built + # statically linked binaries of coreutils, gcc, etc. + + # To fetch the pre-built binaries, we use a statically linked `curl' + # binary which is unpacked here. curl = derivation { name = "curl"; builder = ./bash-static/bash; @@ -11,6 +26,7 @@ rec { args = [ ./scripts/curl-unpack ]; }; + # This function downloads and unpacks a file. download = { url, pkgname, postProcess ? [], addToPath ? [] , extra ? null, extra2 ? null @@ -27,6 +43,8 @@ rec { inherit postProcess addToPath extra extra2 extra3 extra4 patchelf; }; + # The various statically linked components that make up the standard + # environment. coreutils = download { url = http://losser.st-lab.cs.uu.nl/~armijn/.nix/coreutils-5.0-static.tar.gz; pkgname = "coreutils"; @@ -99,9 +117,11 @@ rec { extra = linuxHeaders; }; - - stdenvInitial = let { + # The "fake" standard environment used to build "real" standard + # environments. It consists of just bash, coreutils, and sed, which + # is all that is needed by ../generic/builder.sh. + stdenvInitial = let { body = derivation { name = "stdenv-linux-static-initial"; system = "i686-linux"; @@ -115,12 +135,13 @@ rec { stdenv = body; system = body.system; }); - shell = ./bash-static/bash; }; }; + # This function builds the various standard environments used during + # the bootstrap. stdenvBootFun = {glibc, gcc, binutils, staticGlibc}: (import ../generic) { name = "stdenv-linux-static-boot"; param1 = if staticGlibc then "static" else "dynamic"; @@ -148,4 +169,95 @@ rec { ./patchelf-static ]; }; + + + # Create the first "real" standard environment. This one consists + # of statically linked components only, and a minimal glibc to keep + # the gcc configure script happy. + stdenvLinuxBoot1 = stdenvBootFun { + # Use the statically linked, downloaded glibc/gcc/binutils. + inherit glibc gcc binutils; + staticGlibc = true; + }; + + # 2) These are the packages that we can build with the first + # stdenv. We only need Glibc (in step 3). + stdenvLinuxBoot1Pkgs = allPackages { + stdenv = stdenvLinuxBoot1; + bootCurl = curl; + }; + + # 3) Build Glibc with the statically linked tools. The result is the + # full, dynamically linked, final Glibc. + stdenvLinuxGlibc = stdenvLinuxBoot1Pkgs.glibc; + + # 4) Construct a second stdenv identical to the first, except that + # this one uses the Glibc built in step 3. It still uses + # statically linked tools. + stdenvLinuxBoot2 = stdenvBootFun { + glibc = stdenvLinuxGlibc; + staticGlibc = false; + inherit gcc binutils; + }; + + # 5) The packages that can be built using the second stdenv. + stdenvLinuxBoot2Pkgs = allPackages { + stdenv = stdenvLinuxBoot2; + bootCurl = curl; + }; + + # 6) Construct a third stdenv identical to the second, except that + # this one uses the dynamically linked GCC and Binutils from step + # 5. The other tools (e.g. coreutils) are still static. + stdenvLinuxBoot3 = stdenvBootFun { + glibc = stdenvLinuxGlibc; + staticGlibc = false; + inherit (stdenvLinuxBoot2Pkgs) gcc binutils; + }; + + # 7) The packages that can be built using the third stdenv. + stdenvLinuxBoot3Pkgs = allPackages { + stdenv = stdenvLinuxBoot3; + bootCurl = curl; + }; + + # 8) Construct the final stdenv. It uses the Glibc, GCC and + # Binutils built above, and adds in dynamically linked versions + # of all other tools. + stdenvLinux = (import ../generic) { + name = "stdenv-nix-linux"; + preHook = ./prehook.sh; + initialPath = [ + ((import ../nix/path.nix) {pkgs = stdenvLinuxBoot3Pkgs;}) + stdenvLinuxBoot3Pkgs.patchelf + ]; + + stdenv = stdenvInitial; + + gcc = (import ../../build-support/gcc-wrapper) { + stdenv = stdenvInitial; + nativeTools = false; + nativeGlibc = false; + inherit (stdenvLinuxBoot2Pkgs) gcc binutils; + glibc = stdenvLinuxGlibc; + shell = stdenvLinuxBoot3Pkgs.bash ~ /bin/sh; + }; + + shell = stdenvLinuxBoot3Pkgs.bash ~ /bin/sh; + }; + + # 8) Finally, the set of components built using the Linux stdenv. + # Reuse the tools built in the previous steps. + stdenvLinuxPkgs = + allPackages { + stdenv = stdenvLinux; + bootCurl = stdenvLinuxBoot3Pkgs.curl; + } // + {inherit (stdenvLinuxBoot2Pkgs) binutils gcc;} // + {inherit (stdenvLinuxBoot3Pkgs) + gzip bzip2 bash coreutils diffutils findutils gawk + gnumake gnused gnutar gnugrep curl patch patchelf; + } // + {glibc = stdenvLinuxGlibc;}; + } diff --git a/pkgs/stdenv/nix-linux-static/path.nix b/pkgs/stdenv/nix-linux-static/path.nix deleted file mode 100644 index 01b23f95097..00000000000 --- a/pkgs/stdenv/nix-linux-static/path.nix +++ /dev/null @@ -1,13 +0,0 @@ -{pkgs}: [ - pkgs.coreutils - pkgs.findutils - pkgs.diffutils - pkgs.gnused - pkgs.gnugrep - pkgs.gawk - pkgs.gnutar - pkgs.gzip - pkgs.bzip2 - pkgs.gnumake - pkgs.bash -] diff --git a/pkgs/stdenv/nix-linux-static/pkgs.nix b/pkgs/stdenv/nix-linux-static/pkgs.nix deleted file mode 100644 index 52193ac526f..00000000000 --- a/pkgs/stdenv/nix-linux-static/pkgs.nix +++ /dev/null @@ -1,64 +0,0 @@ -{stdenv}: - -rec { - - inherit stdenv; - - curl = (import ./curl-static) { - inherit stdenv; - }; - - ### TOOLS - coreutils = (import ./coreutils-static) { - inherit stdenv gnutar gzip curl; - }; - - findutils = (import ./findutils-static) { - inherit stdenv gnutar gzip curl; - }; - - diffutils = (import ./diffutils-static) { - inherit stdenv gnutar gzip curl; - }; - - gnused = (import ./gnused-static) { - inherit stdenv gnutar gzip curl; - }; - - gnugrep = (import ./gnugrep-static) { - inherit stdenv gnutar gzip curl; - }; - - gawk = (import ./gawk-static) { - inherit stdenv gnutar gzip curl; - }; - - gnutar = (import ./gnutar-static) { - inherit stdenv; - }; - - gzip = (import ./gzip-static) { - inherit stdenv; - }; - - bzip2 = (import ./bzip2-static) { - inherit stdenv gnutar gzip curl; - }; - - binutils = (import ./binutils-static) { - inherit stdenv gnutar gzip curl; - }; - - gnumake = (import ./gnumake-static) { - inherit stdenv gnutar gzip curl; - }; - - gcc = (import ./gcc-static) { - inherit stdenv; - }; - - bash = (import ./bash-static) { - inherit stdenv; - }; - -} diff --git a/pkgs/stdenv/nix-linux/default.nix b/pkgs/stdenv/nix-linux/default.nix deleted file mode 100644 index 9c48b9ef0a4..00000000000 --- a/pkgs/stdenv/nix-linux/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -{stdenv, glibc, pkgs, genericStdenv, gccWrapper}: - -genericStdenv { - name = "stdenv-nix-linux"; - preHook = ./prehook.sh; - initialPath = [ - ((import ../nix/path.nix) {pkgs = pkgs;}) - pkgs.patchelf - ]; - - inherit stdenv; - - gcc = gccWrapper { - name = pkgs.gcc.name; - nativeTools = false; - nativeGlibc = false; - inherit (pkgs) gcc binutils; - inherit stdenv glibc; - shell = pkgs.bash ~ /bin/sh; - }; - - shell = pkgs.bash ~ /bin/sh; -} diff --git a/pkgs/stdenv/nix-linux/gcc-static/builder.sh b/pkgs/stdenv/nix-linux/gcc-static/builder.sh deleted file mode 100644 index 982d7254106..00000000000 --- a/pkgs/stdenv/nix-linux/gcc-static/builder.sh +++ /dev/null @@ -1,5 +0,0 @@ -. $stdenv/setup - -tar zxvf $src -mkdir $out -cp -a gcc-3.3.4/* $out diff --git a/pkgs/stdenv/nix-linux/gcc-static/default.nix b/pkgs/stdenv/nix-linux/gcc-static/default.nix deleted file mode 100644 index 04dc2ae75b2..00000000000 --- a/pkgs/stdenv/nix-linux/gcc-static/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -{stdenv, fetchurl}: - -stdenv.mkDerivation { - name = "gcc-static-3.3.4"; - builder = ./builder.sh; - src = fetchurl { - url = http://losser.st-lab.cs.uu.nl/~armijn/.nix/gcc-3.3.4-static-nix.tar.gz; - md5 = "8b5c3a5881209edb15682e5e0c7459e4"; - }; -} diff --git a/pkgs/stdenv/nix-linux/prehook.sh b/pkgs/stdenv/nix-linux/prehook.sh deleted file mode 100644 index 5b9c6f87879..00000000000 --- a/pkgs/stdenv/nix-linux/prehook.sh +++ /dev/null @@ -1,2 +0,0 @@ -export NIX_ENFORCE_PURITY=1 -havePatchELF=1 \ No newline at end of file diff --git a/pkgs/system/stdenvs.nix b/pkgs/system/stdenvs.nix index efbbcb0faad..9127c6793c3 100644 --- a/pkgs/system/stdenvs.nix +++ b/pkgs/system/stdenvs.nix @@ -49,102 +49,8 @@ }; - # The Linux build environment is a fully bootstrapped Nix - # environment, that is, it should contain no external references. - - # 0) ... - stdenvLinuxBoot0 = (import ../stdenv/nix-linux-static).stdenvBootFun { - # Use the statically linked, downloaded glibc/gcc/binutils. - inherit (import ../stdenv/nix-linux-static) glibc gcc binutils; - staticGlibc = true; - }; - - stdenvLinuxBoot0Pkgs = allPackages { - stdenv = stdenvLinuxBoot0; - bootCurl = (import ../stdenv/nix-linux-static).curl; - noSysDirs = true; - }; - - # 1) Build glibc in the Nix build environment. The result is - # pure. - stdenvLinuxGlibc = stdenvLinuxBoot0Pkgs.glibc; - - # 2) Construct a stdenv consisting of the Nix build environment, but - # with a gcc-wrapper that causes linking against the glibc from - # step 1. However, since the gcc wrapper here *does* look in - # native system directories (e.g., `/usr/lib'), it doesn't - # prevent impurity in the things it builds (e.g., through - # `-lncurses'). - stdenvLinuxBoot1 = (import ../stdenv/nix-linux-static).stdenvBootFun { - # Use the statically linked gcc/binutils, but the glibc we just - # built. - glibc = stdenvLinuxGlibc; - staticGlibc = false; - inherit (import ../stdenv/nix-linux-static) gcc binutils; - }; - - # 3) Now we can build packages that will link against the Nix - # glibc. We are on thin ice here: the compiler used to build - # these packages doesn't prevent impurity, so e.g. bash ends up - # linking against `/lib/libncurses.so', but the glibc from step 1 - # *doesn't* search in `/lib' etc. So these programs won't work. - stdenvLinuxBoot1Pkgs = allPackages { - stdenv = stdenvLinuxBoot1; - bootCurl = (import ../stdenv/nix-linux-static).curl; - }; - - # 4) Therefore we build a new standard environment which is the same - # as the one in step 2, but with a gcc and binutils from step 3 - # merged in. Since these are pure (they don't search native - # system directories), things built by this stdenv should be pure. - stdenvLinuxBoot2 = (import ../stdenv/nix-linux-static).stdenvBootFun { - # Use the glibc/gcc/binutils we just built (but all other tools are still downloaded). - glibc = stdenvLinuxGlibc; - staticGlibc = false; - inherit (stdenvLinuxBoot1Pkgs) gcc binutils; - }; - - # 5) So these packages should be pure. - stdenvLinuxBoot2Pkgs = allPackages { - stdenv = stdenvLinuxBoot2; - bootCurl = (import ../stdenv/nix-linux-static).curl; - }; - - # 6) Finally we can construct the Nix build environment from the - # packages from step 5. - stdenvLinux = (import ../stdenv/nix-linux) { - stdenv = stdenvLinuxBoot2; - pkgs = stdenvLinuxBoot2Pkgs // { - inherit (stdenvLinuxBoot1Pkgs) gcc binutils; - }; - glibc = stdenvLinuxGlibc; - inherit genericStdenv gccWrapper; - }; - - # 7) And we can build all packages against that, but we don't - # rebuild stuff from step 6. - stdenvLinuxPkgs = - allPackages { - stdenv = stdenvLinux; - bootCurl = stdenvLinuxBoot2Pkgs.curl; - } // - {inherit (stdenvLinuxBoot2Pkgs) - gzip bzip2 bash binutils coreutils diffutils findutils gawk gcc - gnumake gnused gnutar gnugrep curl; - } // - {glibc = stdenvLinuxGlibc;}; - - # In summary, we build gcc (and binutils) three times: - # - in stdenvLinuxBoot1 (from stdenvNativePkgs); impure - # - in stdenvLinuxBoot2 (from stdenvLinuxBoot1Pkgs); pure - # - in stdenvLinux (from stdenvLinuxBoot2Pkgs); pure - # The last one may be redundant, but its good for validation (since - # the second one may use impure inputs). To reduce build time, we - # could reduce the number of bootstrap stages inside each gcc build. - # Right now there are 3 stages, so gcc is built 9 times! - - # On the other hand, a validating build of glibc is a good idea (it - # probably won't work right now due to --rpath madness). + # Linux standard environment. + inherit (import ../stdenv/nix-linux-static) stdenvLinux stdenvLinuxPkgs; # Darwin (Mac OS X) standard environment. Very simple for now