-
-
Notifications
You must be signed in to change notification settings - Fork 18k
stdenv: Nix-driven bootstrap of gcc #209870
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
3b49fb2
trivial-builders/test/references.nix: fix eval
4102714
test-defaultPkgConfigPackages.nix: filter out recurseForDerivations
39c7885
cc-wrapper: if isClang, add -L${gccForLibs.libgcc}/lib
87225ff
ccache-links: inherit version to keep cc-wrapper happy
70d3458
stdenv/linux: factor out commonGccOverrides
fdd49f1
gcc/{11,12}: use lib.pipe
7553d0f
stdenv: Nix-driven bootstrap of gcc
c6bd37a
make-bootstrap-tools.nix: ship libisl.so
86ca0fa
make-bootstrap-tools.nix: cp libgcc_s without -d
d7fe0a5
make-bootstrap-tools.nix: use a patchelf built with -static-{libgcc,l…
fed2300
unpack-bootstrap-tools.sh: patchelf libgcc_s.so.1
96588eb
gcc: add common/checksum.nix
5f57c2e
pkgs/test/stdenv/default.nix: add gcc-stageCompare
6c209e8
emacs: path fixes resulting from libgccjit changes
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,9 +17,40 @@ | |
| , isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null | ||
| , buildPackages ? {} | ||
| , libcxx ? null | ||
|
|
||
| # Whether or not to add `-B` and `-L` to `nix-support/cc-{c,ld}flags` | ||
| , useCcForLibs ? | ||
|
|
||
| # Always add these flags for Clang, because in order to compile (most | ||
| # software) it needs libraries that are shipped and compiled with gcc. | ||
| if isClang then true | ||
|
|
||
| # Never add these flags for a build!=host cross-compiler or a host!=target | ||
| # ("cross-built-native") compiler; currently nixpkgs has a special build | ||
| # path for these (`crossStageStatic`). Hopefully at some point that build | ||
| # path will be merged with this one and this conditional will be removed. | ||
| else if (with stdenvNoCC; buildPlatform != hostPlatform || hostPlatform != targetPlatform) then false | ||
|
|
||
| # Never add these flags when wrapping the bootstrapFiles' compiler; it has a | ||
| # /usr/-like layout with everything smashed into a single outpath, so it has | ||
| # no trouble finding its own libraries. | ||
| else if (cc.passthru.isFromBootstrapFiles or false) then false | ||
|
|
||
| # Add these flags when wrapping `xgcc` (the first compiler that nixpkgs builds) | ||
| else if (cc.passthru.isXgcc or false) then true | ||
|
|
||
| # Add these flags when wrapping `stdenv.cc` | ||
| else if (cc.stdenv.cc.cc.passthru.isXgcc or false) then true | ||
|
|
||
| # Do not add these flags in any other situation. This is `false` mainly to | ||
| # prevent these flags from being added when wrapping *old* versions of gcc | ||
| # (e.g. `gcc6Stdenv`), since they will cause the old gcc to get `-B` and | ||
| # `-L` flags pointing at the new gcc's libstdc++ headers. Example failure: | ||
| # https://hydra.nixos.org/build/213125495 | ||
| else false | ||
|
|
||
| # the derivation at which the `-B` and `-L` flags added by `useCcForLibs` will point | ||
| , gccForLibs ? if useCcForLibs then cc else null | ||
| # same as `gccForLibs`, but generalized beyond clang | ||
| , useCcForLibs ? isClang | ||
| }: | ||
|
|
||
| with lib; | ||
|
|
@@ -319,14 +350,19 @@ stdenv.mkDerivation { | |
| && targetPlatform.isLinux | ||
| && !(stdenv.targetPlatform.useAndroidPrebuilt or false) | ||
| && !(stdenv.targetPlatform.useLLVM or false) | ||
| && gccForLibs != null) '' | ||
| && gccForLibs != null) ('' | ||
| echo "--gcc-toolchain=${gccForLibs}" >> $out/nix-support/cc-cflags | ||
|
|
||
| # Pull in 'cc.out' target to get 'libstdc++fs.a'. It should be in | ||
| # 'cc.lib'. But it's a gcc package bug. | ||
| # TODO(trofi): remove once gcc is fixed to move libraries to .lib output. | ||
| echo "-L${gccForLibs}/${optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}"}/lib" >> $out/nix-support/cc-ldflags | ||
| '' | ||
| # this ensures that when clang passes -lgcc_s to lld (as it does | ||
| # when building e.g. firefox), lld is able to find libgcc_s.so | ||
This conversation was marked as resolved.
Outdated
Show resolved
Hide resolved
|
||
| + lib.optionalString (gccForLibs?libgcc) '' | ||
| echo "-L${gccForLibs.libgcc}/lib" >> $out/nix-support/cc-ldflags | ||
| '') | ||
|
||
|
|
||
| ## | ||
| ## General libc support | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| { lib | ||
| , stdenv | ||
| , nukeReferences | ||
| , langC | ||
| , langCC | ||
| , runtimeShell | ||
| }: | ||
|
|
||
| let | ||
| enableChecksum = (with stdenv; buildPlatform == hostPlatform && hostPlatform == targetPlatform) && langC && langCC; | ||
| in | ||
| (pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs enableChecksum { | ||
| outputs = previousAttrs.outputs ++ lib.optionals enableChecksum [ "checksum" ]; | ||
| # This is a separate phase because gcc assembles its phase scripts | ||
| # in bash instead of nix (we should fix that). | ||
| preFixupPhases = (previousAttrs.preFixupPhases or []) ++ [ "postInstallSaveChecksumPhase" ]; | ||
| # | ||
| # gcc uses an auxiliary utility `genchecksum` to md5-hash (most of) its | ||
| # `.o` and `.a` files prior to linking (in case the linker is | ||
| # nondeterministic). Since we want to compare across gccs built from two | ||
| # separate derivations, we wrap `genchecksum` with a `nuke-references` | ||
| # call. We also stash copies of the inputs to `genchecksum` in | ||
| # `$checksum/inputs/` -- this is extremely helpful for debugging since | ||
| # it's hard to get Nix to not delete the $NIX_BUILD_TOP of a successful | ||
| # build. | ||
| # | ||
| postInstallSaveChecksumPhase = '' | ||
| mv gcc/build/genchecksum gcc/build/.genchecksum-wrapped | ||
| cat > gcc/build/genchecksum <<\EOF | ||
| #!${runtimeShell} | ||
| ${nukeReferences}/bin/nuke-refs $@ | ||
| for INPUT in "$@"; do install -Dt $INPUT $checksum/inputs/; done | ||
| exec build/.genchecksum-wrapped $@ | ||
| EOF | ||
| chmod +x gcc/build/genchecksum | ||
| rm gcc/*-checksum.* | ||
| make -C gcc cc1-checksum.o cc1plus-checksum.o | ||
| install -Dt $checksum/checksums/ gcc/cc*-checksum.o | ||
| ''; | ||
| })) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| { lib | ||
| , stdenv | ||
| , langC | ||
| , langCC | ||
| , langJit | ||
| }: | ||
|
|
||
| let | ||
| enableLibGccOutput = (with stdenv; targetPlatform == hostPlatform) && !langJit; | ||
| in | ||
| (pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs ((!langC) || langJit || enableLibGccOutput) { | ||
| outputs = previousAttrs.outputs ++ lib.optionals enableLibGccOutput [ "libgcc" ]; | ||
| # This is a separate phase because gcc assembles its phase scripts | ||
| # in bash instead of nix (we should fix that). | ||
| preFixupPhases = (previousAttrs.preFixupPhases or []) ++ [ "preFixupLibGccPhase" ]; | ||
| preFixupLibGccPhase = | ||
| # delete extra/unused builds of libgcc_s in non-langC builds | ||
| # (i.e. libgccjit, gnat, etc) to avoid potential confusion | ||
| lib.optionalString (!langC) '' | ||
| rm -f $out/lib/libgcc_s.so* | ||
| '' | ||
|
|
||
| # TODO(amjoseph): remove the `libgcc_s.so` symlinks below and replace them | ||
| # with a `-L${gccForLibs.libgcc}/lib` in cc-wrapper's | ||
| # `$out/nix-support/cc-flags`. See also: | ||
| # - https://github.com/NixOS/nixpkgs/pull/209870#discussion_r1130614895 | ||
| # - https://github.com/NixOS/nixpkgs/pull/209870#discussion_r1130635982 | ||
| # - https://github.com/NixOS/nixpkgs/commit/404155c6acfa59456aebe6156b22fe385e7dec6f | ||
| # | ||
| # move `libgcc_s.so` into its own output, `$libgcc` | ||
| + lib.optionalString enableLibGccOutput ('' | ||
| # move libgcc from lib to its own output (libgcc) | ||
| mkdir -p $libgcc/lib | ||
| mv $lib/lib/libgcc_s.so $libgcc/lib/ | ||
| mv $lib/lib/libgcc_s.so.1 $libgcc/lib/ | ||
| ln -s $libgcc/lib/libgcc_s.so $lib/lib/ | ||
| ln -s $libgcc/lib/libgcc_s.so.1 $lib/lib/ | ||
This conversation was marked as resolved.
Outdated
Show resolved
Hide resolved
|
||
| '' | ||
| # | ||
| # Nixpkgs ordinarily turns dynamic linking into pseudo-static linking: | ||
| # libraries are still loaded dynamically, exactly which copy of each | ||
| # library is loaded is permanently fixed at compile time (via RUNPATH). | ||
| # For libgcc_s we must revert to the "impure dynamic linking" style found | ||
| # in imperative software distributions. We must do this because | ||
| # `libgcc_s` calls `malloc()` and therefore has a `DT_NEEDED` for `libc`, | ||
| # which creates two problems: | ||
| # | ||
| # 1. A circular package dependency `glibc`<-`libgcc`<-`glibc` | ||
| # | ||
| # 2. According to the `-Wl,-rpath` flags added by Nixpkgs' `ld-wrapper`, | ||
| # the two versions of `glibc` in the cycle above are actually | ||
| # different packages. The later one is compiled by this `gcc`, but | ||
| # the earlier one was compiled by the compiler *that compiled* this | ||
| # `gcc` (usually the bootstrapFiles). In any event, the `glibc` | ||
| # dynamic loader won't honor that specificity without namespaced | ||
| # manual loads (`dlmopen()`). Once a `libc` is present in the address | ||
| # space of a process, that `libc` will be used to satisfy all | ||
| # `DT_NEEDED`s for `libc`, regardless of `RUNPATH`s. | ||
| # | ||
| # So we wipe the RUNPATH using `patchelf --set-rpath ""`. We can't use | ||
| # `patchelf --remove-rpath`, because at least as of patchelf 0.15.0 it | ||
| # will leave the old RUNPATH string in the file where the reference | ||
| # scanner can still find it: | ||
| # | ||
| # https://github.com/NixOS/patchelf/issues/453 | ||
| # | ||
| # Note: we might be using the bootstrapFiles' copy of patchelf, so we have | ||
| # to keep doing it this way until both the issue is fixed *and* all the | ||
| # bootstrapFiles are regenerated, on every platform. | ||
| # | ||
| # This patchelfing is *not* effectively equivalent to copying | ||
| # `libgcc_s` into `glibc`'s outpath. There is one minor and one | ||
| # major difference: | ||
| # | ||
| # 1. (Minor): multiple builds of `glibc` (say, with different | ||
| # overrides or parameters) will all reference a single store | ||
| # path: | ||
| # | ||
| # /nix/store/xxx...xxx-gcc-libgcc/lib/libgcc_s.so.1 | ||
| # | ||
| # This many-to-one referrer relationship will be visible in the store's | ||
| # dependency graph, and will be available to `nix-store -q` queries. | ||
| # Copying `libgcc_s` into each of its referrers would lose that | ||
| # information. | ||
| # | ||
| # 2. (Major): by referencing `libgcc_s.so.1`, rather than copying it, we | ||
| # are still able to run `nix-store -qd` on it to find out how it got | ||
| # built! Most importantly, we can see from that deriver which compiler | ||
| # was used to build it (or if it is part of the unpacked | ||
| # bootstrap-files). Copying `libgcc_s.so.1` from one outpath to | ||
| # another eliminates the ability to make these queries. | ||
| # | ||
| + '' | ||
| patchelf --set-rpath "" $libgcc/lib/libgcc_s.so.1 | ||
| ''); | ||
| })) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.