lol
at 16.09-beta 305 lines 10 kB view raw
1# This file constructs the standard build environment for the 2# Linux/i686 platform. It's completely pure; that is, it relies on no 3# external (non-Nix) tools, such as /usr/bin/gcc, and it contains a C 4# compiler and linker that do not search in default locations, 5# ensuring purity of components produced by it. 6 7# The function defaults are for easy testing. 8{ system ? builtins.currentSystem 9, allPackages ? import ../../.. 10, platform ? null, config ? {}, lib ? (import ../../../lib) 11, bootstrapFiles ? 12 if system == "i686-linux" then import ./bootstrap/i686.nix 13 else if system == "x86_64-linux" then import ./bootstrap/x86_64.nix 14 else if system == "armv5tel-linux" then import ./bootstrap/armv5tel.nix 15 else if system == "armv6l-linux" then import ./bootstrap/armv6l.nix 16 else if system == "armv7l-linux" then import ./bootstrap/armv7l.nix 17 else if system == "mips64el-linux" then import ./bootstrap/loongson2f.nix 18 else abort "unsupported platform for the pure Linux stdenv" 19}: 20 21rec { 22 23 commonPreHook = 24 '' 25 export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}" 26 export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}" 27 ${if system == "x86_64-linux" then "NIX_LIB64_IN_SELF_RPATH=1" else ""} 28 ${if system == "mips64el-linux" then "NIX_LIB32_IN_SELF_RPATH=1" else ""} 29 ''; 30 31 32 # The bootstrap process proceeds in several steps. 33 34 35 # Create a standard environment by downloading pre-built binaries of 36 # coreutils, GCC, etc. 37 38 39 # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...). 40 bootstrapTools = derivation { 41 name = "bootstrap-tools"; 42 43 builder = bootstrapFiles.busybox; 44 45 args = [ "ash" "-e" ./scripts/unpack-bootstrap-tools.sh ]; 46 47 tarball = bootstrapFiles.bootstrapTools; 48 49 inherit system; 50 51 # Needed by the GCC wrapper. 52 langC = true; 53 langCC = true; 54 isGNU = true; 55 }; 56 57 58 # This function builds the various standard environments used during 59 # the bootstrap. In all stages, we build an stdenv and the package 60 # set that can be built with that stdenv. 61 stageFun = 62 {gccPlain, glibc, binutils, coreutils, gnugrep, name, overrides ? (pkgs: {}), extraBuildInputs ? []}: 63 64 let 65 66 thisStdenv = import ../generic { 67 inherit system config extraBuildInputs; 68 name = "stdenv-linux-boot"; 69 preHook = 70 '' 71 # Don't patch #!/interpreter because it leads to retained 72 # dependencies on the bootstrapTools in the final stdenv. 73 dontPatchShebangs=1 74 ${commonPreHook} 75 ''; 76 shell = "${bootstrapTools}/bin/bash"; 77 initialPath = [bootstrapTools]; 78 79 fetchurlBoot = import ../../build-support/fetchurl/boot.nix { 80 inherit system; 81 }; 82 83 cc = if isNull gccPlain 84 then null 85 else lib.makeOverridable (import ../../build-support/cc-wrapper) { 86 nativeTools = false; 87 nativeLibc = false; 88 cc = gccPlain; 89 isGNU = true; 90 libc = glibc; 91 inherit binutils coreutils gnugrep; 92 name = name; 93 stdenv = stage0.stdenv; 94 }; 95 96 extraAttrs = { 97 # Having the proper 'platform' in all the stdenvs allows getting proper 98 # linuxHeaders for example. 99 inherit platform; 100 101 # stdenv.glibc is used by GCC build to figure out the system-level 102 # /usr/include directory. 103 inherit glibc; 104 }; 105 overrides = pkgs: (overrides pkgs) // { fetchurl = thisStdenv.fetchurlBoot; }; 106 }; 107 108 thisPkgs = allPackages { 109 inherit system platform; 110 bootStdenv = thisStdenv; 111 }; 112 113 in { stdenv = thisStdenv; pkgs = thisPkgs; }; 114 115 116 # Build a dummy stdenv with no GCC or working fetchurl. This is 117 # because we need a stdenv to build the GCC wrapper and fetchurl. 118 stage0 = stageFun { 119 gccPlain = null; 120 glibc = null; 121 binutils = null; 122 coreutils = null; 123 gnugrep = null; 124 name = null; 125 126 overrides = pkgs: { 127 # The Glibc include directory cannot have the same prefix as the 128 # GCC include directory, since GCC gets confused otherwise (it 129 # will search the Glibc headers before the GCC headers). So 130 # create a dummy Glibc here, which will be used in the stdenv of 131 # stage1. 132 glibc = stage0.stdenv.mkDerivation { 133 name = "bootstrap-glibc"; 134 buildCommand = '' 135 mkdir -p $out 136 ln -s ${bootstrapTools}/lib $out/lib 137 ln -s ${bootstrapTools}/include-glibc $out/include 138 ''; 139 }; 140 }; 141 }; 142 143 144 # Create the first "real" standard environment. This one consists 145 # of bootstrap tools only, and a minimal Glibc to keep the GCC 146 # configure script happy. 147 # 148 # For clarity, we only use the previous stage when specifying these 149 # stages. So stageN should only ever have references for stage{N-1}. 150 # 151 # If we ever need to use a package from more than one stage back, we 152 # simply re-export those packages in the middle stage(s) using the 153 # overrides attribute and the inherit syntax. 154 stage1 = stageFun { 155 gccPlain = bootstrapTools; 156 inherit (stage0.pkgs) glibc; 157 binutils = bootstrapTools; 158 coreutils = bootstrapTools; 159 gnugrep = bootstrapTools; 160 name = "bootstrap-gcc-wrapper"; 161 162 # Rebuild binutils to use from stage2 onwards. 163 overrides = pkgs: { 164 binutils = pkgs.binutils.override { gold = false; }; 165 inherit (stage0.pkgs) glibc; 166 167 # A threaded perl build needs glibc/libpthread_nonshared.a, 168 # which is not included in bootstrapTools, so disable threading. 169 # This is not an issue for the final stdenv, because this perl 170 # won't be included in the final stdenv and won't be exported to 171 # top-level pkgs as an override either. 172 perl = pkgs.perl.override { enableThreading = false; }; 173 }; 174 }; 175 176 177 # 2nd stdenv that contains our own rebuilt binutils and is used for 178 # compiling our own Glibc. 179 stage2 = stageFun { 180 gccPlain = bootstrapTools; 181 inherit (stage1.pkgs) glibc; 182 binutils = stage1.pkgs.binutils; 183 coreutils = bootstrapTools; 184 gnugrep = bootstrapTools; 185 name = "bootstrap-gcc-wrapper"; 186 187 overrides = pkgs: { 188 inherit (stage1.pkgs) perl binutils paxctl gnum4 bison; 189 # This also contains the full, dynamically linked, final Glibc. 190 }; 191 }; 192 193 194 # Construct a third stdenv identical to the 2nd, except that this 195 # one uses the rebuilt Glibc from stage2. It still uses the recent 196 # binutils and rest of the bootstrap tools, including GCC. 197 stage3 = stageFun { 198 gccPlain = bootstrapTools; 199 inherit (stage2.pkgs) glibc binutils; 200 coreutils = bootstrapTools; 201 gnugrep = bootstrapTools; 202 name = "bootstrap-gcc-wrapper"; 203 204 overrides = pkgs: rec { 205 inherit (stage2.pkgs) binutils glibc perl patchelf linuxHeaders gnum4 bison; 206 # Link GCC statically against GMP etc. This makes sense because 207 # these builds of the libraries are only used by GCC, so it 208 # reduces the size of the stdenv closure. 209 gmp = pkgs.gmp.override { stdenv = pkgs.makeStaticLibraries pkgs.stdenv; }; 210 mpfr = pkgs.mpfr.override { stdenv = pkgs.makeStaticLibraries pkgs.stdenv; }; 211 libmpc = pkgs.libmpc.override { stdenv = pkgs.makeStaticLibraries pkgs.stdenv; }; 212 isl_0_14 = pkgs.isl_0_14.override { stdenv = pkgs.makeStaticLibraries pkgs.stdenv; }; 213 gccPlain = pkgs.gcc.cc.override { 214 isl = isl_0_14; 215 }; 216 }; 217 extraBuildInputs = [ stage2.pkgs.patchelf stage2.pkgs.paxctl ]; 218 }; 219 220 221 # Construct a fourth stdenv that uses the new GCC. But coreutils is 222 # still from the bootstrap tools. 223 stage4 = stageFun { 224 inherit (stage3.pkgs) gccPlain glibc binutils; 225 gnugrep = bootstrapTools; 226 coreutils = bootstrapTools; 227 name = ""; 228 229 overrides = pkgs: { 230 # Zlib has to be inherited and not rebuilt in this stage, 231 # because gcc (since JAR support) already depends on zlib, and 232 # then if we already have a zlib we want to use that for the 233 # other purposes (binutils and top-level pkgs) too. 234 inherit (stage3.pkgs) gettext gnum4 bison gmp perl glibc zlib linuxHeaders; 235 236 gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) { 237 nativeTools = false; 238 nativeLibc = false; 239 isGNU = true; 240 cc = stage4.stdenv.cc.cc; 241 libc = stage4.pkgs.glibc; 242 inherit (stage4.pkgs) binutils coreutils gnugrep; 243 name = ""; 244 stdenv = stage4.stdenv; 245 shell = stage4.pkgs.bash + "/bin/bash"; 246 }; 247 }; 248 extraBuildInputs = [ stage3.pkgs.patchelf stage3.pkgs.xz ]; 249 }; 250 251 252 # Construct the final stdenv. It uses the Glibc and GCC, and adds 253 # in a new binutils that doesn't depend on bootstrap-tools, as well 254 # as dynamically linked versions of all other tools. 255 # 256 # When updating stdenvLinux, make sure that the result has no 257 # dependency (`nix-store -qR') on bootstrapTools or the first 258 # binutils built. 259 stdenvLinux = import ../generic rec { 260 inherit system config; 261 262 preHook = 263 '' 264 # Make "strip" produce deterministic output, by setting 265 # timestamps etc. to a fixed value. 266 commonStripFlags="--enable-deterministic-archives" 267 ${commonPreHook} 268 ''; 269 270 initialPath = 271 ((import ../common-path.nix) {pkgs = stage4.pkgs;}); 272 273 extraBuildInputs = [ stage4.pkgs.patchelf stage4.pkgs.paxctl ]; 274 275 cc = stage4.pkgs.gcc; 276 277 shell = cc.shell; 278 279 inherit (stage4.stdenv) fetchurlBoot; 280 281 extraAttrs = { 282 inherit (stage4.pkgs) glibc; 283 inherit platform bootstrapTools; 284 shellPackage = stage4.pkgs.bash; 285 }; 286 287 /* outputs TODO 288 allowedRequisites = with stage4.pkgs; 289 [ gzip bzip2 xz bash binutils coreutils diffutils findutils gawk 290 glibc gnumake gnused gnutar gnugrep gnupatch patchelf attr acl 291 paxctl zlib pcre linuxHeaders ed gcc gcc.cc libsigsegv 292 ]; 293 */ 294 295 overrides = pkgs: { 296 gcc = cc; 297 298 inherit (stage4.pkgs) 299 gzip bzip2 xz bash binutils coreutils diffutils findutils gawk 300 glibc gnumake gnused gnutar gnugrep gnupatch patchelf 301 attr acl paxctl zlib pcre; 302 }; 303 }; 304 305}