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