Skip to content

stdenv, gcc: rename postPostInstall -> preFixup#223634

Closed
ghost wants to merge 13 commits intostagingfrom
unknown repository
Closed

stdenv, gcc: rename postPostInstall -> preFixup#223634
ghost wants to merge 13 commits intostagingfrom
unknown repository

Conversation

@ghost
Copy link
Copy Markdown

@ghost ghost commented Mar 28, 2023

Description of changes

This commit implements @SuperSandro2000's suggestion here:

#209870 (review)

I am submitting it as a separate PR in order to avoid a full rebuild on Hydra.

Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 23.05 Release Notes (or backporting 22.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Adam Joseph and others added 13 commits March 16, 2023 21:35
The command

```
nix-build -A tests.trivial-builders.references --show-trace
```

fails eval with

```
in job ‘nixpkgs.tests.trivial-builders.references’:
error: The option `meta.description' does not exist. Definition values:
       - In `makeTest parameters': "Run the Nixpkgs trivial builders tests"
```

because `meta.description` and `meta.license` are not valid for
`nixosTest`s (they are valid for `mkDerivation` of course).

This has been causing Hydra eval failures:

  https://hydra.nixos.org/jobset/nixos/pr-209870-gcc-external-bootstrap#tabs-errors

Let's fix eval by removing these attributes.
The command at the top of this file fails to evaluate:

```
$ nix-build -A tests.pkg-config.defaultPkgConfigPackages
in job ‘nixpkgs.tests.pkg-config.defaultPkgConfigPackages.tests-combined.x86_64-linux’:
error: pkg-config module `recurseForDerivations` is not defined to be a derivation. Please check the attribute value for `recurseForDerivations` in `pkgs/top-level/pkg-config-packages.nix` in Nixpkgs.
```

This is also causing eval errors on Hydra:

  https://hydra.nixos.org/jobset/nixos/pr-209870-gcc-external-bootstrap#tabs-errors

Let's filter out `recurseForDerivations=true` from the attrset,
since it exists mainly as a flag to signal special handling when
recursing.
When wrapping `clang` and using a `gccForLibs` whose `libgcc` is in
its own output (rather than the `lib` output), this commit will adds
`-L${gccForLibs.libgcc}/lib` to `cc-ldflags`.

If that flag is not added, `firefox` will fail to compile because it
invokes `clang-wrapper` with `-fuse-ld=lld` and passes `-lgcc_s` to
`lld`, but does not tell `lld` where to find `libgcc_s.so`.  In that
situation, firefox will fail to link.
The Nix-driven bootstrap of gcc expects that `stdenv.cc.cc` has a
`version` attribute, except if `stdenv.cc` is the `bootstrapFiles`.

This commit causes `ccache-links`'s `cc-wrapper` to `inherit
version` in order to satisfy that requirement.  Without this commit,
ofborg CI will fail.

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
This commit has no effect on eval.  It simply factors out a common
subexpression.
This commit has no effect on eval.  It simply reorganizes the
`gcc11` and `gcc12` expressions so they apply a list of
`overrideAttrs`.  The list is currently empty.
 #### Summary

By default, when you type `make`, GCC will compile itself three
times.  This PR inhibits that behavior by configuring GCC with
`--disable-bootstrap`, and reimplements the triple-rebuild using
Nix rather than `make`/`sh`.

 #### Immediate Benefits

- Allow `gcc11` and `gcc12` on `aarch64` (without needing new
  `bootstrapFiles`)
- Faster stdenv rebuilds: the third compilation of gcc
  (i.e. stageCompare) is no longer a `drvInput` of the final stdenv.
  This allows Nix to build stageCompare in parallel with the rest of
  nixpkgs instead of in series.
- No more copying `libgcc_s` out of the bootstrap-files or other
  derivations
- No more Frankenstein compiler: the final gcc and the libraries it
  links against (mpfr, mpc, isl, glibc) are all built by the same
  compiler (xgcc) instead of a mixture of the bootstrapFiles'
  compiler and xgcc.
- No more [static lib{mpfr,mpc,gmp,isl}.a hack]
- Many other small `stdenv` hacks eliminated
- `gcc` and `clang` share the same codepath for more of `cc-wrapper`.

 #### Future Benefits

- This should allow using a [foreign] `bootstrap-files` so long as
  `hostPlatform.canExecute bootstrapFiles`.
- This should allow each of the libraries that ship with `gcc`
  (lib{backtrace, atomic, cc1, decnumber, ffi, gomp, iberty,
  offloadatomic, quadmath, sanitizer, ssp, stdc++-v3, vtv}) to be
  built in separate (one-liner) derivations which `inherit src;`
  from `gcc`, much like #132343

 #### Incorporates

- #210004
- #36948 (unreverted)
- #210325
- #210118
- #210132
- #210109
- #213909
- #216136
- #216237
- #210019
- #216232
- #216016
- #217977
- #217995

 #### Closes

- Closes #108305
- Closes #108111
- Closes #201254
- Closes #208412

 #### Credits

This project was made possible by three important insights, none of
which were mine:

1. @Ericson2314 was the first to advocate for this change, and
   probably the first to appreciate its advantages.  Nix-driven
   (external) bootstrap is "cross by default".

2. @trofi has figured out a lot about how to get gcc to not mix up
   the copy of `libstdc++` that it depends on with the copy that it
   builds, by moving the `bootstrapFiles`' `libstdc++` into a
   [versioned directory].  This allows a Nix-driven bootstrap of gcc
   without the final gcc would still having references to the
   `bootstrapFiles`.

3. Using the undocumented variable [`user-defined-trusted-dirs`]
   when building glibc.  When glibc `dlopen()`s `libgcc_s.so`, it
   uses a completely different and totally special set of rules for
   finding `libgcc_s.so`.  This trick is the only way we can put
   `libgcc_s.so` in its own separate outpath without creating
   circular dependencies or dependencies on the bootstrapFiles.  I
   would never have guessed to use this (or that it existed!) if it
   were not for a [comment in guix] which @Mic92 [mentioned].

My own role in this PR was basically: being available to go on a
coding binge at an opportune moment, so we wouldn't waste a
[crisis].

[aarch64-compare-ofborg]: https://github.com/NixOS/nixpkgs/pull/209870/checks?check_run_id=10662822938
[amd64-compare-ofborg]: https://github.com/NixOS/nixpkgs/pull/209870/checks?check_run_id=10662825857
[nonexistent sysroot]: #210004
[versioned directory]: #209054
[`user-defined-trusted-dirs`]: https://sourceware.org/legacy-ml/libc-help/2013-11/msg00026.html
[comment in guix]: https://github.com/guix-mirror/guix/blob/5e4ec8218142eee8e6e148e787381a5ef891c5b1/gnu/packages/gcc.scm#L253
[mentioned]: #210112 (comment)
[crisis]: #108305
[foreign]: #170857 (comment)
[static lib{mpfr,mpc,gmp,isl}.a hack]: https://github.com/NixOS/nixpkgs/blob/2f1948af9c984ebb82dfd618e67dc949755823e2/pkgs/stdenv/linux/default.nix#L380
This commit adds `gcc/common/checksum.nix`, which contains code
common to both gcc11 and gcc12, implementing the `enableChecksum`
feature.

When gcc's built-in bootstrap (`--enable-bootstrap`) is used, gcc
compiles itself three times and compares a hash of the unlinked `.o`
files from the second and third compilation.  The
`enableChecksum=true` parameter performs the same comparison as part
of the `postInstall` phase.

Notably, `enableChecksum=true` can be used with `enableBootstrap=false`.

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
This commit adds a derivation `gcc-stageCompare` to
`pkgs/test/stdenv/default.nix`.

It is important to always build this derivation whenever building
`stdenv`!  Because we are using a Nix-driven bootstrap instead of
gcc's built-in `--enable-bootstrap`, the `gcc` derivation no longer
performs the post-self-compilation sanity check.  You must build
this derivation in order to perform that sanity check.

The major benefit of this new approach is that the sanity check
(which involves a third compilation of gcc) can be performed
*concurrently* with all packages that depend on `stdenv`, rather
than serially.  Since `stdenv` has very little derivation-level
parallelism it cannot take advantage of more than one or perhaps two
builders.  If you have three or more builders this commit will
reduce the time-to-rebuild-stdenv by around 20% (one of three gcc
rebuilds is removed from the critical path, and stdenv's build time
is dominated by roughly 3*gcc + 1*binutils + 1*bison-test-suite).

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
The Nix-driven bootstrap of gcc resulted in some changes to the
structure of the `libgccjit` outpaths, and also added an additional
output (`libgcc`) to `gcc`.

This commit makes the corresponding changes in the `emacs`
derivation in order to not break emacs.

Emacs is the only user of `libgccjit` in nixpkgs at the moment.
This commit implements @SuperSandro2000's suggestion here:

  #209870 (review)

I am submitting it as a separate PR in order to avoid a full rebuild
on Hydra.
@ghost ghost mentioned this pull request Mar 28, 2023
4 tasks
@github-actions github-actions bot added 6.topic: emacs Text editor 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: stdenv Standard environment labels Mar 28, 2023
@ofborg ofborg bot added 10.rebuild-linux-stdenv This PR causes stdenv to rebuild on Linux and must target a staging branch. 8.has: package (new) This PR adds a new package 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. labels Mar 28, 2023
@Artturin Artturin closed this Apr 22, 2023
@Artturin
Copy link
Copy Markdown
Member

no references to postPostInstallPhase in master so assuming unnecessary

@ghost ghost deleted the pr/stdenv/rename-extra-phases branch April 24, 2023 00:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: emacs Text editor 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: stdenv Standard environment 8.has: package (new) This PR adds a new package 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. 10.rebuild-linux-stdenv This PR causes stdenv to rebuild on Linux and must target a staging branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant