nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at devShellTools-shell 943 lines 35 kB view raw
1# This file constructs the standard build environment for the 2# Linux 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# It starts from prebuilt seed bootstrapFiles and creates a series of 8# nixpkgs instances (stages) to gradually rebuild stdenv, which 9# is used to build all other packages (including the bootstrapFiles). 10# 11# Goals of the bootstrap process: 12# 1. final stdenv must not reference any of the bootstrap files. 13# 2. final stdenv must not contain any of the bootstrap files. 14# 3. final stdenv must not contain any of the files directly 15# generated by the bootstrap code generators (assembler, linker, 16# compiler). 17# 18# These goals ensure that final packages and final stdenv are built 19# exclusively using nixpkgs package definitions and don't depend 20# on bootstrapTools (via direct references, inclusion 21# of copied code, or code compiled directly by bootstrapTools). 22# 23# Stages are described below along with their definitions. 24# 25# Debugging stdenv dependency graph: 26# An useful tool to explore dependencies across stages is to use 27# '__bootPackages' attribute of 'stdenv. Examples of last 3 stages: 28# - stdenv 29# - stdenv.__bootPackages.stdenv 30# - stdenv.__bootPackages.stdenv.__bootPackages.stdenv 31# - ... and so on. 32# 33# To explore build-time dependencies in graphical form one can use 34# the following: 35# $ nix-store --query --graph $(nix-instantiate -A stdenv) | 36# grep -P -v '[.]sh|[.]patch|bash|[.]tar' | # avoid clutter 37# dot -Tsvg > stdenv-final.svg 38# 39# To find all the packages built by a particular stdenv instance: 40# $ for stage in 0 1 2 3 4; do 41# echo "stage${stage} used in:" 42# nix-store --query --graph $(nix-instantiate -A stdenv) | 43# grep -P ".*bootstrap-stage${stage}-stdenv.*->.*" | 44# sed 's/"[0-9a-z]\{32\}-/"/g' 45# done 46# 47# To verify which stdenv was used to build a given final package: 48# $ nix-store --query --graph $(nix-instantiate -A stdenv) | 49# grep -P -v '[.]sh|[.]patch|bash|[.]tar' | 50# grep -P '.*stdenv.*->.*glibc-2' 51# "...-bootstrap-stage2-stdenv-linux.drv" -> "...-glibc-2.35-224.drv"; 52# 53# For a TUI (rather than CLI) view, you can use: 54# 55# $ nix-tree --derivation $(nix-instantiate -A stdenv) 56{ 57 lib, 58 localSystem, 59 crossSystem, 60 config, 61 overlays, 62 crossOverlays ? [ ], 63 64 bootstrapFiles ? 65 let 66 table = { 67 glibc = { 68 i686-linux = import ./bootstrap-files/i686-unknown-linux-gnu.nix; 69 x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-gnu.nix; 70 armv5tel-linux = import ./bootstrap-files/armv5tel-unknown-linux-gnueabi.nix; 71 armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-gnueabihf.nix; 72 armv7l-linux = import ./bootstrap-files/armv7l-unknown-linux-gnueabihf.nix; 73 aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-gnu.nix; 74 mipsel-linux = import ./bootstrap-files/mipsel-unknown-linux-gnu.nix; 75 mips64el-linux = import ( 76 if localSystem.isMips64n32 then 77 ./bootstrap-files/mips64el-unknown-linux-gnuabin32.nix 78 else 79 ./bootstrap-files/mips64el-unknown-linux-gnuabi64.nix 80 ); 81 powerpc64-linux = import ./bootstrap-files/powerpc64-unknown-linux-gnuabielfv2.nix; 82 powerpc64le-linux = import ./bootstrap-files/powerpc64le-unknown-linux-gnu.nix; 83 riscv64-linux = import ./bootstrap-files/riscv64-unknown-linux-gnu.nix; 84 s390x-linux = import ./bootstrap-files/s390x-unknown-linux-gnu.nix; 85 loongarch64-linux = import ./bootstrap-files/loongarch64-unknown-linux-gnu.nix; 86 }; 87 musl = { 88 aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-musl.nix; 89 armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-musleabihf.nix; 90 x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-musl.nix; 91 }; 92 }; 93 94 # Try to find an architecture compatible with our current system. We 95 # just try every bootstrap we’ve got and test to see if it is 96 # compatible with or current architecture. 97 getCompatibleTools = lib.foldl ( 98 v: system: 99 if v != null then 100 v 101 else if localSystem.canExecute (lib.systems.elaborate { inherit system; }) then 102 archLookupTable.${system} 103 else 104 null 105 ) null (lib.attrNames archLookupTable); 106 107 archLookupTable = table.${localSystem.libc} or (throw "unsupported libc for the pure Linux stdenv"); 108 files = 109 archLookupTable.${localSystem.system} or ( 110 if getCompatibleTools != null then 111 getCompatibleTools 112 else 113 (throw "unsupported platform for the pure Linux stdenv") 114 ); 115 in 116 (config.replaceBootstrapFiles or lib.id) files, 117}: 118 119assert crossSystem == localSystem; 120 121let 122 inherit (localSystem) system; 123 124 isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg); 125 isFromBootstrapFiles = pkg: pkg.passthru.isFromBootstrapFiles or false; 126 isBuiltByNixpkgsCompiler = pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc; 127 isBuiltByBootstrapFilesCompiler = pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc; 128 129 commonGccOverrides = { 130 # Use a deterministically built compiler 131 # see https://github.com/NixOS/nixpkgs/issues/108475 for context 132 reproducibleBuild = true; 133 profiledCompiler = false; 134 135 # It appears that libcc1 (which is not a g++ plugin; it is a gdb plugin) gets linked against 136 # the libstdc++ from the compiler that *built* g++, not the libstdc++ which was just built. 137 # This causes a reference chain from stdenv to the bootstrapFiles: 138 # 139 # stdenv -> gcc-lib -> xgcc-lib -> bootstrapFiles 140 # 141 disableGdbPlugin = true; 142 }; 143 144 commonPreHook = '' 145 export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}" 146 export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}" 147 ''; 148 149 # The bootstrap process proceeds in several steps. 150 151 # Create a standard environment by downloading pre-built binaries of 152 # coreutils, GCC, etc. 153 154 # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...). 155 bootstrapTools = import ./bootstrap-tools { 156 inherit (localSystem) libc system; 157 inherit lib bootstrapFiles config; 158 isFromBootstrapFiles = true; 159 }; 160 161 # This function builds the various standard environments used during 162 # the bootstrap. In all stages, we build an stdenv and the package 163 # set that can be built with that stdenv. 164 stageFun = 165 prevStage: 166 { 167 name, 168 overrides ? (self: super: { }), 169 extraNativeBuildInputs ? [ ], 170 callPackage ? null, 171 }: 172 173 let 174 175 thisStdenv = import ../generic { 176 name = "${name}-stdenv-linux"; 177 buildPlatform = localSystem; 178 hostPlatform = localSystem; 179 targetPlatform = localSystem; 180 inherit config extraNativeBuildInputs; 181 preHook = '' 182 # Don't patch #!/interpreter because it leads to retained 183 # dependencies on the bootstrapTools in the final stdenv. 184 dontPatchShebangs=1 185 ${commonPreHook} 186 ''; 187 shell = "${bootstrapTools}/bin/bash"; 188 initialPath = [ bootstrapTools ]; 189 190 fetchurlBoot = import ../../build-support/fetchurl/boot.nix { 191 inherit system; 192 inherit (config) rewriteURL; 193 }; 194 195 cc = 196 if prevStage.gcc-unwrapped == null then 197 null 198 else 199 (lib.makeOverridable (import ../../build-support/cc-wrapper) { 200 name = "${name}-gcc-wrapper"; 201 nativeTools = false; 202 nativeLibc = false; 203 expand-response-params = lib.optionalString ( 204 prevStage.stdenv.hasCC or false && prevStage.stdenv.cc != "/dev/null" 205 ) prevStage.expand-response-params; 206 cc = prevStage.gcc-unwrapped; 207 bintools = prevStage.binutils; 208 isGNU = true; 209 inherit (prevStage) libc; 210 inherit lib; 211 inherit (prevStage) coreutils gnugrep; 212 stdenvNoCC = prevStage.ccWrapperStdenv; 213 fortify-headers = prevStage.fortify-headers; 214 runtimeShell = prevStage.ccWrapperStdenv.shell; 215 }).overrideAttrs 216 ( 217 a: 218 lib.optionalAttrs (prevStage.gcc-unwrapped.passthru.isXgcc or false) { 219 # This affects only `xgcc` (the compiler which compiles the final compiler). 220 postFixup = (a.postFixup or "") + '' 221 echo "--sysroot=${lib.getDev prevStage.libc}" >> $out/nix-support/cc-cflags 222 ''; 223 } 224 ); 225 226 overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; }; 227 inherit callPackage; 228 }; 229 230 in 231 { 232 inherit config overlays; 233 stdenv = thisStdenv; 234 }; 235 236in 237assert bootstrapTools.passthru.isFromBootstrapFiles or false; # sanity check 238[ 239 240 ( 241 { }: 242 { 243 __raw = true; 244 245 gcc-unwrapped = null; 246 binutils = null; 247 coreutils = null; 248 gnugrep = null; 249 } 250 ) 251 252 # Build a dummy stdenv with no GCC or working fetchurl. This is 253 # because we need a stdenv to build the GCC wrapper and fetchurl. 254 ( 255 prevStage: 256 stageFun prevStage { 257 name = "bootstrap-stage0"; 258 259 overrides = self: super: { 260 # We thread stage0's stdenv through under this name so downstream stages 261 # can use it for wrapping gcc too. This way, downstream stages don't need 262 # to refer to this stage directly, which violates the principle that each 263 # stage should only access the stage that came before it. 264 ccWrapperStdenv = self.stdenv; 265 # The Glibc include directory cannot have the same prefix as the 266 # GCC include directory, since GCC gets confused otherwise (it 267 # will search the Glibc headers before the GCC headers). So 268 # create a dummy Glibc here, which will be used in the stdenv of 269 # stage1. 270 ${localSystem.libc} = self.stdenv.mkDerivation { 271 pname = "bootstrap-stage0-${localSystem.libc}"; 272 strictDeps = true; 273 version = "bootstrapFiles"; 274 enableParallelBuilding = true; 275 buildCommand = '' 276 mkdir -p $out 277 ln -s ${bootstrapTools}/lib $out/lib 278 '' 279 + lib.optionalString (localSystem.libc == "glibc") '' 280 ln -s ${bootstrapTools}/include-glibc $out/include 281 '' 282 + lib.optionalString (localSystem.libc == "musl") '' 283 ln -s ${bootstrapTools}/include-libc $out/include 284 ''; 285 passthru.isFromBootstrapFiles = true; 286 }; 287 gcc-unwrapped = bootstrapTools; 288 binutils = import ../../build-support/bintools-wrapper { 289 name = "bootstrap-stage0-binutils-wrapper"; 290 nativeTools = false; 291 nativeLibc = false; 292 expand-response-params = ""; 293 inherit lib; 294 inherit (self) 295 stdenvNoCC 296 coreutils 297 gnugrep 298 libc 299 ; 300 bintools = bootstrapTools; 301 runtimeShell = "${bootstrapTools}/bin/bash"; 302 }; 303 coreutils = bootstrapTools; 304 gnugrep = bootstrapTools; 305 }; 306 } 307 ) 308 309 # Create the first "real" standard environment. This one consists 310 # of bootstrap tools only, and a minimal Glibc to keep the GCC 311 # configure script happy. 312 # 313 # For clarity, we only use the previous stage when specifying these 314 # stages. So stageN should only ever have references for stage{N-1}. 315 # 316 # If we ever need to use a package from more than one stage back, we 317 # simply re-export those packages in the middle stage(s) using the 318 # overrides attribute and the inherit syntax. 319 ( 320 prevStage: 321 # previous stage0 stdenv: 322 assert isFromBootstrapFiles prevStage.binutils.bintools; 323 assert isFromBootstrapFiles prevStage."${localSystem.libc}"; 324 assert isFromBootstrapFiles prevStage.libc; 325 assert isFromBootstrapFiles prevStage.gcc-unwrapped; 326 assert isFromBootstrapFiles prevStage.coreutils; 327 assert isFromBootstrapFiles prevStage.gnugrep; 328 stageFun prevStage { 329 name = "bootstrap-stage1"; 330 331 # Rebuild binutils to use from stage2 onwards. 332 overrides = self: super: { 333 binutils-unwrapped = super.binutils-unwrapped.override { 334 enableGold = false; 335 }; 336 inherit (prevStage) 337 ccWrapperStdenv 338 gcc-unwrapped 339 coreutils 340 gnugrep 341 binutils 342 ; 343 344 ${localSystem.libc} = prevStage.${localSystem.libc}; 345 346 # A threaded perl build needs glibc/libpthread_nonshared.a, 347 # which is not included in bootstrapTools, so disable threading. 348 # This is not an issue for the final stdenv, because this perl 349 # won't be included in the final stdenv and won't be exported to 350 # top-level pkgs as an override either. 351 perl = super.perl.override { 352 enableThreading = false; 353 enableCrypt = false; 354 }; 355 356 # Let gettext "checking for working iconv" success without trying 357 # to convert between UTF-8 and EUC-JP which doesn't work here 358 # because of missing locale and gconv, same for libunistring below 359 gettext = super.gettext.overrideAttrs (attrs: { 360 env = attrs.env or { } // { 361 am_cv_func_iconv_works = "yes"; 362 }; 363 }); 364 }; 365 366 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64. 367 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ]; 368 } 369 ) 370 371 # First rebuild of gcc; this is linked against all sorts of junk 372 # from the bootstrap-files, but we only care about the code that 373 # this compiler *emits*. The `gcc` binary produced in this stage 374 # is not part of the final stdenv. 375 ( 376 prevStage: 377 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped; 378 assert isFromBootstrapFiles prevStage."${localSystem.libc}"; 379 assert isFromBootstrapFiles prevStage.libc; 380 assert isFromBootstrapFiles prevStage.gcc-unwrapped; 381 assert isFromBootstrapFiles prevStage.coreutils; 382 assert isFromBootstrapFiles prevStage.gnugrep; 383 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf; 384 stageFun prevStage { 385 name = "bootstrap-stage-xgcc"; 386 overrides = self: super: { 387 inherit (prevStage) 388 ccWrapperStdenv 389 coreutils 390 gnugrep 391 gettext 392 bison 393 texinfo 394 zlib 395 gnum4 396 perl 397 patchelf 398 ; 399 ${localSystem.libc} = prevStage.${localSystem.libc}; 400 gmp = super.gmp.override { cxx = false; }; 401 # This stage also rebuilds binutils which will of course be used only in the next stage. 402 # We inherit this until stage3, in stage4 it will be rebuilt using the adjacent bash/runtimeShell pkg. 403 # TODO(@sternenseemann): Can we already build the wrapper with the actual runtimeShell here? 404 # Historically, the wrapper didn't use runtimeShell, so the used shell had to be changed explicitly 405 # (or stdenvNoCC.shell would be used) which happened in stage4. 406 binutils = super.binutils.override { 407 runtimeShell = "${bootstrapTools}/bin/bash"; 408 }; 409 gcc-unwrapped = 410 (super.gcc-unwrapped.override ( 411 commonGccOverrides 412 // { 413 # The most logical name for this package would be something like 414 # "gcc-stage1". Unfortunately "stage" is already reserved for the 415 # layers of stdenv, so using "stage" in the name of this package 416 # would cause massive confusion. 417 # 418 # Gcc calls its "stage1" compiler `xgcc` (--disable-bootstrap results 419 # in `xgcc` being copied to $prefix/bin/gcc). So we imitate that. 420 # 421 name = "xgcc"; 422 423 # xgcc uses ld linked against nixpkgs' glibc and gcc built 424 # against bootstrapTools glibc. We can't allow loading 425 # $out/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so 426 # to mix libc.so: 427 # ...-binutils-patchelfed-ld-2.40/bin/ld: ...-xgcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so: 428 # error loading plugin: ...-bootstrap-tools/lib/libpthread.so.0: undefined symbol: __libc_vfork, version GLIBC_PRIVATE 429 enableLTO = false; 430 } 431 )).overrideAttrs 432 (a: { 433 434 # This signals to cc-wrapper (as overridden above in this file) to add `--sysroot` 435 # to `$out/nix-support/cc-cflags`. 436 passthru = a.passthru // { 437 isXgcc = true; 438 }; 439 440 # Gcc will look for the C library headers in 441 # 442 # ${with_build_sysroot}${native_system_header_dir} 443 # 444 # The ordinary gcc expression sets `--with-build-sysroot=/` and sets 445 # `native-system-header-dir` to `"${lib.getDev stdenv.cc.libc}/include`. 446 # 447 # Unfortunately the value of "--with-native-system-header-dir=" gets "burned in" to the 448 # compiler, and it is quite difficult to get the compiler to change or ignore it 449 # afterwards. On the other hand, the `sysroot` is very easy to change; you can just pass 450 # a `--sysroot` flag to `gcc`. 451 # 452 # So we override the expression to remove the default settings for these flags, and 453 # replace them such that the concatenated value will be the same as before, but we split 454 # the value between the two variables differently: `--native-system-header-dir=/include`, 455 # and `--with-build-sysroot=${lib.getDev stdenv.cc.libc}`. 456 # 457 configureFlags = (a.configureFlags or [ ]) ++ [ 458 "--with-native-system-header-dir=/include" 459 "--with-build-sysroot=${lib.getDev self.stdenv.cc.libc}" 460 # Don't assume that `gettext` was built with iconv support, since we don't have 461 # our own `glibc` yet. 462 "--disable-nls" 463 ]; 464 465 # This is a separate phase because gcc assembles its phase scripts 466 # in bash instead of nix (we should fix that). 467 preFixupPhases = (a.preFixupPhases or [ ]) ++ [ "preFixupXgccPhase" ]; 468 469 # This is needed to prevent "error: cycle detected in build of '...-xgcc-....drv' 470 # in the references of output 'lib' from output 'out'" 471 preFixupXgccPhase = '' 472 find $lib/lib/ -name \*.so\* -exec patchelf --shrink-rpath {} \; || true 473 ''; 474 }); 475 }; 476 477 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64. 478 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ]; 479 } 480 ) 481 482 # 2nd stdenv that contains our own rebuilt binutils and is used for 483 # compiling our own Glibc. 484 # 485 ( 486 prevStage: 487 # previous stage1 stdenv: 488 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped; 489 assert isFromBootstrapFiles prevStage."${localSystem.libc}"; 490 assert isFromBootstrapFiles prevStage.libc; 491 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped; 492 assert isFromBootstrapFiles prevStage.coreutils; 493 assert isFromBootstrapFiles prevStage.gnugrep; 494 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf; 495 stageFun prevStage { 496 name = "bootstrap-stage2"; 497 498 overrides = self: super: { 499 inherit (prevStage) 500 ccWrapperStdenv 501 gettext 502 gcc-unwrapped 503 coreutils 504 gnugrep 505 perl 506 gnum4 507 bison 508 texinfo 509 which 510 ; 511 dejagnu = super.dejagnu.overrideAttrs (a: { 512 doCheck = false; 513 }); 514 515 # Avoids infinite recursion, as this is in the build-time dependencies of libc. 516 libiconv = self.libcIconv prevStage.libc; 517 518 # We need libidn2 and its dependency libunistring as glibc dependency. 519 # To avoid the cycle, we build against bootstrap libc, nuke references, 520 # and use the result as input for our final glibc. We also pass this pair 521 # through, so the final package-set uses exactly the same builds. 522 libunistring = super.libunistring.overrideAttrs (attrs: { 523 postFixup = attrs.postFixup or "" + '' 524 ${self.nukeReferences}/bin/nuke-refs "$out"/lib/lib*.so.*.* 525 ''; 526 # Apparently iconv won't work with bootstrap glibc, but it will be used 527 # with glibc built later where we keep *this* build of libunistring, 528 # so we need to trick it into supporting libiconv. 529 env = attrs.env or { } // { 530 am_cv_func_iconv_works = "yes"; 531 }; 532 }); 533 libidn2 = super.libidn2.overrideAttrs (attrs: { 534 postFixup = attrs.postFixup or "" + '' 535 ${self.nukeReferences}/bin/nuke-refs -e '${lib.getLib self.libunistring}' \ 536 "$out"/lib/lib*.so.*.* 537 ''; 538 }); 539 540 # This also contains the full, dynamically linked, final Glibc. 541 binutils = prevStage.binutils.override { 542 # Rewrap the binutils with the new glibc, so both the next 543 # stage's wrappers use it. 544 inherit (self) libc; 545 546 # Unfortunately, when building gcc in the next stage, its LTO plugin 547 # would use the final libc but `ld` would use the bootstrap one, 548 # and that can fail to load. Therefore we upgrade `ld` to use newer libc; 549 # apparently the interpreter needs to match libc, too. 550 bintools = self.stdenvNoCC.mkDerivation { 551 pname = prevStage.bintools.bintools.pname + "-patchelfed-ld"; 552 inherit (prevStage.bintools.bintools) version; 553 passthru = { inherit (prevStage.bintools.passthru) isFromBootstrapFiles; }; 554 enableParallelBuilding = true; 555 dontUnpack = true; 556 dontBuild = true; 557 strictDeps = true; 558 # We wouldn't need to *copy* all, but it's easier and the result is temporary anyway. 559 installPhase = '' 560 mkdir -p "$out"/bin 561 cp -a '${prevStage.bintools.bintools}'/bin/* "$out"/bin/ 562 chmod +w "$out"/bin/ld.bfd 563 patchelf --set-interpreter '${self.libc}'/lib/ld*.so.? \ 564 --set-rpath "${self.libc}/lib:$(patchelf --print-rpath "$out"/bin/ld.bfd)" \ 565 "$out"/bin/ld.bfd 566 ''; 567 }; 568 }; 569 570 # TODO(amjoseph): It is not yet entirely clear why this is necessary. 571 # Something strange is going on with xgcc and libstdc++ on pkgsMusl. 572 patchelf = super.patchelf.overrideAttrs ( 573 previousAttrs: 574 lib.optionalAttrs super.stdenv.hostPlatform.isMusl { 575 NIX_CFLAGS_COMPILE = (previousAttrs.NIX_CFLAGS_COMPILE or "") + " -static-libstdc++"; 576 } 577 ); 578 579 }; 580 581 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64. 582 # `libtool` comes with obsolete config.sub/config.guess that don't recognize Risc-V. 583 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ]; 584 } 585 ) 586 587 # Construct a third stdenv identical to the 2nd, except that this 588 # one uses the rebuilt Glibc from stage2. It still uses the recent 589 # binutils and rest of the bootstrap tools, including GCC. 590 ( 591 prevStage: 592 # previous stage2 stdenv: 593 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 594 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 595 assert isBuiltByNixpkgsCompiler prevStage.libc; 596 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped; 597 assert isFromBootstrapFiles prevStage.coreutils; 598 assert isFromBootstrapFiles prevStage.gnugrep; 599 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 600 assert lib.all isBuiltByNixpkgsCompiler [ 601 prevStage.gmp 602 prevStage.isl_0_20 603 prevStage.libmpc 604 prevStage.mpfr 605 ]; 606 stageFun prevStage { 607 name = "bootstrap-stage3"; 608 609 overrides = 610 self: super: 611 { 612 inherit (prevStage) 613 ccWrapperStdenv 614 binutils 615 coreutils 616 gnugrep 617 perl 618 patchelf 619 linuxHeaders 620 gnum4 621 bison 622 libidn2 623 libunistring 624 libxcrypt 625 ; 626 # We build a special copy of libgmp which doesn't use libstdc++, because 627 # xgcc++'s libstdc++ references the bootstrap-files (which is what 628 # compiles xgcc++). 629 gmp = super.gmp.override { cxx = false; }; 630 } 631 // { 632 ${localSystem.libc} = prevStage.${localSystem.libc}; 633 gcc-unwrapped = 634 (super.gcc-unwrapped.override ( 635 commonGccOverrides 636 // { 637 inherit (prevStage) which; 638 } 639 )).overrideAttrs 640 (a: { 641 # so we can add them to allowedRequisites below 642 passthru = a.passthru // { 643 inherit (self) 644 gmp 645 mpfr 646 libmpc 647 isl 648 ; 649 }; 650 }); 651 }; 652 extraNativeBuildInputs = [ 653 prevStage.patchelf 654 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64. 655 prevStage.updateAutotoolsGnuConfigScriptsHook 656 ]; 657 } 658 ) 659 660 # Construct a fourth stdenv that uses the new GCC. But coreutils is 661 # still from the bootstrap tools. 662 # 663 ( 664 prevStage: 665 # previous stage3 stdenv: 666 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 667 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 668 assert isBuiltByNixpkgsCompiler prevStage.libc; 669 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped; 670 assert isFromBootstrapFiles prevStage.coreutils; 671 assert isFromBootstrapFiles prevStage.gnugrep; 672 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 673 stageFun prevStage { 674 name = "bootstrap-stage4"; 675 676 overrides = self: super: { 677 # Zlib has to be inherited and not rebuilt in this stage, 678 # because gcc (since JAR support) already depends on zlib, and 679 # then if we already have a zlib we want to use that for the 680 # other purposes (binutils and top-level pkgs) too. 681 inherit (prevStage) 682 gettext 683 gnum4 684 bison 685 perl 686 texinfo 687 zlib 688 linuxHeaders 689 libidn2 690 libunistring 691 ; 692 ${localSystem.libc} = prevStage.${localSystem.libc}; 693 # Since this is the first fresh build of binutils since stage2, our own runtimeShell will be used. 694 binutils = super.binutils.override { 695 # Build expand-response-params with last stage like below 696 inherit (prevStage) expand-response-params; 697 }; 698 699 # To allow users' overrides inhibit dependencies too heavy for 700 # bootstrap, like guile: https://github.com/NixOS/nixpkgs/issues/181188 701 gnumake = super.gnumake.override { inBootstrap = true; }; 702 703 gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) { 704 nativeTools = false; 705 nativeLibc = false; 706 isGNU = true; 707 inherit (prevStage) expand-response-params; 708 cc = prevStage.gcc-unwrapped; 709 bintools = self.binutils; 710 inherit lib; 711 inherit (self) 712 stdenvNoCC 713 coreutils 714 gnugrep 715 runtimeShell 716 libc 717 ; 718 fortify-headers = self.fortify-headers; 719 }; 720 }; 721 extraNativeBuildInputs = [ 722 prevStage.patchelf 723 prevStage.xz 724 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64. 725 prevStage.updateAutotoolsGnuConfigScriptsHook 726 ]; 727 } 728 ) 729 730 # Construct the final stdenv. It uses the Glibc and GCC, and adds 731 # in a new binutils that doesn't depend on bootstrap-tools, as well 732 # as dynamically linked versions of all other tools. 733 # 734 # When updating stdenvLinux, make sure that the result has no 735 # dependency (`nix-store -qR') on bootstrapTools or the first 736 # binutils built. 737 # 738 ( 739 prevStage: 740 # previous stage4 stdenv; see stage3 comment regarding gcc, 741 # which applies here as well. 742 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 743 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 744 assert isBuiltByNixpkgsCompiler prevStage.libc; 745 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped; 746 assert isBuiltByNixpkgsCompiler prevStage.coreutils; 747 assert isBuiltByNixpkgsCompiler prevStage.gnugrep; 748 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 749 { 750 inherit config overlays; 751 stdenv = import ../generic rec { 752 name = "stdenv-linux"; 753 754 buildPlatform = localSystem; 755 hostPlatform = localSystem; 756 targetPlatform = localSystem; 757 inherit config; 758 759 preHook = commonPreHook; 760 761 initialPath = ((import ../generic/common-path.nix) { pkgs = prevStage; }); 762 763 extraNativeBuildInputs = [ 764 prevStage.patchelf 765 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64. 766 prevStage.updateAutotoolsGnuConfigScriptsHook 767 ]; 768 769 cc = prevStage.gcc; 770 771 shell = cc.shell; 772 773 inherit (prevStage.stdenv) fetchurlBoot; 774 775 extraAttrs = { 776 inherit bootstrapTools; 777 shellPackage = prevStage.bash; 778 }; 779 780 disallowedRequisites = [ bootstrapTools.out ]; 781 782 # Mainly avoid reference to bootstrap tools 783 allowedRequisites = 784 let 785 inherit (prevStage) 786 gzip 787 bzip2 788 xz 789 zlib 790 bashNonInteractive 791 binutils 792 coreutils 793 diffutils 794 findutils 795 gawk 796 gmp 797 gnumake 798 gnused 799 gnutar 800 gnugrep 801 gnupatch 802 patchelf 803 ed 804 file 805 glibc 806 attr 807 acl 808 libidn2 809 libunistring 810 linuxHeaders 811 gcc 812 fortify-headers 813 gcc-unwrapped 814 ; 815 in 816 # Simple executable tools 817 lib.concatMap 818 (p: [ 819 (lib.getBin p) 820 (lib.getLib p) 821 ]) 822 [ 823 gzip 824 bzip2 825 xz 826 bashNonInteractive 827 binutils.bintools 828 coreutils 829 diffutils 830 findutils 831 gawk 832 gmp 833 gnumake 834 gnused 835 gnutar 836 gnugrep 837 gnupatch 838 patchelf 839 ed 840 file 841 ] 842 # Library dependencies 843 ++ map lib.getLib [ 844 attr 845 acl 846 zlib 847 gnugrep.pcre2 848 libidn2 849 libunistring 850 ] 851 # More complicated cases 852 ++ (map (x: lib.getOutput x (prevStage.libc)) [ 853 "out" 854 "dev" 855 "bin" 856 ]) 857 ++ [ 858 linuxHeaders # propagated from .dev 859 binutils 860 gcc 861 gcc.cc 862 gcc.cc.lib 863 gcc.expand-response-params # != (prevStage.)expand-response-params 864 gcc.cc.libgcc 865 glibc.passthru.libgcc 866 ] 867 ++ lib.optionals (localSystem.libc == "musl") [ fortify-headers ] 868 ++ [ 869 prevStage.updateAutotoolsGnuConfigScriptsHook 870 prevStage.gnu-config 871 ] 872 ++ [ 873 gcc-unwrapped.gmp 874 gcc-unwrapped.libmpc 875 gcc-unwrapped.mpfr 876 gcc-unwrapped.isl 877 ]; 878 879 overrides = 880 self: super: 881 { 882 inherit (prevStage) 883 gzip 884 bzip2 885 xz 886 bashNonInteractive 887 coreutils 888 diffutils 889 findutils 890 gawk 891 gnused 892 gnutar 893 gnugrep 894 gnupatch 895 patchelf 896 attr 897 acl 898 zlib 899 libunistring 900 ; 901 inherit (prevStage.gnugrep) pcre2; 902 ${localSystem.libc} = prevStage.${localSystem.libc}; 903 904 # Hack: avoid libidn2.{bin,dev} referencing bootstrap tools. There's a logical cycle. 905 libidn2 = import ../../development/libraries/libidn2/no-bootstrap-reference.nix { 906 inherit lib; 907 inherit (prevStage) libidn2; 908 inherit (self) 909 stdenv 910 runCommandLocal 911 patchelf 912 libunistring 913 ; 914 }; 915 916 gnumake = super.gnumake.override { inBootstrap = false; }; 917 } 918 // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) { 919 # Need to get rid of these when cross-compiling. 920 inherit (prevStage) binutils binutils-unwrapped; 921 gcc = cc; 922 }; 923 }; 924 } 925 ) 926 927 # This "no-op" stage is just a place to put the assertions about stage5. 928 ( 929 prevStage: 930 # previous stage5 stdenv; see stage3 comment regarding gcc, 931 # which applies here as well. 932 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 933 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 934 assert isBuiltByNixpkgsCompiler prevStage.libc; 935 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped; 936 assert isBuiltByNixpkgsCompiler prevStage.coreutils; 937 assert isBuiltByNixpkgsCompiler prevStage.gnugrep; 938 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 939 { 940 inherit (prevStage) config overlays stdenv; 941 } 942 ) 943]