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