Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
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{ lib 57, localSystem, crossSystem, config, overlays, crossOverlays ? [] 58 59, bootstrapFiles ? 60 let table = { 61 glibc = { 62 i686-linux = import ./bootstrap-files/i686.nix; 63 x86_64-linux = import ./bootstrap-files/x86_64.nix; 64 armv5tel-linux = import ./bootstrap-files/armv5tel.nix; 65 armv6l-linux = import ./bootstrap-files/armv6l.nix; 66 armv7l-linux = import ./bootstrap-files/armv7l.nix; 67 aarch64-linux = import ./bootstrap-files/aarch64.nix; 68 mipsel-linux = import ./bootstrap-files/mipsel.nix; 69 mips64el-linux = import 70 (if localSystem.isMips64n32 71 then ./bootstrap-files/mips64el-n32.nix 72 else ./bootstrap-files/mips64el.nix); 73 powerpc64le-linux = import ./bootstrap-files/powerpc64le.nix; 74 riscv64-linux = import ./bootstrap-files/riscv64.nix; 75 }; 76 musl = { 77 aarch64-linux = import ./bootstrap-files/aarch64-musl.nix; 78 armv6l-linux = import ./bootstrap-files/armv6l-musl.nix; 79 x86_64-linux = import ./bootstrap-files/x86_64-musl.nix; 80 }; 81 }; 82 83 # Try to find an architecture compatible with our current system. We 84 # just try every bootstrap we’ve got and test to see if it is 85 # compatible with or current architecture. 86 getCompatibleTools = lib.foldl (v: system: 87 if v != null then v 88 else if localSystem.canExecute (lib.systems.elaborate { inherit system; }) then archLookupTable.${system} 89 else null) null (lib.attrNames archLookupTable); 90 91 archLookupTable = table.${localSystem.libc} 92 or (abort "unsupported libc for the pure Linux stdenv"); 93 files = archLookupTable.${localSystem.system} or (if getCompatibleTools != null then getCompatibleTools 94 else (abort "unsupported platform for the pure Linux stdenv")); 95 in files 96}: 97 98assert crossSystem == localSystem; 99 100let 101 inherit (localSystem) system; 102 103 isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg); 104 isFromBootstrapFiles = 105 pkg: pkg.passthru.isFromBootstrapFiles or false; 106 isBuiltByNixpkgsCompiler = 107 pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc; 108 isBuiltByBootstrapFilesCompiler = 109 pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc; 110 111 commonGccOverrides = { 112 # Use a deterministically built compiler 113 # see https://github.com/NixOS/nixpkgs/issues/108475 for context 114 reproducibleBuild = true; 115 profiledCompiler = false; 116 117 # It appears that libcc1 (which is not a g++ plugin; it is a gdb plugin) gets linked against 118 # the libstdc++ from the compiler that *built* g++, not the libstdc++ which was just built. 119 # This causes a reference chain from stdenv to the bootstrapFiles: 120 # 121 # stdenv -> gcc-lib -> xgcc-lib -> bootstrapFiles 122 # 123 disableGdbPlugin = true; 124 }; 125 126 commonPreHook = 127 '' 128 export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}" 129 export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}" 130 ''; 131 132 133 # The bootstrap process proceeds in several steps. 134 135 136 # Create a standard environment by downloading pre-built binaries of 137 # coreutils, GCC, etc. 138 139 140 # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...). 141 bootstrapTools = (import (if localSystem.libc == "musl" then ./bootstrap-tools-musl else ./bootstrap-tools) { 142 inherit system bootstrapFiles; 143 extraAttrs = lib.optionalAttrs config.contentAddressedByDefault { 144 __contentAddressed = true; 145 outputHashAlgo = "sha256"; 146 outputHashMode = "recursive"; 147 }; 148 }) // { passthru.isFromBootstrapFiles = true; }; 149 150 getLibc = stage: stage.${localSystem.libc}; 151 152 153 # This function builds the various standard environments used during 154 # the bootstrap. In all stages, we build an stdenv and the package 155 # set that can be built with that stdenv. 156 stageFun = prevStage: 157 { name, overrides ? (self: super: {}), extraNativeBuildInputs ? [] }: 158 159 let 160 161 thisStdenv = import ../generic { 162 name = "${name}-stdenv-linux"; 163 buildPlatform = localSystem; 164 hostPlatform = localSystem; 165 targetPlatform = localSystem; 166 inherit config extraNativeBuildInputs; 167 preHook = 168 '' 169 # Don't patch #!/interpreter because it leads to retained 170 # dependencies on the bootstrapTools in the final stdenv. 171 dontPatchShebangs=1 172 ${commonPreHook} 173 ''; 174 shell = "${bootstrapTools}/bin/bash"; 175 initialPath = [bootstrapTools]; 176 177 fetchurlBoot = import ../../build-support/fetchurl/boot.nix { 178 inherit system; 179 }; 180 181 cc = if prevStage.gcc-unwrapped == null 182 then null 183 else (lib.makeOverridable (import ../../build-support/cc-wrapper) { 184 name = "${name}-gcc-wrapper"; 185 nativeTools = false; 186 nativeLibc = false; 187 buildPackages = lib.optionalAttrs (prevStage ? stdenv) { 188 inherit (prevStage) stdenv; 189 }; 190 cc = prevStage.gcc-unwrapped; 191 bintools = prevStage.binutils; 192 isGNU = true; 193 libc = getLibc prevStage; 194 inherit lib; 195 inherit (prevStage) coreutils gnugrep; 196 stdenvNoCC = prevStage.ccWrapperStdenv; 197 }).overrideAttrs(a: lib.optionalAttrs (prevStage.gcc-unwrapped.passthru.isXgcc or false) { 198 # This affects only `xgcc` (the compiler which compiles the final compiler). 199 postFixup = (a.postFixup or "") + '' 200 echo "--sysroot=${lib.getDev (getLibc prevStage)}" >> $out/nix-support/cc-cflags 201 ''; 202 }); 203 204 overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; }; 205 }; 206 207 in { 208 inherit config overlays; 209 stdenv = thisStdenv; 210 }; 211 212in 213 assert bootstrapTools.passthru.isFromBootstrapFiles or false; # sanity check 214[ 215 216 ({}: { 217 __raw = true; 218 219 gcc-unwrapped = null; 220 binutils = null; 221 coreutils = null; 222 gnugrep = null; 223 }) 224 225 # Build a dummy stdenv with no GCC or working fetchurl. This is 226 # because we need a stdenv to build the GCC wrapper and fetchurl. 227 (prevStage: stageFun prevStage { 228 name = "bootstrap-stage0"; 229 230 overrides = self: super: { 231 # We thread stage0's stdenv through under this name so downstream stages 232 # can use it for wrapping gcc too. This way, downstream stages don't need 233 # to refer to this stage directly, which violates the principle that each 234 # stage should only access the stage that came before it. 235 ccWrapperStdenv = self.stdenv; 236 # The Glibc include directory cannot have the same prefix as the 237 # GCC include directory, since GCC gets confused otherwise (it 238 # will search the Glibc headers before the GCC headers). So 239 # create a dummy Glibc here, which will be used in the stdenv of 240 # stage1. 241 ${localSystem.libc} = self.stdenv.mkDerivation { 242 pname = "bootstrap-stage0-${localSystem.libc}"; 243 strictDeps = true; 244 version = "bootstrapFiles"; 245 enableParallelBuilding = true; 246 buildCommand = '' 247 mkdir -p $out 248 ln -s ${bootstrapTools}/lib $out/lib 249 '' + lib.optionalString (localSystem.libc == "glibc") '' 250 ln -s ${bootstrapTools}/include-glibc $out/include 251 '' + lib.optionalString (localSystem.libc == "musl") '' 252 ln -s ${bootstrapTools}/include-libc $out/include 253 ''; 254 passthru.isFromBootstrapFiles = true; 255 }; 256 gcc-unwrapped = bootstrapTools; 257 binutils = import ../../build-support/bintools-wrapper { 258 name = "bootstrap-stage0-binutils-wrapper"; 259 nativeTools = false; 260 nativeLibc = false; 261 buildPackages = { }; 262 libc = getLibc self; 263 inherit lib; 264 inherit (self) stdenvNoCC coreutils gnugrep; 265 bintools = bootstrapTools; 266 }; 267 coreutils = bootstrapTools; 268 gnugrep = bootstrapTools; 269 }; 270 }) 271 272 273 # Create the first "real" standard environment. This one consists 274 # of bootstrap tools only, and a minimal Glibc to keep the GCC 275 # configure script happy. 276 # 277 # For clarity, we only use the previous stage when specifying these 278 # stages. So stageN should only ever have references for stage{N-1}. 279 # 280 # If we ever need to use a package from more than one stage back, we 281 # simply re-export those packages in the middle stage(s) using the 282 # overrides attribute and the inherit syntax. 283 (prevStage: 284 # previous stage0 stdenv: 285 assert isFromBootstrapFiles prevStage.binutils.bintools; 286 assert isFromBootstrapFiles prevStage."${localSystem.libc}"; 287 assert isFromBootstrapFiles prevStage.gcc-unwrapped; 288 assert isFromBootstrapFiles prevStage.coreutils; 289 assert isFromBootstrapFiles prevStage.gnugrep; 290 stageFun prevStage { 291 name = "bootstrap-stage1"; 292 293 # Rebuild binutils to use from stage2 onwards. 294 overrides = self: super: { 295 binutils-unwrapped = super.binutils-unwrapped.override { 296 enableGold = false; 297 }; 298 inherit (prevStage) 299 ccWrapperStdenv 300 gcc-unwrapped coreutils gnugrep binutils; 301 302 ${localSystem.libc} = getLibc prevStage; 303 304 # A threaded perl build needs glibc/libpthread_nonshared.a, 305 # which is not included in bootstrapTools, so disable threading. 306 # This is not an issue for the final stdenv, because this perl 307 # won't be included in the final stdenv and won't be exported to 308 # top-level pkgs as an override either. 309 perl = super.perl.override { enableThreading = false; enableCrypt = false; }; 310 }; 311 312 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64. 313 extraNativeBuildInputs = 314 lib.optional (localSystem.isLoongArch64) prevStage.updateAutotoolsGnuConfigScriptsHook; 315 }) 316 317 # First rebuild of gcc; this is linked against all sorts of junk 318 # from the bootstrap-files, but we only care about the code that 319 # this compiler *emits*. The `gcc` binary produced in this stage 320 # is not part of the final stdenv. 321 (prevStage: 322 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped; 323 assert isFromBootstrapFiles prevStage."${localSystem.libc}"; 324 assert isFromBootstrapFiles prevStage.gcc-unwrapped; 325 assert isFromBootstrapFiles prevStage.coreutils; 326 assert isFromBootstrapFiles prevStage.gnugrep; 327 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf; 328 stageFun prevStage { 329 name = "bootstrap-stage-xgcc"; 330 overrides = final: prev: { 331 inherit (prevStage) ccWrapperStdenv coreutils gnugrep gettext bison texinfo zlib gnum4 perl patchelf; 332 ${localSystem.libc} = getLibc prevStage; 333 gmp = prev.gmp.override { cxx = false; }; 334 gcc-unwrapped = 335 (prev.gcc-unwrapped.override (commonGccOverrides // { 336 # The most logical name for this package would be something like 337 # "gcc-stage1". Unfortunately "stage" is already reserved for the 338 # layers of stdenv, so using "stage" in the name of this package 339 # would cause massive confusion. 340 # 341 # Gcc calls its "stage1" compiler `xgcc` (--disable-bootstrap results 342 # in `xgcc` being copied to $prefix/bin/gcc). So we imitate that. 343 # 344 name = "xgcc"; 345 346 # xgcc uses ld linked against nixpkgs' glibc and gcc built 347 # against bootstrapTools glibc. We can't allow loading 348 # $out/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so 349 # to mix libc.so: 350 # ...-binutils-patchelfed-ld-2.40/bin/ld: ...-xgcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so: 351 # error loading plugin: ...-bootstrap-tools/lib/libpthread.so.0: undefined symbol: __libc_vfork, version GLIBC_PRIVATE 352 enableLTO = false; 353 })).overrideAttrs (a: { 354 355 # This signals to cc-wrapper (as overridden above in this file) to add `--sysroot` 356 # to `$out/nix-support/cc-cflags`. 357 passthru = a.passthru // { isXgcc = true; }; 358 359 # Gcc will look for the C library headers in 360 # 361 # ${with_build_sysroot}${native_system_header_dir} 362 # 363 # The ordinary gcc expression sets `--with-build-sysroot=/` and sets 364 # `native-system-header-dir` to `"${lib.getDev stdenv.cc.libc}/include`. 365 # 366 # Unfortunately the value of "--with-native-system-header-dir=" gets "burned in" to the 367 # compiler, and it is quite difficult to get the compiler to change or ignore it 368 # afterwards. On the other hand, the `sysroot` is very easy to change; you can just pass 369 # a `--sysroot` flag to `gcc`. 370 # 371 # So we override the expression to remove the default settings for these flags, and 372 # replace them such that the concatenated value will be the same as before, but we split 373 # the value between the two variables differently: `--native-system-header-dir=/include`, 374 # and `--with-build-sysroot=${lib.getDev stdenv.cc.libc}`. 375 # 376 configureFlags = (a.configureFlags or []) ++ [ 377 "--with-native-system-header-dir=/include" 378 "--with-build-sysroot=${lib.getDev final.stdenv.cc.libc}" 379 ]; 380 381 # This is a separate phase because gcc assembles its phase scripts 382 # in bash instead of nix (we should fix that). 383 preFixupPhases = (a.preFixupPhases or []) ++ [ "preFixupXgccPhase" ]; 384 385 # This is needed to prevent "error: cycle detected in build of '...-xgcc-....drv' 386 # in the references of output 'lib' from output 'out'" 387 preFixupXgccPhase = '' 388 find $lib/lib/ -name \*.so\* -exec patchelf --shrink-rpath {} \; || true 389 ''; 390 }); 391 }; 392 393 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64. 394 extraNativeBuildInputs = 395 lib.optional (localSystem.isLoongArch64) prevStage.updateAutotoolsGnuConfigScriptsHook; 396 }) 397 398 # 2nd stdenv that contains our own rebuilt binutils and is used for 399 # compiling our own Glibc. 400 # 401 (prevStage: 402 # previous stage1 stdenv: 403 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped; 404 assert isFromBootstrapFiles prevStage."${localSystem.libc}"; 405 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped; 406 assert isFromBootstrapFiles prevStage.coreutils; 407 assert isFromBootstrapFiles prevStage.gnugrep; 408 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf; 409 stageFun prevStage { 410 name = "bootstrap-stage2"; 411 412 overrides = self: super: { 413 inherit (prevStage) 414 ccWrapperStdenv gettext 415 gcc-unwrapped coreutils gnugrep 416 perl gnum4 bison texinfo which; 417 dejagnu = super.dejagnu.overrideAttrs (a: { doCheck = false; } ); 418 419 # We need libidn2 and its dependency libunistring as glibc dependency. 420 # To avoid the cycle, we build against bootstrap libc, nuke references, 421 # and use the result as input for our final glibc. We also pass this pair 422 # through, so the final package-set uses exactly the same builds. 423 libunistring = super.libunistring.overrideAttrs (attrs: { 424 postFixup = attrs.postFixup or "" + '' 425 ${self.nukeReferences}/bin/nuke-refs "$out"/lib/lib*.so.*.* 426 ''; 427 # Apparently iconv won't work with bootstrap glibc, but it will be used 428 # with glibc built later where we keep *this* build of libunistring, 429 # so we need to trick it into supporting libiconv. 430 env = attrs.env or {} // { am_cv_func_iconv_works = "yes"; }; 431 }); 432 libidn2 = super.libidn2.overrideAttrs (attrs: { 433 postFixup = attrs.postFixup or "" + '' 434 ${self.nukeReferences}/bin/nuke-refs -e '${lib.getLib self.libunistring}' \ 435 "$out"/lib/lib*.so.*.* 436 ''; 437 }); 438 439 # This also contains the full, dynamically linked, final Glibc. 440 binutils = prevStage.binutils.override { 441 # Rewrap the binutils with the new glibc, so both the next 442 # stage's wrappers use it. 443 libc = getLibc self; 444 445 # Unfortunately, when building gcc in the next stage, its LTO plugin 446 # would use the final libc but `ld` would use the bootstrap one, 447 # and that can fail to load. Therefore we upgrade `ld` to use newer libc; 448 # apparently the interpreter needs to match libc, too. 449 bintools = self.stdenvNoCC.mkDerivation { 450 pname = prevStage.bintools.bintools.pname + "-patchelfed-ld"; 451 inherit (prevStage.bintools.bintools) version; 452 passthru = { inherit (prevStage.bintools.passthru) isFromBootstrapFiles; }; 453 enableParallelBuilding = true; 454 dontUnpack = true; 455 dontBuild = true; 456 strictDeps = true; 457 # We wouldn't need to *copy* all, but it's easier and the result is temporary anyway. 458 installPhase = '' 459 mkdir -p "$out"/bin 460 cp -a '${prevStage.bintools.bintools}'/bin/* "$out"/bin/ 461 chmod +w "$out"/bin/ld.bfd 462 patchelf --set-interpreter '${getLibc self}'/lib/ld*.so.? \ 463 --set-rpath "${getLibc self}/lib:$(patchelf --print-rpath "$out"/bin/ld.bfd)" \ 464 "$out"/bin/ld.bfd 465 ''; 466 }; 467 }; 468 469 # TODO(amjoseph): It is not yet entirely clear why this is necessary. 470 # Something strange is going on with xgcc and libstdc++ on pkgsMusl. 471 patchelf = super.patchelf.overrideAttrs(previousAttrs: 472 lib.optionalAttrs super.stdenv.hostPlatform.isMusl { 473 NIX_CFLAGS_COMPILE = (previousAttrs.NIX_CFLAGS_COMPILE or "") + " -static-libstdc++"; 474 }); 475 476 }; 477 478 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64. 479 # `libtool` comes with obsolete config.sub/config.guess that don't recognize Risc-V. 480 extraNativeBuildInputs = 481 lib.optional (localSystem.isLoongArch64 || localSystem.isRiscV) prevStage.updateAutotoolsGnuConfigScriptsHook; 482 }) 483 484 485 # Construct a third stdenv identical to the 2nd, except that this 486 # one uses the rebuilt Glibc from stage2. It still uses the recent 487 # binutils and rest of the bootstrap tools, including GCC. 488 (prevStage: 489 # previous stage2 stdenv: 490 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 491 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 492 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped; 493 assert isFromBootstrapFiles prevStage.coreutils; 494 assert isFromBootstrapFiles prevStage.gnugrep; 495 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 496 assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [ gmp isl_0_20 libmpc mpfr ]); 497 stageFun prevStage { 498 name = "bootstrap-stage3"; 499 500 overrides = self: super: rec { 501 inherit (prevStage) 502 ccWrapperStdenv 503 binutils coreutils gnugrep gettext 504 perl patchelf linuxHeaders gnum4 bison libidn2 libunistring libxcrypt; 505 # We build a special copy of libgmp which doesn't use libstdc++, because 506 # xgcc++'s libstdc++ references the bootstrap-files (which is what 507 # compiles xgcc++). 508 gmp = super.gmp.override { cxx = false; }; 509 } // { 510 ${localSystem.libc} = getLibc prevStage; 511 gcc-unwrapped = (super.gcc-unwrapped.override (commonGccOverrides // { 512 inherit (prevStage) which; 513 } 514 )).overrideAttrs (a: { 515 # so we can add them to allowedRequisites below 516 passthru = a.passthru // { inherit (self) gmp mpfr libmpc isl; }; 517 }); 518 }; 519 extraNativeBuildInputs = [ prevStage.patchelf ] ++ 520 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64. 521 lib.optional (!localSystem.isx86 || localSystem.libc == "musl") 522 prevStage.updateAutotoolsGnuConfigScriptsHook; 523 }) 524 525 526 # Construct a fourth stdenv that uses the new GCC. But coreutils is 527 # still from the bootstrap tools. 528 # 529 (prevStage: 530 # previous stage3 stdenv: 531 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 532 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 533 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped; 534 assert isFromBootstrapFiles prevStage.coreutils; 535 assert isFromBootstrapFiles prevStage.gnugrep; 536 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 537 stageFun prevStage { 538 name = "bootstrap-stage4"; 539 540 overrides = self: super: { 541 # Zlib has to be inherited and not rebuilt in this stage, 542 # because gcc (since JAR support) already depends on zlib, and 543 # then if we already have a zlib we want to use that for the 544 # other purposes (binutils and top-level pkgs) too. 545 inherit (prevStage) gettext gnum4 bison perl texinfo zlib linuxHeaders libidn2 libunistring; 546 ${localSystem.libc} = getLibc prevStage; 547 binutils = super.binutils.override { 548 # Don't use stdenv's shell but our own 549 shell = self.bash + "/bin/bash"; 550 # Build expand-response-params with last stage like below 551 buildPackages = { 552 inherit (prevStage) stdenv; 553 }; 554 }; 555 556 # To allow users' overrides inhibit dependencies too heavy for 557 # bootstrap, like guile: https://github.com/NixOS/nixpkgs/issues/181188 558 gnumake = super.gnumake.override { inBootstrap = true; }; 559 560 gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) { 561 nativeTools = false; 562 nativeLibc = false; 563 isGNU = true; 564 buildPackages = { 565 inherit (prevStage) stdenv; 566 }; 567 cc = prevStage.gcc-unwrapped; 568 bintools = self.binutils; 569 libc = getLibc self; 570 inherit lib; 571 inherit (self) stdenvNoCC coreutils gnugrep; 572 shell = self.bash + "/bin/bash"; 573 }; 574 }; 575 extraNativeBuildInputs = [ prevStage.patchelf prevStage.xz ] ++ 576 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64. 577 lib.optional (!localSystem.isx86 || localSystem.libc == "musl") 578 prevStage.updateAutotoolsGnuConfigScriptsHook; 579 }) 580 581 # Construct the final stdenv. It uses the Glibc and GCC, and adds 582 # in a new binutils that doesn't depend on bootstrap-tools, as well 583 # as dynamically linked versions of all other tools. 584 # 585 # When updating stdenvLinux, make sure that the result has no 586 # dependency (`nix-store -qR') on bootstrapTools or the first 587 # binutils built. 588 # 589 (prevStage: 590 # previous stage4 stdenv; see stage3 comment regarding gcc, 591 # which applies here as well. 592 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 593 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 594 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped; 595 assert isBuiltByNixpkgsCompiler prevStage.coreutils; 596 assert isBuiltByNixpkgsCompiler prevStage.gnugrep; 597 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 598 { 599 inherit config overlays; 600 stdenv = import ../generic rec { 601 name = "stdenv-linux"; 602 603 buildPlatform = localSystem; 604 hostPlatform = localSystem; 605 targetPlatform = localSystem; 606 inherit config; 607 608 preHook = commonPreHook; 609 610 initialPath = 611 ((import ../generic/common-path.nix) {pkgs = prevStage;}); 612 613 extraNativeBuildInputs = [ prevStage.patchelf ] ++ 614 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64. 615 lib.optional (!localSystem.isx86 || localSystem.libc == "musl") 616 prevStage.updateAutotoolsGnuConfigScriptsHook; 617 618 cc = prevStage.gcc; 619 620 shell = cc.shell; 621 622 inherit (prevStage.stdenv) fetchurlBoot; 623 624 extraAttrs = { 625 inherit bootstrapTools; 626 shellPackage = prevStage.bash; 627 }; 628 629 disallowedRequisites = [ bootstrapTools.out ]; 630 631 # Mainly avoid reference to bootstrap tools 632 allowedRequisites = with prevStage; with lib; 633 # Simple executable tools 634 concatMap (p: [ (getBin p) (getLib p) ]) [ 635 gzip bzip2 xz bash binutils.bintools coreutils diffutils findutils 636 gawk gmp gnumake gnused gnutar gnugrep gnupatch patchelf ed file 637 ] 638 # Library dependencies 639 ++ map getLib ( 640 [ attr acl zlib gnugrep.pcre2 libidn2 libunistring ] 641 ++ lib.optional (gawk.libsigsegv != null) gawk.libsigsegv 642 ) 643 # More complicated cases 644 ++ (map (x: getOutput x (getLibc prevStage)) [ "out" "dev" "bin" ] ) 645 ++ [ linuxHeaders # propagated from .dev 646 binutils gcc gcc.cc gcc.cc.lib gcc.expand-response-params gcc.cc.libgcc glibc.passthru.libgcc 647 ] 648 ++ lib.optionals (!localSystem.isx86 || localSystem.libc == "musl") 649 [ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ] 650 ++ (with gcc-unwrapped.passthru; [ 651 gmp libmpc mpfr isl 652 ]) 653 ; 654 655 overrides = self: super: { 656 inherit (prevStage) 657 gzip bzip2 xz bash coreutils diffutils findutils gawk 658 gnused gnutar gnugrep gnupatch patchelf 659 attr acl zlib libunistring; 660 inherit (prevStage.gnugrep) pcre2; 661 ${localSystem.libc} = getLibc prevStage; 662 663 # Hack: avoid libidn2.{bin,dev} referencing bootstrap tools. There's a logical cycle. 664 libidn2 = import ../../development/libraries/libidn2/no-bootstrap-reference.nix { 665 inherit lib; 666 inherit (prevStage) libidn2; 667 inherit (self) stdenv runCommandLocal patchelf libunistring; 668 }; 669 670 gnumake = super.gnumake.override { inBootstrap = false; }; 671 } // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) { 672 # Need to get rid of these when cross-compiling. 673 inherit (prevStage) binutils binutils-unwrapped; 674 gcc = cc; 675 }; 676 }; 677 }) 678 679 # This "no-op" stage is just a place to put the assertions about stage5. 680 (prevStage: 681 # previous stage5 stdenv; see stage3 comment regarding gcc, 682 # which applies here as well. 683 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped; 684 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc}; 685 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped; 686 assert isBuiltByNixpkgsCompiler prevStage.coreutils; 687 assert isBuiltByNixpkgsCompiler prevStage.gnugrep; 688 assert isBuiltByNixpkgsCompiler prevStage.patchelf; 689 { inherit (prevStage) config overlays stdenv; }) 690]