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.
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).
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,
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).
23 # Stages are described below along with their definitions.
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:
29 # - stdenv.__bootPackages.stdenv
30 # - stdenv.__bootPackages.stdenv.__bootPackages.stdenv
33 # To explore build-time dependencies in graphical form one can use
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
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'
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";
53 # For a TUI (rather than CLI) view, you can use:
55 # $ nix-tree --derivation $(nix-instantiate -A stdenv)
57 , localSystem, crossSystem, config, overlays, crossOverlays ? []
62 i686-linux = import ./bootstrap-files/i686-unknown-linux-gnu.nix;
63 x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-gnu.nix;
64 armv5tel-linux = import ./bootstrap-files/armv5tel-unknown-linux-gnueabi.nix;
65 armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-gnueabihf.nix;
66 armv7l-linux = import ./bootstrap-files/armv7l-unknown-linux-gnueabihf.nix;
67 aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-gnu.nix;
68 mipsel-linux = import ./bootstrap-files/mipsel-unknown-linux-gnu.nix;
69 mips64el-linux = import
70 (if localSystem.isMips64n32
71 then ./bootstrap-files/mips64el-unknown-linux-gnuabin32.nix
72 else ./bootstrap-files/mips64el-unknown-linux-gnuabi64.nix);
73 powerpc64-linux = import ./bootstrap-files/powerpc64-unknown-linux-gnuabielfv2.nix;
74 powerpc64le-linux = import ./bootstrap-files/powerpc64le-unknown-linux-gnu.nix;
75 riscv64-linux = import ./bootstrap-files/riscv64-unknown-linux-gnu.nix;
76 s390x-linux = import ./bootstrap-files/s390x-unknown-linux-gnu.nix;
79 aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-musl.nix;
80 armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-musleabihf.nix;
81 x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-musl.nix;
85 # Try to find an architecture compatible with our current system. We
86 # just try every bootstrap we’ve got and test to see if it is
87 # compatible with or current architecture.
88 getCompatibleTools = lib.foldl (v: system:
90 else if localSystem.canExecute (lib.systems.elaborate { inherit system; }) then archLookupTable.${system}
91 else null) null (lib.attrNames archLookupTable);
93 archLookupTable = table.${localSystem.libc}
94 or (throw "unsupported libc for the pure Linux stdenv");
95 files = archLookupTable.${localSystem.system} or (if getCompatibleTools != null then getCompatibleTools
96 else (throw "unsupported platform for the pure Linux stdenv"));
97 in (config.replaceBootstrapFiles or lib.id) files
100 assert crossSystem == localSystem;
103 inherit (localSystem) system;
105 isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg);
106 isFromBootstrapFiles =
107 pkg: pkg.passthru.isFromBootstrapFiles or false;
108 isBuiltByNixpkgsCompiler =
109 pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc;
110 isBuiltByBootstrapFilesCompiler =
111 pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc;
113 commonGccOverrides = {
114 # Use a deterministically built compiler
115 # see https://github.com/NixOS/nixpkgs/issues/108475 for context
116 reproducibleBuild = true;
117 profiledCompiler = false;
119 # It appears that libcc1 (which is not a g++ plugin; it is a gdb plugin) gets linked against
120 # the libstdc++ from the compiler that *built* g++, not the libstdc++ which was just built.
121 # This causes a reference chain from stdenv to the bootstrapFiles:
123 # stdenv -> gcc-lib -> xgcc-lib -> bootstrapFiles
125 disableGdbPlugin = true;
130 export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
131 export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
135 # The bootstrap process proceeds in several steps.
138 # Create a standard environment by downloading pre-built binaries of
139 # coreutils, GCC, etc.
142 # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...).
143 bootstrapTools = import ./bootstrap-tools {
144 inherit (localSystem) libc system;
145 inherit lib bootstrapFiles config;
146 isFromBootstrapFiles = true;
149 getLibc = stage: stage.${localSystem.libc};
152 # This function builds the various standard environments used during
153 # the bootstrap. In all stages, we build an stdenv and the package
154 # set that can be built with that stdenv.
155 stageFun = prevStage:
156 { name, overrides ? (self: super: {}), extraNativeBuildInputs ? [] }:
160 thisStdenv = import ../generic {
161 name = "${name}-stdenv-linux";
162 buildPlatform = localSystem;
163 hostPlatform = localSystem;
164 targetPlatform = localSystem;
165 inherit config extraNativeBuildInputs;
168 # Don't patch #!/interpreter because it leads to retained
169 # dependencies on the bootstrapTools in the final stdenv.
173 shell = "${bootstrapTools}/bin/bash";
174 initialPath = [bootstrapTools];
176 fetchurlBoot = import ../../build-support/fetchurl/boot.nix {
180 cc = if prevStage.gcc-unwrapped == null
182 else (lib.makeOverridable (import ../../build-support/cc-wrapper) {
183 name = "${name}-gcc-wrapper";
186 expand-response-params = lib.optionalString
187 (prevStage.stdenv.hasCC or false && prevStage.stdenv.cc != "/dev/null")
188 prevStage.expand-response-params;
189 cc = prevStage.gcc-unwrapped;
190 bintools = prevStage.binutils;
192 libc = getLibc prevStage;
194 inherit (prevStage) coreutils gnugrep;
195 stdenvNoCC = prevStage.ccWrapperStdenv;
196 fortify-headers = prevStage.fortify-headers;
197 runtimeShell = prevStage.ccWrapperStdenv.shell;
198 }).overrideAttrs(a: lib.optionalAttrs (prevStage.gcc-unwrapped.passthru.isXgcc or false) {
199 # This affects only `xgcc` (the compiler which compiles the final compiler).
200 postFixup = (a.postFixup or "") + ''
201 echo "--sysroot=${lib.getDev (getLibc prevStage)}" >> $out/nix-support/cc-cflags
205 overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; };
209 inherit config overlays;
214 assert bootstrapTools.passthru.isFromBootstrapFiles or false; # sanity check
220 gcc-unwrapped = null;
226 # Build a dummy stdenv with no GCC or working fetchurl. This is
227 # because we need a stdenv to build the GCC wrapper and fetchurl.
228 (prevStage: stageFun prevStage {
229 name = "bootstrap-stage0";
231 overrides = self: super: {
232 # We thread stage0's stdenv through under this name so downstream stages
233 # can use it for wrapping gcc too. This way, downstream stages don't need
234 # to refer to this stage directly, which violates the principle that each
235 # stage should only access the stage that came before it.
236 ccWrapperStdenv = self.stdenv;
237 # The Glibc include directory cannot have the same prefix as the
238 # GCC include directory, since GCC gets confused otherwise (it
239 # will search the Glibc headers before the GCC headers). So
240 # create a dummy Glibc here, which will be used in the stdenv of
242 ${localSystem.libc} = self.stdenv.mkDerivation {
243 pname = "bootstrap-stage0-${localSystem.libc}";
245 version = "bootstrapFiles";
246 enableParallelBuilding = true;
249 ln -s ${bootstrapTools}/lib $out/lib
250 '' + lib.optionalString (localSystem.libc == "glibc") ''
251 ln -s ${bootstrapTools}/include-glibc $out/include
252 '' + lib.optionalString (localSystem.libc == "musl") ''
253 ln -s ${bootstrapTools}/include-libc $out/include
255 passthru.isFromBootstrapFiles = true;
257 gcc-unwrapped = bootstrapTools;
258 binutils = import ../../build-support/bintools-wrapper {
259 name = "bootstrap-stage0-binutils-wrapper";
262 expand-response-params = "";
265 inherit (self) stdenvNoCC coreutils gnugrep;
266 bintools = bootstrapTools;
267 runtimeShell = "${bootstrapTools}/bin/bash";
269 coreutils = bootstrapTools;
270 gnugrep = bootstrapTools;
275 # Create the first "real" standard environment. This one consists
276 # of bootstrap tools only, and a minimal Glibc to keep the GCC
277 # configure script happy.
279 # For clarity, we only use the previous stage when specifying these
280 # stages. So stageN should only ever have references for stage{N-1}.
282 # If we ever need to use a package from more than one stage back, we
283 # simply re-export those packages in the middle stage(s) using the
284 # overrides attribute and the inherit syntax.
286 # previous stage0 stdenv:
287 assert isFromBootstrapFiles prevStage.binutils.bintools;
288 assert isFromBootstrapFiles prevStage."${localSystem.libc}";
289 assert isFromBootstrapFiles prevStage.gcc-unwrapped;
290 assert isFromBootstrapFiles prevStage.coreutils;
291 assert isFromBootstrapFiles prevStage.gnugrep;
293 name = "bootstrap-stage1";
295 # Rebuild binutils to use from stage2 onwards.
296 overrides = self: super: {
297 binutils-unwrapped = super.binutils-unwrapped.override {
302 gcc-unwrapped coreutils gnugrep binutils;
304 ${localSystem.libc} = getLibc prevStage;
306 # A threaded perl build needs glibc/libpthread_nonshared.a,
307 # which is not included in bootstrapTools, so disable threading.
308 # This is not an issue for the final stdenv, because this perl
309 # won't be included in the final stdenv and won't be exported to
310 # top-level pkgs as an override either.
311 perl = super.perl.override { enableThreading = false; enableCrypt = false; };
314 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
315 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
318 # First rebuild of gcc; this is linked against all sorts of junk
319 # from the bootstrap-files, but we only care about the code that
320 # this compiler *emits*. The `gcc` binary produced in this stage
321 # is not part of the final stdenv.
323 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
324 assert isFromBootstrapFiles prevStage."${localSystem.libc}";
325 assert isFromBootstrapFiles prevStage.gcc-unwrapped;
326 assert isFromBootstrapFiles prevStage.coreutils;
327 assert isFromBootstrapFiles prevStage.gnugrep;
328 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
330 name = "bootstrap-stage-xgcc";
331 overrides = self: super: {
332 inherit (prevStage) ccWrapperStdenv coreutils gnugrep gettext bison texinfo zlib gnum4 perl patchelf;
333 ${localSystem.libc} = getLibc prevStage;
334 gmp = super.gmp.override { cxx = false; };
335 # This stage also rebuilds binutils which will of course be used only in the next stage.
336 # We inherit this until stage3, in stage4 it will be rebuilt using the adjacent bash/runtimeShell pkg.
337 # TODO(@sternenseemann): Can we already build the wrapper with the actual runtimeShell here?
338 # Historically, the wrapper didn't use runtimeShell, so the used shell had to be changed explicitly
339 # (or stdenvNoCC.shell would be used) which happened in stage4.
340 binutils = super.binutils.override {
341 runtimeShell = "${bootstrapTools}/bin/bash";
344 (super.gcc-unwrapped.override (commonGccOverrides // {
345 # The most logical name for this package would be something like
346 # "gcc-stage1". Unfortunately "stage" is already reserved for the
347 # layers of stdenv, so using "stage" in the name of this package
348 # would cause massive confusion.
350 # Gcc calls its "stage1" compiler `xgcc` (--disable-bootstrap results
351 # in `xgcc` being copied to $prefix/bin/gcc). So we imitate that.
355 # xgcc uses ld linked against nixpkgs' glibc and gcc built
356 # against bootstrapTools glibc. We can't allow loading
357 # $out/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so
359 # ...-binutils-patchelfed-ld-2.40/bin/ld: ...-xgcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so:
360 # error loading plugin: ...-bootstrap-tools/lib/libpthread.so.0: undefined symbol: __libc_vfork, version GLIBC_PRIVATE
362 })).overrideAttrs (a: {
364 # This signals to cc-wrapper (as overridden above in this file) to add `--sysroot`
365 # to `$out/nix-support/cc-cflags`.
366 passthru = a.passthru // { isXgcc = true; };
368 # Gcc will look for the C library headers in
370 # ${with_build_sysroot}${native_system_header_dir}
372 # The ordinary gcc expression sets `--with-build-sysroot=/` and sets
373 # `native-system-header-dir` to `"${lib.getDev stdenv.cc.libc}/include`.
375 # Unfortunately the value of "--with-native-system-header-dir=" gets "burned in" to the
376 # compiler, and it is quite difficult to get the compiler to change or ignore it
377 # afterwards. On the other hand, the `sysroot` is very easy to change; you can just pass
378 # a `--sysroot` flag to `gcc`.
380 # So we override the expression to remove the default settings for these flags, and
381 # replace them such that the concatenated value will be the same as before, but we split
382 # the value between the two variables differently: `--native-system-header-dir=/include`,
383 # and `--with-build-sysroot=${lib.getDev stdenv.cc.libc}`.
385 configureFlags = (a.configureFlags or []) ++ [
386 "--with-native-system-header-dir=/include"
387 "--with-build-sysroot=${lib.getDev self.stdenv.cc.libc}"
390 # This is a separate phase because gcc assembles its phase scripts
391 # in bash instead of nix (we should fix that).
392 preFixupPhases = (a.preFixupPhases or []) ++ [ "preFixupXgccPhase" ];
394 # This is needed to prevent "error: cycle detected in build of '...-xgcc-....drv'
395 # in the references of output 'lib' from output 'out'"
396 preFixupXgccPhase = ''
397 find $lib/lib/ -name \*.so\* -exec patchelf --shrink-rpath {} \; || true
402 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
403 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
406 # 2nd stdenv that contains our own rebuilt binutils and is used for
407 # compiling our own Glibc.
410 # previous stage1 stdenv:
411 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
412 assert isFromBootstrapFiles prevStage."${localSystem.libc}";
413 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
414 assert isFromBootstrapFiles prevStage.coreutils;
415 assert isFromBootstrapFiles prevStage.gnugrep;
416 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
418 name = "bootstrap-stage2";
420 overrides = self: super: {
422 ccWrapperStdenv gettext
423 gcc-unwrapped coreutils gnugrep
424 perl gnum4 bison texinfo which;
425 dejagnu = super.dejagnu.overrideAttrs (a: { doCheck = false; } );
427 # We need libidn2 and its dependency libunistring as glibc dependency.
428 # To avoid the cycle, we build against bootstrap libc, nuke references,
429 # and use the result as input for our final glibc. We also pass this pair
430 # through, so the final package-set uses exactly the same builds.
431 libunistring = super.libunistring.overrideAttrs (attrs: {
432 postFixup = attrs.postFixup or "" + ''
433 ${self.nukeReferences}/bin/nuke-refs "$out"/lib/lib*.so.*.*
435 # Apparently iconv won't work with bootstrap glibc, but it will be used
436 # with glibc built later where we keep *this* build of libunistring,
437 # so we need to trick it into supporting libiconv.
438 env = attrs.env or {} // { am_cv_func_iconv_works = "yes"; };
440 libidn2 = super.libidn2.overrideAttrs (attrs: {
441 postFixup = attrs.postFixup or "" + ''
442 ${self.nukeReferences}/bin/nuke-refs -e '${lib.getLib self.libunistring}' \
443 "$out"/lib/lib*.so.*.*
447 # This also contains the full, dynamically linked, final Glibc.
448 binutils = prevStage.binutils.override {
449 # Rewrap the binutils with the new glibc, so both the next
450 # stage's wrappers use it.
453 # Unfortunately, when building gcc in the next stage, its LTO plugin
454 # would use the final libc but `ld` would use the bootstrap one,
455 # and that can fail to load. Therefore we upgrade `ld` to use newer libc;
456 # apparently the interpreter needs to match libc, too.
457 bintools = self.stdenvNoCC.mkDerivation {
458 pname = prevStage.bintools.bintools.pname + "-patchelfed-ld";
459 inherit (prevStage.bintools.bintools) version;
460 passthru = { inherit (prevStage.bintools.passthru) isFromBootstrapFiles; };
461 enableParallelBuilding = true;
465 # We wouldn't need to *copy* all, but it's easier and the result is temporary anyway.
468 cp -a '${prevStage.bintools.bintools}'/bin/* "$out"/bin/
469 chmod +w "$out"/bin/ld.bfd
470 patchelf --set-interpreter '${getLibc self}'/lib/ld*.so.? \
471 --set-rpath "${getLibc self}/lib:$(patchelf --print-rpath "$out"/bin/ld.bfd)" \
477 # TODO(amjoseph): It is not yet entirely clear why this is necessary.
478 # Something strange is going on with xgcc and libstdc++ on pkgsMusl.
479 patchelf = super.patchelf.overrideAttrs(previousAttrs:
480 lib.optionalAttrs super.stdenv.hostPlatform.isMusl {
481 NIX_CFLAGS_COMPILE = (previousAttrs.NIX_CFLAGS_COMPILE or "") + " -static-libstdc++";
486 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
487 # `libtool` comes with obsolete config.sub/config.guess that don't recognize Risc-V.
488 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
492 # Construct a third stdenv identical to the 2nd, except that this
493 # one uses the rebuilt Glibc from stage2. It still uses the recent
494 # binutils and rest of the bootstrap tools, including GCC.
496 # previous stage2 stdenv:
497 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
498 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
499 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
500 assert isFromBootstrapFiles prevStage.coreutils;
501 assert isFromBootstrapFiles prevStage.gnugrep;
502 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
503 assert lib.all isBuiltByNixpkgsCompiler [ prevStage.gmp prevStage.isl_0_20 prevStage.libmpc prevStage.mpfr ];
505 name = "bootstrap-stage3";
507 overrides = self: super: rec {
510 binutils coreutils gnugrep gettext
511 perl patchelf linuxHeaders gnum4 bison libidn2 libunistring libxcrypt;
512 # We build a special copy of libgmp which doesn't use libstdc++, because
513 # xgcc++'s libstdc++ references the bootstrap-files (which is what
515 gmp = super.gmp.override { cxx = false; };
517 ${localSystem.libc} = getLibc prevStage;
518 gcc-unwrapped = (super.gcc-unwrapped.override (commonGccOverrides // {
519 inherit (prevStage) which;
521 )).overrideAttrs (a: {
522 # so we can add them to allowedRequisites below
523 passthru = a.passthru // { inherit (self) gmp mpfr libmpc isl; };
526 extraNativeBuildInputs = [
528 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
529 prevStage.updateAutotoolsGnuConfigScriptsHook
534 # Construct a fourth stdenv that uses the new GCC. But coreutils is
535 # still from the bootstrap tools.
538 # previous stage3 stdenv:
539 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
540 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
541 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
542 assert isFromBootstrapFiles prevStage.coreutils;
543 assert isFromBootstrapFiles prevStage.gnugrep;
544 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
546 name = "bootstrap-stage4";
548 overrides = self: super: {
549 # Zlib has to be inherited and not rebuilt in this stage,
550 # because gcc (since JAR support) already depends on zlib, and
551 # then if we already have a zlib we want to use that for the
552 # other purposes (binutils and top-level pkgs) too.
553 inherit (prevStage) gettext gnum4 bison perl texinfo zlib linuxHeaders libidn2 libunistring;
554 ${localSystem.libc} = getLibc prevStage;
555 # Since this is the first fresh build of binutils since stage2, our own runtimeShell will be used.
556 binutils = super.binutils.override {
557 # Build expand-response-params with last stage like below
558 inherit (prevStage) expand-response-params;
561 # To allow users' overrides inhibit dependencies too heavy for
562 # bootstrap, like guile: https://github.com/NixOS/nixpkgs/issues/181188
563 gnumake = super.gnumake.override { inBootstrap = true; };
565 gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
569 inherit (prevStage) expand-response-params;
570 cc = prevStage.gcc-unwrapped;
571 bintools = self.binutils;
574 inherit (self) stdenvNoCC coreutils gnugrep runtimeShell;
575 fortify-headers = self.fortify-headers;
578 extraNativeBuildInputs = [
579 prevStage.patchelf prevStage.xz
580 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
581 prevStage.updateAutotoolsGnuConfigScriptsHook
585 # Construct the final stdenv. It uses the Glibc and GCC, and adds
586 # in a new binutils that doesn't depend on bootstrap-tools, as well
587 # as dynamically linked versions of all other tools.
589 # When updating stdenvLinux, make sure that the result has no
590 # dependency (`nix-store -qR') on bootstrapTools or the first
594 # previous stage4 stdenv; see stage3 comment regarding gcc,
595 # which applies here as well.
596 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
597 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
598 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
599 assert isBuiltByNixpkgsCompiler prevStage.coreutils;
600 assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
601 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
603 inherit config overlays;
604 stdenv = import ../generic rec {
605 name = "stdenv-linux";
607 buildPlatform = localSystem;
608 hostPlatform = localSystem;
609 targetPlatform = localSystem;
612 preHook = commonPreHook;
615 ((import ../generic/common-path.nix) {pkgs = prevStage;});
617 extraNativeBuildInputs = [
619 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
620 prevStage.updateAutotoolsGnuConfigScriptsHook
627 inherit (prevStage.stdenv) fetchurlBoot;
630 inherit bootstrapTools;
631 shellPackage = prevStage.bash;
634 disallowedRequisites = [ bootstrapTools.out ];
636 # Mainly avoid reference to bootstrap tools
637 allowedRequisites = let
638 inherit (prevStage) gzip bzip2 xz zlib bash binutils coreutils diffutils findutils
639 gawk gmp gnumake gnused gnutar gnugrep gnupatch patchelf ed file glibc
640 attr acl libidn2 libunistring linuxHeaders gcc fortify-headers gcc-unwrapped
643 # Simple executable tools
644 lib.concatMap (p: [ (lib.getBin p) (lib.getLib p) ]) [
645 gzip bzip2 xz bash binutils.bintools coreutils diffutils findutils
646 gawk gmp gnumake gnused gnutar gnugrep gnupatch patchelf ed file
648 # Library dependencies
649 ++ map lib.getLib [ attr acl zlib gnugrep.pcre2 libidn2 libunistring ]
650 # More complicated cases
651 ++ (map (x: lib.getOutput x (getLibc prevStage)) [ "out" "dev" "bin" ] )
652 ++ [ linuxHeaders # propagated from .dev
653 binutils gcc gcc.cc gcc.cc.lib
654 gcc.expand-response-params # != (prevStage.)expand-response-params
655 gcc.cc.libgcc glibc.passthru.libgcc
657 ++ lib.optionals (localSystem.libc == "musl") [ fortify-headers ]
658 ++ [ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ]
660 gcc-unwrapped.gmp gcc-unwrapped.libmpc gcc-unwrapped.mpfr gcc-unwrapped.isl
664 overrides = self: super: {
666 gzip bzip2 xz bash coreutils diffutils findutils gawk
667 gnused gnutar gnugrep gnupatch patchelf
668 attr acl zlib libunistring;
669 inherit (prevStage.gnugrep) pcre2;
670 ${localSystem.libc} = getLibc prevStage;
672 # Hack: avoid libidn2.{bin,dev} referencing bootstrap tools. There's a logical cycle.
673 libidn2 = import ../../development/libraries/libidn2/no-bootstrap-reference.nix {
675 inherit (prevStage) libidn2;
676 inherit (self) stdenv runCommandLocal patchelf libunistring;
679 gnumake = super.gnumake.override { inBootstrap = false; };
680 } // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
681 # Need to get rid of these when cross-compiling.
682 inherit (prevStage) binutils binutils-unwrapped;
688 # This "no-op" stage is just a place to put the assertions about stage5.
690 # previous stage5 stdenv; see stage3 comment regarding gcc,
691 # which applies here as well.
692 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
693 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
694 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
695 assert isBuiltByNixpkgsCompiler prevStage.coreutils;
696 assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
697 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
698 { inherit (prevStage) config overlays stdenv; })