···1717, isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null
1818, buildPackages ? {}
1919, libcxx ? null
2020+2121+# Whether or not to add `-B` and `-L` to `nix-support/cc-{c,ld}flags`
2222+, useCcForLibs ?
2323+2424+ # Always add these flags for Clang, because in order to compile (most
2525+ # software) it needs libraries that are shipped and compiled with gcc.
2626+ if isClang then true
2727+2828+ # Never add these flags for a build!=host cross-compiler or a host!=target
2929+ # ("cross-built-native") compiler; currently nixpkgs has a special build
3030+ # path for these (`crossStageStatic`). Hopefully at some point that build
3131+ # path will be merged with this one and this conditional will be removed.
3232+ else if (with stdenvNoCC; buildPlatform != hostPlatform || hostPlatform != targetPlatform) then false
3333+3434+ # Never add these flags when wrapping the bootstrapFiles' compiler; it has a
3535+ # /usr/-like layout with everything smashed into a single outpath, so it has
3636+ # no trouble finding its own libraries.
3737+ else if (cc.passthru.isFromBootstrapFiles or false) then false
3838+3939+ # Add these flags when wrapping `xgcc` (the first compiler that nixpkgs builds)
4040+ else if (cc.passthru.isXgcc or false) then true
4141+4242+ # Add these flags when wrapping `stdenv.cc`
4343+ else if (cc.stdenv.cc.cc.passthru.isXgcc or false) then true
4444+4545+ # Do not add these flags in any other situation. This is `false` mainly to
4646+ # prevent these flags from being added when wrapping *old* versions of gcc
4747+ # (e.g. `gcc6Stdenv`), since they will cause the old gcc to get `-B` and
4848+ # `-L` flags pointing at the new gcc's libstdc++ headers. Example failure:
4949+ # https://hydra.nixos.org/build/213125495
5050+ else false
5151+5252+# the derivation at which the `-B` and `-L` flags added by `useCcForLibs` will point
2053, gccForLibs ? if useCcForLibs then cc else null
2121-# same as `gccForLibs`, but generalized beyond clang
2222-, useCcForLibs ? isClang
2354}:
24552556with lib;
···321352 && targetPlatform.isLinux
322353 && !(stdenv.targetPlatform.useAndroidPrebuilt or false)
323354 && !(stdenv.targetPlatform.useLLVM or false)
324324- && gccForLibs != null) ''
355355+ && gccForLibs != null) (''
325356 echo "--gcc-toolchain=${gccForLibs}" >> $out/nix-support/cc-cflags
326357327358 # Pull in 'cc.out' target to get 'libstdc++fs.a'. It should be in
···329360 # TODO(trofi): remove once gcc is fixed to move libraries to .lib output.
330361 echo "-L${gccForLibs}/${optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}"}/lib" >> $out/nix-support/cc-ldflags
331362 ''
363363+ # this ensures that when clang passes -lgcc_s to lld (as it does
364364+ # when building e.g. firefox), lld is able to find libgcc_s.so
365365+ + lib.optionalString (gccForLibs?libgcc) ''
366366+ echo "-L${gccForLibs.libgcc}/lib" >> $out/nix-support/cc-ldflags
367367+ '')
332368333369 ##
334370 ## General libc support
+4-2
pkgs/build-support/emacs/wrapper.nix
···6767 # Store all paths we want to add to emacs here, so that we only need to add
6868 # one path to the load lists
6969 deps = runCommand "emacs-packages-deps"
7070- {
7070+ ({
7171 inherit explicitRequires lndir emacs;
7272 nativeBuildInputs = lib.optional nativeComp gcc;
7373- }
7373+ } // lib.optionalAttrs nativeComp {
7474+ inherit (emacs) LIBRARY_PATH;
7575+ })
7476 ''
7577 findInputsOld() {
7678 local pkg="$1"; shift
···11+{ lib
22+, stdenv
33+, nukeReferences
44+, langC
55+, langCC
66+, runtimeShell
77+}:
88+99+let
1010+ enableChecksum = (with stdenv; buildPlatform == hostPlatform && hostPlatform == targetPlatform) && langC && langCC;
1111+in
1212+(pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs enableChecksum {
1313+ outputs = previousAttrs.outputs ++ lib.optionals enableChecksum [ "checksum" ];
1414+ # This is a separate phase because gcc assembles its phase scripts
1515+ # in bash instead of nix (we should fix that).
1616+ preFixupPhases = (previousAttrs.preFixupPhases or []) ++ [ "postInstallSaveChecksumPhase" ];
1717+ #
1818+ # gcc uses an auxiliary utility `genchecksum` to md5-hash (most of) its
1919+ # `.o` and `.a` files prior to linking (in case the linker is
2020+ # nondeterministic). Since we want to compare across gccs built from two
2121+ # separate derivations, we wrap `genchecksum` with a `nuke-references`
2222+ # call. We also stash copies of the inputs to `genchecksum` in
2323+ # `$checksum/inputs/` -- this is extremely helpful for debugging since
2424+ # it's hard to get Nix to not delete the $NIX_BUILD_TOP of a successful
2525+ # build.
2626+ #
2727+ postInstallSaveChecksumPhase = ''
2828+ mv gcc/build/genchecksum gcc/build/.genchecksum-wrapped
2929+ cat > gcc/build/genchecksum <<\EOF
3030+ #!${runtimeShell}
3131+ ${nukeReferences}/bin/nuke-refs $@
3232+ for INPUT in "$@"; do install -Dt $INPUT $checksum/inputs/; done
3333+ exec build/.genchecksum-wrapped $@
3434+ EOF
3535+ chmod +x gcc/build/genchecksum
3636+ rm gcc/*-checksum.*
3737+ make -C gcc cc1-checksum.o cc1plus-checksum.o
3838+ install -Dt $checksum/checksums/ gcc/cc*-checksum.o
3939+ '';
4040+}))
+96
pkgs/development/compilers/gcc/common/libgcc.nix
···11+{ lib
22+, stdenv
33+, langC
44+, langCC
55+, langJit
66+}:
77+88+let
99+ enableLibGccOutput = (with stdenv; targetPlatform == hostPlatform) && !langJit;
1010+in
1111+(pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs ((!langC) || langJit || enableLibGccOutput) {
1212+ outputs = previousAttrs.outputs ++ lib.optionals enableLibGccOutput [ "libgcc" ];
1313+ # This is a separate phase because gcc assembles its phase scripts
1414+ # in bash instead of nix (we should fix that).
1515+ preFixupPhases = (previousAttrs.preFixupPhases or []) ++ [ "preFixupLibGccPhase" ];
1616+ preFixupLibGccPhase =
1717+ # delete extra/unused builds of libgcc_s in non-langC builds
1818+ # (i.e. libgccjit, gnat, etc) to avoid potential confusion
1919+ lib.optionalString (!langC) ''
2020+ rm -f $out/lib/libgcc_s.so*
2121+ ''
2222+2323+ # TODO(amjoseph): remove the `libgcc_s.so` symlinks below and replace them
2424+ # with a `-L${gccForLibs.libgcc}/lib` in cc-wrapper's
2525+ # `$out/nix-support/cc-flags`. See also:
2626+ # - https://github.com/NixOS/nixpkgs/pull/209870#discussion_r1130614895
2727+ # - https://github.com/NixOS/nixpkgs/pull/209870#discussion_r1130635982
2828+ # - https://github.com/NixOS/nixpkgs/commit/404155c6acfa59456aebe6156b22fe385e7dec6f
2929+ #
3030+ # move `libgcc_s.so` into its own output, `$libgcc`
3131+ + lib.optionalString enableLibGccOutput (''
3232+ # move libgcc from lib to its own output (libgcc)
3333+ mkdir -p $libgcc/lib
3434+ mv $lib/lib/libgcc_s.so $libgcc/lib/
3535+ mv $lib/lib/libgcc_s.so.1 $libgcc/lib/
3636+ ln -s $libgcc/lib/libgcc_s.so $lib/lib/
3737+ ln -s $libgcc/lib/libgcc_s.so.1 $lib/lib/
3838+ ''
3939+ #
4040+ # Nixpkgs ordinarily turns dynamic linking into pseudo-static linking:
4141+ # libraries are still loaded dynamically, exactly which copy of each
4242+ # library is loaded is permanently fixed at compile time (via RUNPATH).
4343+ # For libgcc_s we must revert to the "impure dynamic linking" style found
4444+ # in imperative software distributions. We must do this because
4545+ # `libgcc_s` calls `malloc()` and therefore has a `DT_NEEDED` for `libc`,
4646+ # which creates two problems:
4747+ #
4848+ # 1. A circular package dependency `glibc`<-`libgcc`<-`glibc`
4949+ #
5050+ # 2. According to the `-Wl,-rpath` flags added by Nixpkgs' `ld-wrapper`,
5151+ # the two versions of `glibc` in the cycle above are actually
5252+ # different packages. The later one is compiled by this `gcc`, but
5353+ # the earlier one was compiled by the compiler *that compiled* this
5454+ # `gcc` (usually the bootstrapFiles). In any event, the `glibc`
5555+ # dynamic loader won't honor that specificity without namespaced
5656+ # manual loads (`dlmopen()`). Once a `libc` is present in the address
5757+ # space of a process, that `libc` will be used to satisfy all
5858+ # `DT_NEEDED`s for `libc`, regardless of `RUNPATH`s.
5959+ #
6060+ # So we wipe the RUNPATH using `patchelf --set-rpath ""`. We can't use
6161+ # `patchelf --remove-rpath`, because at least as of patchelf 0.15.0 it
6262+ # will leave the old RUNPATH string in the file where the reference
6363+ # scanner can still find it:
6464+ #
6565+ # https://github.com/NixOS/patchelf/issues/453
6666+ #
6767+ # Note: we might be using the bootstrapFiles' copy of patchelf, so we have
6868+ # to keep doing it this way until both the issue is fixed *and* all the
6969+ # bootstrapFiles are regenerated, on every platform.
7070+ #
7171+ # This patchelfing is *not* effectively equivalent to copying
7272+ # `libgcc_s` into `glibc`'s outpath. There is one minor and one
7373+ # major difference:
7474+ #
7575+ # 1. (Minor): multiple builds of `glibc` (say, with different
7676+ # overrides or parameters) will all reference a single store
7777+ # path:
7878+ #
7979+ # /nix/store/xxx...xxx-gcc-libgcc/lib/libgcc_s.so.1
8080+ #
8181+ # This many-to-one referrer relationship will be visible in the store's
8282+ # dependency graph, and will be available to `nix-store -q` queries.
8383+ # Copying `libgcc_s` into each of its referrers would lose that
8484+ # information.
8585+ #
8686+ # 2. (Major): by referencing `libgcc_s.so.1`, rather than copying it, we
8787+ # are still able to run `nix-store -qd` on it to find out how it got
8888+ # built! Most importantly, we can see from that deriver which compiler
8989+ # was used to build it (or if it is part of the unpacked
9090+ # bootstrap-files). Copying `libgcc_s.so.1` from one outpath to
9191+ # another eliminates the ability to make these queries.
9292+ #
9393+ + ''
9494+ patchelf --set-rpath "" $libgcc/lib/libgcc_s.so.1
9595+ '');
9696+}))
+26-27
pkgs/development/libraries/glibc/default.nix
···6666 ]);
6767 };
68686969- # When building glibc from bootstrap-tools, we need libgcc_s at RPATH for
7070- # any program we run, because the gcc will have been placed at a new
7171- # store path than that determined when built (as a source for the
7272- # bootstrap-tools tarball)
7373- # Building from a proper gcc staying in the path where it was installed,
7474- # libgcc_s will now be at {gcc}/lib, and gcc's libgcc will be found without
7575- # any special hack.
7676- # TODO: remove this hack. Things that rely on this hack today:
7777- # - dejagnu: during linux bootstrap tcl SIGSEGVs
7878- # - clang-wrapper in cross-compilation
7979- # Last attempt: https://github.com/NixOS/nixpkgs/pull/36948
8080- preInstall = lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform) ''
8181- if [ -f ${lib.getLib stdenv.cc.cc}/lib/libgcc_s.so.1 ]; then
8282- mkdir -p $out/lib
8383- cp ${lib.getLib stdenv.cc.cc}/lib/libgcc_s.so.1 $out/lib/libgcc_s.so.1
8484- # the .so It used to be a symlink, but now it is a script
8585- cp -a ${lib.getLib stdenv.cc.cc}/lib/libgcc_s.so $out/lib/libgcc_s.so
8686- # wipe out reference to previous libc it was built against
8787- chmod +w $out/lib/libgcc_s.so.1
8888- # rely on default RUNPATHs of the binary and other libraries
8989- # Do no force-pull wrong glibc.
9090- patchelf --remove-rpath $out/lib/libgcc_s.so.1
9191- # 'patchelf' does not remove the string itself. Wipe out
9292- # string reference to avoid possible link to bootstrapTools
9393- ${buildPackages.nukeReferences}/bin/nuke-refs $out/lib/libgcc_s.so.1
9494- fi
9595- '';
6969+ # glibc needs to `dlopen()` `libgcc_s.so` but does not link
7070+ # against it. Furthermore, glibc doesn't use the ordinary
7171+ # `dlopen()` call to do this; instead it uses one which ignores
7272+ # most paths:
7373+ #
7474+ # https://sourceware.org/legacy-ml/libc-help/2013-11/msg00026.html
7575+ #
7676+ # In order to get it to not ignore `libgcc_s.so`, we have to add its path to
7777+ # `user-defined-trusted-dirs`:
7878+ #
7979+ # https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/Makefile;h=b509b3eada1fb77bf81e2a0ca5740b94ad185764#l1355
8080+ #
8181+ # Conveniently, this will also inform Nix of the fact that glibc depends on
8282+ # gcc.libgcc, since the path will be embedded in the resulting binary.
8383+ #
8484+ makeFlags =
8585+ (previousAttrs.makeFlags or [])
8686+ ++ lib.optionals (stdenv.cc.cc?libgcc) [
8787+ "user-defined-trusted-dirs=${stdenv.cc.cc.libgcc}/lib"
8888+ ];
96899790 postInstall = (if stdenv.hostPlatform == stdenv.buildPlatform then ''
9891 echo SUPPORTED-LOCALES=C.UTF-8/UTF-8 > ../glibc-2*/localedata/SUPPORTED
···163156 '';
164157165158 separateDebugInfo = true;
159159+160160+ passthru =
161161+ (previousAttrs.passthru or {})
162162+ // lib.optionalAttrs (stdenv.cc.cc?libgcc) {
163163+ inherit (stdenv.cc.cc) libgcc;
164164+ };
166165167166 meta = (previousAttrs.meta or {}) // { description = "The GNU C Library"; };
168167})
+2-1
pkgs/development/tools/misc/ccache/default.nix
···7474 # A derivation that provides gcc and g++ commands, but that
7575 # will end up calling ccache for the given cacheDir
7676 links = { unwrappedCC, extraConfig }: stdenv.mkDerivation {
7777- name = "ccache-links";
7777+ pname = "ccache-links";
7878+ inherit (finalAttrs) version;
7879 passthru = {
7980 isClang = unwrappedCC.isClang or false;
8081 isGNU = unwrappedCC.isGNU or false;
···3030# use a copy of patchelf.
3131LD_LIBRARY_PATH=$out/lib $LD_BINARY $out/bin/cp $out/bin/patchelf .
32323333+# Older versions of the bootstrap-files did not compile their
3434+# patchelf with -static-libgcc, so we have to be very careful not to
3535+# run patchelf on the same copy of libgcc_s that it links against.
3636+LD_LIBRARY_PATH=$out/lib $LD_BINARY $out/bin/cp $out/lib/libgcc_s.so.1 .
3737+LD_LIBRARY_PATH=.:$out/lib:$LIBSTDCXX_SO_DIR $LD_BINARY \
3838+ ./patchelf --set-rpath $out/lib --force-rpath $out/lib/libgcc_s.so.1
3939+3340for i in $out/bin/* $out/libexec/gcc/*/*/*; do
3441 if [ -L "$i" ]; then continue; fi
3542 if [ -z "${i##*/liblto*}" ]; then continue; fi
+137-63
pkgs/stdenv/linux/default.nix
···1010#
1111# Goals of the bootstrap process:
1212# 1. final stdenv must not reference any of the bootstrap files.
1313-# 2. final stdenv must not contain any of the bootstrap files
1414-# (the only current violation is libgcc_s.so in glibc).
1313+# 2. final stdenv must not contain any of the bootstrap files.
1514# 3. final stdenv must not contain any of the files directly
1615# generated by the bootstrap code generators (assembler, linker,
1717-# compiler). The only current violations are: libgcc_s.so in glibc,
1818-# the lib{mpfr,mpc,gmp,isl} which are statically linked
1919-# into the final gcc).
1616+# compiler).
2017#
2118# These goals ensure that final packages and final stdenv are built
2219# exclusively using nixpkgs package definitions and don't depend
···111108 isBuiltByBootstrapFilesCompiler =
112109 pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc;
113110111111+ commonGccOverrides = {
112112+ # Use a deterministically built compiler
113113+ # see https://github.com/NixOS/nixpkgs/issues/108475 for context
114114+ reproducibleBuild = true;
115115+ profiledCompiler = false;
116116+117117+ # It appears that libcc1 (which is not a g++ plugin; it is a gdb plugin) gets linked against
118118+ # the libstdc++ from the compiler that *built* g++, not the libstdc++ which was just built.
119119+ # This causes a reference chain from stdenv to the bootstrapFiles:
120120+ #
121121+ # stdenv -> gcc-lib -> xgcc-lib -> bootstrapFiles
122122+ #
123123+ disableGdbPlugin = true;
124124+ };
125125+114126 commonPreHook =
115127 ''
116128 export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
···170182171183 cc = if prevStage.gcc-unwrapped == null
172184 then null
173173- else lib.makeOverridable (import ../../build-support/cc-wrapper) {
185185+ else (lib.makeOverridable (import ../../build-support/cc-wrapper) {
174186 name = "${name}-gcc-wrapper";
175187 nativeTools = false;
176188 nativeLibc = false;
···184196 inherit lib;
185197 inherit (prevStage) coreutils gnugrep;
186198 stdenvNoCC = prevStage.ccWrapperStdenv;
187187- };
199199+ }).overrideAttrs(a: lib.optionalAttrs (prevStage.gcc-unwrapped.passthru.isXgcc or false) {
200200+ # This affects only `xgcc` (the compiler which compiles the final compiler).
201201+ postFixup = (a.postFixup or "") + ''
202202+ echo "--sysroot=${lib.getDev (getLibc prevStage)}" >> $out/nix-support/cc-cflags
203203+ '';
204204+ });
188205189206 overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; };
190207 };
···226243 ${localSystem.libc} = self.stdenv.mkDerivation {
227244 pname = "bootstrap-stage0-${localSystem.libc}";
228245 strictDeps = true;
229229- version = "bootstrap";
246246+ version = "bootstrapFiles";
230247 enableParallelBuilding = true;
231248 buildCommand = ''
232249 mkdir -p $out
···282299 };
283300 inherit (prevStage)
284301 ccWrapperStdenv
285285- gcc-unwrapped coreutils gnugrep;
302302+ gcc-unwrapped coreutils gnugrep binutils;
286303287304 ${localSystem.libc} = getLibc prevStage;
288305···295312 };
296313 })
297314315315+ # First rebuild of gcc; this is linked against all sorts of junk
316316+ # from the bootstrap-files, but we only care about the code that
317317+ # this compiler *emits*. The `gcc` binary produced in this stage
318318+ # is not part of the final stdenv.
319319+ (prevStage:
320320+ assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
321321+ assert isFromBootstrapFiles prevStage."${localSystem.libc}";
322322+ assert isFromBootstrapFiles prevStage.gcc-unwrapped;
323323+ assert isFromBootstrapFiles prevStage.coreutils;
324324+ assert isFromBootstrapFiles prevStage.gnugrep;
325325+ stageFun prevStage {
326326+ name = "bootstrap-stage-xgcc";
327327+ overrides = final: prev: {
328328+ inherit (prevStage) ccWrapperStdenv coreutils gnugrep gettext bison texinfo zlib gnum4 perl;
329329+ patchelf = bootstrapTools;
330330+ ${localSystem.libc} = getLibc prevStage;
331331+ gmp = prev.gmp.override { cxx = false; };
332332+ gcc-unwrapped =
333333+ (prev.gcc-unwrapped.override (commonGccOverrides // {
334334+ # The most logical name for this package would be something like
335335+ # "gcc-stage1". Unfortunately "stage" is already reserved for the
336336+ # layers of stdenv, so using "stage" in the name of this package
337337+ # would cause massive confusion.
338338+ #
339339+ # Gcc calls its "stage1" compiler `xgcc` (--disable-bootstrap results
340340+ # in `xgcc` being copied to $prefix/bin/gcc). So we imitate that.
341341+ #
342342+ name = "xgcc";
343343+344344+ })).overrideAttrs (a: {
345345+346346+ # This signals to cc-wrapper (as overridden above in this file) to add `--sysroot`
347347+ # to `$out/nix-support/cc-cflags`.
348348+ passthru = a.passthru // { isXgcc = true; };
349349+350350+ # Gcc will look for the C library headers in
351351+ #
352352+ # ${with_build_sysroot}${native_system_header_dir}
353353+ #
354354+ # The ordinary gcc expression sets `--with-build-sysroot=/` and sets
355355+ # `native-system-header-dir` to `"${lib.getDev stdenv.cc.libc}/include`.
356356+ #
357357+ # Unfortunately the value of "--with-native-system-header-dir=" gets "burned in" to the
358358+ # compiler, and it is quite difficult to get the compiler to change or ignore it
359359+ # afterwards. On the other hand, the `sysroot` is very easy to change; you can just pass
360360+ # a `--sysroot` flag to `gcc`.
361361+ #
362362+ # So we override the expression to remove the default settings for these flags, and
363363+ # replace them such that the concatenated value will be the same as before, but we split
364364+ # the value between the two variables differently: `--native-system-header-dir=/include`,
365365+ # and `--with-build-sysroot=${lib.getDev stdenv.cc.libc}`.
366366+ #
367367+ configureFlags = (a.configureFlags or []) ++ [
368368+ "--with-native-system-header-dir=/include"
369369+ "--with-build-sysroot=${lib.getDev final.stdenv.cc.libc}"
370370+ ];
371371+372372+ # This is a separate phase because gcc assembles its phase scripts
373373+ # in bash instead of nix (we should fix that).
374374+ preFixupPhases = (a.preFixupPhases or []) ++ [ "preFixupXgccPhase" ];
375375+376376+ # This is needed to prevent "error: cycle detected in build of '...-xgcc-....drv'
377377+ # in the references of output 'lib' from output 'out'"
378378+ preFixupXgccPhase = ''
379379+ find $lib/lib/ -name \*.so\* -exec patchelf --shrink-rpath {} \; || true
380380+ '';
381381+ });
382382+ };
383383+ })
298384299385 # 2nd stdenv that contains our own rebuilt binutils and is used for
300386 # compiling our own Glibc.
···303389 # previous stage1 stdenv:
304390 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
305391 assert isFromBootstrapFiles prevStage."${localSystem.libc}";
306306- assert isFromBootstrapFiles prevStage.gcc-unwrapped;
392392+ assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
307393 assert isFromBootstrapFiles prevStage.coreutils;
308394 assert isFromBootstrapFiles prevStage.gnugrep;
309395 stageFun prevStage {
···313399 inherit (prevStage)
314400 ccWrapperStdenv gettext
315401 gcc-unwrapped coreutils gnugrep
316316- perl gnum4 bison;
402402+ perl gnum4 bison texinfo which;
317403 dejagnu = super.dejagnu.overrideAttrs (a: { doCheck = false; } );
318404319405 # We need libidn2 and its dependency libunistring as glibc dependency.
···378464 # binutils and rest of the bootstrap tools, including GCC.
379465 (prevStage:
380466 # previous stage2 stdenv:
381381- assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
382382- assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
383383- assert isFromBootstrapFiles prevStage.gcc-unwrapped;
467467+ assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
468468+ assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
469469+ assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
384470 assert isFromBootstrapFiles prevStage.coreutils;
385471 assert isFromBootstrapFiles prevStage.gnugrep;
472472+ assert lib.all isBuiltByNixpkgsCompiler (with prevStage; [ gmp isl_0_20 libmpc mpfr ]);
386473 stageFun prevStage {
387474 name = "bootstrap-stage3";
388475···390477 inherit (prevStage)
391478 ccWrapperStdenv
392479 binutils coreutils gnugrep gettext
393393- perl patchelf linuxHeaders gnum4 bison libidn2 libunistring;
480480+ perl patchelf linuxHeaders gnum4 bison libidn2 libunistring libxcrypt;
481481+ # We build a special copy of libgmp which doesn't use libstdc++, because
482482+ # xgcc++'s libstdc++ references the bootstrap-files (which is what
483483+ # compiles xgcc++).
484484+ gmp = super.gmp.override { cxx = false; };
485485+ } // {
394486 ${localSystem.libc} = getLibc prevStage;
395395- gcc-unwrapped =
396396- let makeStaticLibrariesAndMark = pkg:
397397- lib.makeOverridable (pkg.override { stdenv = self.makeStaticLibraries self.stdenv; })
398398- .overrideAttrs (a: { pname = "${a.pname}-stage3"; });
399399- in super.gcc-unwrapped.override {
400400- # Link GCC statically against GMP etc. This makes sense because
401401- # these builds of the libraries are only used by GCC, so it
402402- # reduces the size of the stdenv closure.
403403- gmp = makeStaticLibrariesAndMark super.gmp;
404404- mpfr = makeStaticLibrariesAndMark super.mpfr;
405405- libmpc = makeStaticLibrariesAndMark super.libmpc;
406406- isl = makeStaticLibrariesAndMark super.isl_0_20;
407407- # Use a deterministically built compiler
408408- # see https://github.com/NixOS/nixpkgs/issues/108475 for context
409409- reproducibleBuild = true;
410410- profiledCompiler = false;
411411- };
487487+ gcc-unwrapped = (super.gcc-unwrapped.override (commonGccOverrides // {
488488+ inherit (prevStage) which;
489489+ }
490490+ )).overrideAttrs (a: {
491491+ # so we can add them to allowedRequisites below
492492+ passthru = a.passthru // { inherit (self) gmp mpfr libmpc isl; };
493493+ });
412494 };
413495 extraNativeBuildInputs = [ prevStage.patchelf ] ++
414496 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
···422504 #
423505 (prevStage:
424506 # previous stage3 stdenv:
425425- assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
426426- assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
427427- assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
428428- assert isFromBootstrapFiles prevStage.coreutils;
429429- assert isFromBootstrapFiles prevStage.gnugrep;
430430- # Can assume prevStage.gcc-unwrapped has almost no code from
431431- # bootstrapTools as gcc bootstraps internally. The only
432432- # exceptions are crt files from glibc built bybootstrapTools
433433- # used to link executables and libraries, and the
434434- # bootstrapTools-built, statically-linked
435435- # lib{mpfr,mpc,gmp,isl}.a which are linked into the final gcc
436436- # (see commit cfde88976ba4cddd01b1bb28b40afd12ea93a11d).
507507+ assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
508508+ assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
509509+ assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
510510+ assert isFromBootstrapFiles prevStage.coreutils;
511511+ assert isFromBootstrapFiles prevStage.gnugrep;
437512 stageFun prevStage {
438513 name = "bootstrap-stage4";
439514···452527 inherit (prevStage) stdenv;
453528 };
454529 };
455455-456456- # force gmp to rebuild so we have the option of dynamically linking
457457- # libgmp without creating a reference path from:
458458- # stage5.gcc -> stage4.coreutils -> stage3.glibc -> bootstrap
459459- gmp = lib.makeOverridable (super.gmp.override { stdenv = self.stdenv; }).overrideAttrs (a: { pname = "${a.pname}-stage4"; });
460530461531 # To allow users' overrides inhibit dependencies too heavy for
462532 # bootstrap, like guile: https://github.com/NixOS/nixpkgs/issues/181188
···494564 (prevStage:
495565 # previous stage4 stdenv; see stage3 comment regarding gcc,
496566 # which applies here as well.
497497- assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
498498- assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
499499- assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
500500- assert isBuiltByNixpkgsCompiler prevStage.coreutils;
501501- assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
567567+ assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
568568+ assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
569569+ assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
570570+ assert isBuiltByNixpkgsCompiler prevStage.coreutils;
571571+ assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
502572 {
503573 inherit config overlays;
504574 stdenv = import ../generic rec {
···546616 )
547617 # More complicated cases
548618 ++ (map (x: getOutput x (getLibc prevStage)) [ "out" "dev" "bin" ] )
549549- ++ [ /*propagated from .dev*/ linuxHeaders
550550- binutils gcc gcc.cc gcc.cc.lib gcc.expand-response-params
619619+ ++ [ linuxHeaders # propagated from .dev
620620+ binutils gcc gcc.cc gcc.cc.lib gcc.expand-response-params gcc.cc.libgcc glibc.passthru.libgcc
551621 ]
552552- ++ lib.optionals (!localSystem.isx86 || localSystem.libc == "musl")
553553- [ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ];
622622+ ++ lib.optionals (!localSystem.isx86 || localSystem.libc == "musl")
623623+ [ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ]
624624+ ++ (with gcc-unwrapped.passthru; [
625625+ gmp libmpc mpfr isl
626626+ ])
627627+ ;
554628555629 overrides = self: super: {
556630 inherit (prevStage)
···579653 (prevStage:
580654 # previous stage5 stdenv; see stage3 comment regarding gcc,
581655 # which applies here as well.
582582- assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
583583- assert isBuiltByBootstrapFilesCompiler prevStage.${localSystem.libc};
584584- assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
585585- assert isBuiltByNixpkgsCompiler prevStage.coreutils;
586586- assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
656656+ assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
657657+ assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
658658+ assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
659659+ assert isBuiltByNixpkgsCompiler prevStage.coreutils;
660660+ assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
587661 { inherit (prevStage) config overlays stdenv; })
588662]
···11+# This test *must* be run prior to releasing any build of either stdenv or the
22+# gcc that it exports! This check should also be part of CI for any PR that
33+# causes a rebuild of `stdenv.cc`.
44+#
55+# When we used gcc's internal bootstrap it did this check as part of (and
66+# serially with) the gcc derivation. Now that we bootstrap externally this
77+# check can be done in parallel with any/all of stdenv's referrers. But we
88+# must remember to do the check.
99+#
1010+1111+{ stdenv
1212+, pkgs
1313+, lib
1414+}:
1515+1616+assert stdenv.cc.isGNU;
1717+with pkgs;
1818+# rebuild gcc using the "final" stdenv
1919+let gcc-stageCompare = (gcc-unwrapped.override {
2020+ reproducibleBuild = true;
2121+ profiledCompiler = false;
2222+ stdenv = overrideCC stdenv (wrapCCWith {
2323+ cc = stdenv.cc;
2424+ });
2525+ }).overrideAttrs(_: {
2626+ NIX_OUTPATH_USED_AS_RANDOM_SEED = stdenv.cc.cc.out;
2727+ });
2828+in (runCommand "gcc-stageCompare" {} ''
2929+ diff -sr ${pkgs.gcc-unwrapped.checksum}/checksums ${gcc-stageCompare.checksum}/checksums && touch $out
3030+'').overrideAttrs (a: {
3131+ meta = (a.meta or { }) // { platforms = lib.platforms.linux; };
3232+})