Creating the build directory in `..` may be OK in a sandbox, but this
makes it unnecessarily annoying when trying to work with this in a
source-checkout.
Hence, move the `build/` directory into the source tree.
Addresses further comments in #347965
On a Ubuntu machine with only C.utf-8 installed, you'd still get
perl: warning: Setting locale failed
since C.utf-8 is installed into `/usr/lib/locale` directly rather than
the archive.
`glibc` will first try to find a locate in the archive[1] and then fall
back to `lib/locale`[2]. This means that Ubuntu applications still find
C.utf-8 since its glibc finds it in `/usr/lib/locale`. However, Nix
built applications don't since they fall back to the system-wide archive
in `/usr/lib/locale/locale-archive`.
This patch changes our glibc to do the same what Ubuntu does: C.utf-8 is
installed into `$out/lib/locale`. If the systemd-wide locale archive
doesn't have C.utf-8, glibc now falls back to looking in
`$out/lib/locale`.
I confirmed on an Ubuntu 24.04 VM with empty locale archive that a
`cowsay` built on this branch falls back to `$out/lib/locale`:
/* exists, but empty */
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
[...]
/* fallback */
openat(AT_FDCWD, "/nix/store/vckzn6k0648yas09c58aq05bav82l46x-glibc-2.40-66/lib/locale/C.utf8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 3
I checked that this doesn't have obvious regressions on NixOS by
building the synapse test on this branch since synapse explicitly
depends on C.utf8 in PostgreSQL.
[1] https://sourceware.org/git/?p=glibc.git;a=blob;f=locale/findlocale.c;h=e5e2bd3974fe4fd31ae3567d411f1f84dccf8573;hb=HEAD#l152
[2] https://sourceware.org/git/?p=glibc.git;a=blob;f=locale/findlocale.c;h=e5e2bd3974fe4fd31ae3567d411f1f84dccf8573;hb=HEAD#l167
After final improvements to the official formatter implementation,
this commit now performs the first treewide reformat of Nix files using it.
This is part of the implementation of RFC 166.
Only "inactive" files are reformatted, meaning only files that
aren't being touched by any PR with activity in the past 2 months.
This is to avoid conflicts for PRs that might soon be merged.
Later we can do a full treewide reformat to get the rest,
which should not cause as many conflicts.
A CI check has already been running for some time to ensure that new and
already-formatted files are formatted, so the files being reformatted here
should also stay formatted.
This commit was automatically created and can be verified using
nix-build a08b3a4d19.tar.gz \
--argstr baseRev 57b193d8dd
result/bin/apply-formatting $NIXPKGS_PATH
this appears to have been added to glibc because of the number
of packages in some distributions that were built with CET enabled
before a CET enabled machine was available to test for breakage
with.
we don't have that problem to such an extent and users of hardened
systems will likely want to enable this by default.
Announcement: https://lists.gnu.org/archive/html/info-gnu/2024-01/msg00017.html
This release seems relatively harmless in terms of potential fallout.
Most notably is the removal of `crypt(3)` in favor of libxcrypt which
we've done already and compatibility from ISO C2X.
Also decided to drop the old *.gz approach in favor of inlining the
patch with the changes from the release branch directly: it's relatively
small in contrast to certain lockfiles in this repo and having a textual
version makes reviews & diffs easier. See also
https://github.com/NixOS/nixpkgs/pull/258972#discussion_r1454962456 for
more context.
This is an alternative resolution of the problem identified in
https://github.com/NixOS/nixpkgs/pull/259964
which stated that "glibc depends on buildPackages.glibc for locale
things. buildPackages.glibc depended on buildPackages.libgcc,
which, since it's GCC, depends on the target's bintools, which
depend on the target's glibc, which, again, depends on
buildPackages.glibc, causing an infinute recursion when evaluating
buildPackages.glibc when glibc hasn't come from stdenv (e.g. on
musl)."
The fact that we use pkgsBuildHost.glibc instead of
pkgsBuildBuild.glibc to generate the locales has always been a gross
hack. If we simply remove the gross hack the circularity goes away.
On some platforms (e.g. loongarch64-linux), libutil.so.1 is not built in
glibc (see glibc login/Makefile), only a dummy libutil.a is provided.
Do not symlink libutil.so but copy libutil.a to glibc.out if
libutil.so.1 does not exist.
### Summary
This PR completely and finally solves the gcc<->glibc circular
`buildInputs` problem, for cross compilation. The same technique
can be applied to native builds in the future.
Closes#213453
### Motivation
Prior to this PR, we had the following circular `buildInputs` problem:
1. gcc has glibc in its `buildInputs`
- a compiled copy of glibc must be present before building gcc;
if it isn't, gcc cripples itself (`inhibit_libc`) and refuses
to build libgcc_s.so
2. glibc has libgcc_s.so in its `buildInputs`
- glibc `dlopen()`s libgcc_s.so in order to implement POSIX
thread cancellation. For security reasons `glibc` requires
that the path to `libgcc_s.so` is [hardwired] into `glibc` at
compile time, so it's technically not a true dynamic link -- it
just pretends to be one.
3. libgcc_s.so is built in the same derivation as gcc
- libgcc_s.so is built as part of the gcc build process
We must cut one of these three links in the loop.
### Previous Attempts
Previously https://github.com/NixOS/nixpkgs/pull/238154 had
attempted to cut link (1) by building `gcc` without `glibc`, and
using the `libgcc_s` which emerges from that build. Unfortunately
this just doesn't work. GCC's configure script extracts quite a lot
of information from the glibc headers (which are a build artifact --
you can't just copy them out of the source tarball) and various
`./configure`-driven linking attempts. If `glibc` isn't around at
build time you wind up with a `libgcc_s.so` that is missing various
unwinder features (see https://github.com/NixOS/nixpkgs/issues/213453
for the most problematic one).
Musl "cuts" link (2), or rather never creates it in the first place.
["Cancellation cleanup handling in musl has no relationship to C++
exceptions and unwinding... glibc implements cancellation as an
exception"](https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-cancellation).
IMHO Musl made the smarter decision here. It is incredibly rare to
find a codebase that uses both POSIX thread cancellation *and* C++
exceptions. I have never seen a codebase that uses both *and*
expects them to be aware of each other, and I would be astonished if
one existed. Glibc paid an immense cost in complexity for something
nobody has ever used.
### Changes Made
This PR cuts link (3): instead of building libgcc_s.so as part of
gcc, we build it separately from gcc. Now there is a strict acyclic
graph of `buildInputs`:
```
gccWithoutTargetLibc
|
+--->glibc-nolibgcc
| |
| v
+--->libgcc
| |
| v
+--->glibc
| |
| v
+--->gcc
```
In other words, there's a simple linear `buildInputs` chain
`glibc-nolibgcc` `->` `libgcc` `->` `glibc` `->` `gcc` where all
four packages are compiled by (and therefore have as a
`(native)BuildInput`) `gccWithoutTargetLibc`.
`gccWithoutTargetLibc` and `glibc-nolibgcc` are strictly
bootstrapping artifacts; nothing else has them as a `buildInput` and
they shouldn't appear in the closure of any final deployment
packages. `glibc-nolibgcc` lacks `libgcc_s.so`, so it will segfault
if you try to use it with POSIX thread cancellation. Fortunately
all we need from it is (a) its headers (`lib.getDev`) and (b) to use
it in the `./configure` script for `libgcc`.
When translated over to the native bootstrap, `xgcc` takes the place
of `gccWithoutTargetLibc`, and the "first `glibc`" (we build two of
them) takes the place of `glibc-nolibgcc`. At that point our native
and cross bootstrap have the same overall architecture, and it
becomes possible to merge them (at last!)
[213453]: https://github.com/NixOS/nixpkgs/issues/213453
[238154]: https://github.com/NixOS/nixpkgs/pull/238154
[hardwired]: 7553d0fe29/pkgs/development/libraries/glibc/default.nix (L69-L88)
with structuredAttrs lists will be bash arrays which cannot be exported
which will be a issue with some patches and some wrappers like cc-wrapper
this makes it clearer that NIX_CFLAGS_COMPILE must be a string as lists
in env cause a eval failure
Without the change a copy from freshly built `gcc` still retains a
reference even after `patchelf --remove-rpath` because `patchelf` does
not cleanup dynamic sprintgs section.
The change stubs the reference out and fixes build on bootstraps where
`gcc` is built before `glibc`.
Otherwise copy it from the default output. The difference is visible
when we build `glibc` with:
- `bootstrapTools` `gcc`: ${stdenv.cc.cc.out}/lib/libgcc_s.so.1 is used
- `nixpkgs` `gcc`: ${stdenv.cc.cc.lib}/lib/libgcc_s.so.1 is used
Noticed when experimented with multiple `gcc` rebuilds in bootstrap.
While at it killing `RUNPATH` reference to bootstrap `glibc`.
Passing `-l$NIX_BUILD_CORES` improperly limits the overall system load.
For a build machine which is configured to run `$B` builds where each
build gets `total cores / B` cores (`$C`), passing `-l $C` to make will
improperly limit the load to `$C` instead of `$B * $C`.
This effect becomes quite pronounced on machines with 80 cores, with
40 simultaneous builds and a cores limit of 2. On a machine with this
configuration, Nix will run 40 builds and make will limit the overall
system load to approximately 2. A build machine with this many cores
can happily run with a load approaching 80.
A non-solution is to oversubscribe the machine, by picking a larger
`$C`. However, there is no way to divide the number of cores in a way
which fairly subdivides the available cores when `$B` is greater than
1.
There has been exploration of passing a jobserver in to the sandbox,
or sharing a jobserver between all the builds. This is one option, but
relatively complicated and only supports make. Lots of other software
uses its own implementation of `-j` and doesn't support either `-l` or
the Make jobserver.
For the case of an interactive user machine, the user should limit
overall system load using `$B`, `$C`, and optionally systemd's
cpu/network/io limiting features.
Making this change should significantly improve the utilization of our
build farm, and improve the throughput of Hydra.
Before the change separate-debug-info.sh did the stripping itself.
This scheme has a few problems:
1. Stripping happens only on ELF files. *.a and *.o files are skipped.
Derivations have to do it manually. Usually incorrectly
as they don't run $RANLIB (true for `glibc` and `musl`).
2. Stripping happens on all paths. Ideally only `stripDebugList` paths
should be considered.
3. Host strip is called on Target files.
This change offloads stripping logic to strip hook. This strips more
files for `glibc` and `musl`. Now we can remove most $STRIP calls
from individual derivations.
Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
Linking via `-lpthread` (or `-pthread`) is not needed anymore since
`glibc-2.34` since all the functionality is part of `libc.so.6` and
`libpthread.so.6` only exists for backwards-compatibility.
However, e.g. `gcc` (`libgomp` to be precise) expects a `libpthread.so`
to link against, otherwise the configure script will fail. As already
stated in the glibc release-notes itself, it is to expect that a lot
more applications will have issues with this, so I decided to re-add
`libpthread.so` as well.
For `librt.so.1`, the same thing is needed to make sure that Perl still
compiles:
/nix/store/d6y5r7m93x14bmgn2p75fannz39jz66f-binutils-2.35.1/bin/ld: cannot find -lrt
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:490: ../../lib/auto/Time/HiRes/HiRes.so] Error 1
make[1]: Leaving directory '/build/perl-5.34.0/dist/Time-HiRes'