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