glibc: install C.utf8 into locale dir instead of archive

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
This commit is contained in:
Maximilian Bosch 2025-02-15 15:47:26 +01:00
parent e41e61c973
commit 1158cd5c13
No known key found for this signature in database

View File

@ -119,7 +119,10 @@ in
if stdenv.buildPlatform.canExecute stdenv.hostPlatform then
''
echo SUPPORTED-LOCALES=C.UTF-8/UTF-8 > ../glibc-2*/localedata/SUPPORTED
make -j''${NIX_BUILD_CORES:-1} localedata/install-locales
# Don't install C.utf-8 into the archive, but into $out/lib/locale: on non-NixOS
# systems with an empty /usr/lib/locale/locale-archive, glibc would fall back to
# $libdir/locale/C.utf-8 instead of the locale archive of pkgs.glibc. See also #347965.
make -j''${NIX_BUILD_CORES:-1} localedata/install-locale-files
''
else
lib.optionalString stdenv.buildPlatform.isLinux