@@ -9,29 +9,20 @@ versions:
99 - /glibc-/
1010 - /\.tar\.xz/
1111
12- # Empirically verified host-independent build (pkgx toolchain only,
13- # debian:bookworm-slim base with no apt-installed compiler):
14- # linux/x86-64: 2.17, 2.24, 2.27, 2.28, 2.34, 2.38, 2.41, 2.42, 2.43
15- # linux/aarch64: 2.17, 2.24, 2.27, 2.28, 2.34, 2.38, 2.41, 2.42, 2.43
16- # Full 9-version parity on both arches. Each bottle cross-tested on
17- # Alpine 3.18 (musl host), Debian 11, Ubuntu 22.04 — all return
18- # gnu_get_libc_version() = <bottle-version>.
12+ # Current support targets:
13+ # linux/x86-64: 2.17+
14+ # linux/aarch64: 2.28+
1915#
20- # 2.17 (manylinux2014 / CentOS 7 / HPC baseline) and 2.24
21- # (manylinux_2_24) are built via a bootstrap-cascaded toolchain
22- # (gcc 7.5 + binutils 2.28). The cascade procedure is documented in
23- # README.md "HPC bootstrap cascade". The toolchain bottles produced
24- # (gcc 9.5, gcc 7.5, binutils 2.28/2.30/2.31/2.32) are candidates
25- # to ship in dist.pkgx.dev as `gnu.org/gcc` and `gnu.org/binutils`
26- # older-version bottles — currently built inside the build env.
16+ # Older aarch64 glibc releases fail in rtld/ld.so with non-PIC relocation
17+ # errors under the modern pkgx toolchain. Treat <2.28 aarch64 as unsupported
18+ # unless/until we add a real old-toolchain bootstrap path.
2719#
2820# darwin/* is intentionally absent. glibc is the GNU C library for the
2921# Linux kernel — macOS uses libSystem + dyld with an entirely separate
3022# binary format (Mach-O vs ELF). There is no glibc port to Darwin and
3123# bottling one would not produce something usable.
3224platforms :
33- - linux/x86-64
34- - linux/aarch64
25+ - linux
3526
3627build :
3728 # Skip brewkit's "SLOW rpath fixes" — it writes a 46-package
@@ -47,7 +38,10 @@ build:
4738 dependencies :
4839 gnu.org/make : " >=4.0"
4940 gnu.org/gawk : " >=3"
50- gnu.org/gcc : " *" # pkgx ships 10.5–16.1; verified with 16.1
41+ gnu.org/gcc : 14 # gcc 16 trips old glibc aarch64 rtld / inline semantics
42+ gnu.org/gmp : " >=4.2"
43+ gnu.org/mpfr : " >=2.4.0"
44+ gnu.org/mpc : " >=0.8.0"
5145 gnu.org/binutils : " >=2.40" # required by glibc 2.42+; older glibcs also build with 2.46
5246 gnu.org/gettext : " *"
5347 gnu.org/texinfo : " *" # required for `make install` (manual/libc.info)
@@ -62,11 +56,17 @@ build:
6256 perl.org : " ^5"
6357 python.org : " ~3.11"
6458 kernel.org/linux-headers : " *" # the file that makes the build host-independent
65- nixos.org/patchelf : " *" # used to detect ELF tools before wrapping them
6659
6760 working-directory : build
6861
6962 script :
63+ - run :
64+ - if test "{{hw.arch}}" = "aarch64"; then
65+ - echo "glibc {{version}} is unsupported on linux/aarch64; this recipe supports linux/aarch64 from 2.28 onward."
66+ - exit 1
67+ - fi
68+ if : <2.28
69+
7070 # Hygiene patches from nixpkgs. They prevent the new ld.so from reading
7171 # the host's /etc/ld.so.cache and /etc/ld.so.preload — both files have
7272 # glibc-version-specific binary formats, reading them with a different
@@ -82,51 +82,102 @@ build:
8282 if : " >=2.32"
8383 working-directory : ..
8484
85- # glibc 2.17/2.18 configure has a python regex that rejects `make` >= 4.0.
86- # 1-line fix preserving the same regex shape, accepting modern make.
87- # Use # as sed delimiter because the pattern itself contains |.
88- - run : sed -i 's#3\.79\* | 3\.\[89\]\*#3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*#' configure
85+ - run :
86+ # glibc 2.17/2.18 configure has a version case that rejects `make` >= 4.0.
87+ # Keep the same case-pattern shape, accepting modern make.
88+ # Use # as sed delimiter because the pattern itself contains |.
89+ - sed -i 's#3\.79\* | 3\.\[89\]\*#3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*#' configure
90+ # glibc 2.17/2.18 configure similarly only accepts gcc 4.x or 5–9.x.
91+ # Modern pkgx gcc is 10+, so extend the existing case branch.
92+ - sed -i 's#\[5-9\]\.\* )#[5-9].* | [1-9][0-9]*.* )#' configure
93+ # The ld --no-whole-archive probe uses pre-C99 function definitions
94+ # (`_start () {}`), but glibc itself still needs gnu99 later. Keep
95+ # gnu89 scoped to this configure probe; do not put it in CFLAGS.
96+ - sed -i '/checking for ld --no-whole-archive/,/-nostdlib/s/\$CFLAGS \$CPPFLAGS/\$CFLAGS -std=gnu89 \$CPPFLAGS/' configure
97+ # Force the configure cache so Makeconfig gets `gnu89-inline-CFLAGS=-fgnu89-inline`.
98+ - export libc_cv_gnu89_inline=yes
99+ # Likewise, stdio lock cleanup macros require `exceptions=-fexceptions`.
100+ - export libc_cv_gcc_exceptions=yes
101+ # With current GCC/binutils, glibc 2.17's rtld link keeps explicit
102+ # references to a few libc-private syscall wrappers that older builds
103+ # used to fold away. Keep this scoped to rtld so normal libc remains
104+ # upstream-shaped.
105+ - rm -f build/elf/dl-pkgx-rtld-compat.* build/elf/dl-allobjs.os build/elf/librtld* build/elf/ld.so build/elf/ld-linux*
106+ - install -m 644 props/dl-pkgx-rtld-compat-2.17.c sysdeps/unix/sysv/linux/dl-pkgx-rtld-compat.c
107+ - grep -q 'dl-pkgx-rtld-compat' sysdeps/unix/sysv/linux/Makefile ||
108+ sed -i 's/dl-fxstatat64/dl-fxstatat64 dl-pkgx-rtld-compat/' sysdeps/unix/sysv/linux/Makefile
109+ - awk -f $PROP sysdeps/unix/sysv/linux/Makefile > sysdeps/unix/sysv/linux/Makefile.pkgx
110+ - mv sysdeps/unix/sysv/linux/Makefile.pkgx sysdeps/unix/sysv/linux/Makefile
111+ - cat props/sysdeps-Makefile >> sysdeps/unix/sysv/linux/Makefile
112+ # glibc 2.17's early Makerules pass can evaluate before soversions.mk is
113+ # included, clearing `static-only-routines` and omitting elf-init.oS from
114+ # libc_nonshared.a. Dynamic build tools then fail to resolve
115+ # __libc_csu_init/fini from crt1.o.
116+ - sed -i '/ifndef libc.so-version/,/endif/s/^static-only-routines =/# static-only-routines =/' Makerules
117+ # Ensure the nonshared archive actually carries the csu entry points used
118+ # by crt1.o. crt1.o needs __libc_csu_init/fini from elf-init.oS, and this
119+ # old release's generated stamp handling is fragile enough to pin directly.
120+ - grep -q '^o-objects.oS += elf-init.oS$' csu/Makefile || echo 'o-objects.oS += elf-init.oS' >> csu/Makefile
121+ prop : |
122+ /# rtld-pkgx-alias-routines/ { skip = 1; next }
123+ skip && /^ifeq \(\$\(subdir\),elf\)$/ { next }
124+ skip && /^sysdep-rtld-routines \+=/ { next }
125+ skip && /^endif$/ { skip = 0; next }
126+ { print }
89127 if : <2.19
90128 working-directory : ..
91129
92- # glibc < 2.32 has multiple tentative .bss definitions of __nss_*_database
93- # that gcc 10+'s default -fno-common rejects. Add -fcommon for old glibc.
94130 - run :
95- - EXTRA_CFLAGS=""
96- - if [ {{version.major}}{{version.minor}} -lt 232 ]; then
97- - EXTRA_CFLAGS="-fcommon -Wno-error"
98- - fi
131+ # glibc 2.24's Makerules try to copy <cstdlib>/<cmath> by deriving their
132+ # paths from `$(CXX) -M`; with modern C++ headers that probe can return
133+ # empty, making `install $< $@T` call install with no source operand.
134+ # Disable this optional workaround for the 2.24 build.
135+ - sed -i 's/^ifneq (,$(CXX))/ifneq (,$(CXX_DISABLED_FOR_PKGX))/' Makerules
99136 # glibc decides its own pie/-shared per target — pkgx gcc 16
100137 # is built with --enable-default-pie, so its CC defaults add
101138 # -fPIE/-pie. That breaks glibc's static auxiliary tools
102139 # (support/test-run-command et al) with "_DYNAMIC isn't
103140 # defined". Explicitly disable the default with -fno-PIE and
104141 # -no-pie at the link step; glibc adds them back per-target
105142 # where actually wanted (shared libs use -fPIC anyway).
106- #
107- # libc_cv_slibdir / libc_cv_rtlddir override the autoconf-cached
108- # slibdir / rtlddir vars so libc.so.6 + ld-linux*.so go into
109- # the sub-libdir alongside our other libs. Without this,
110- # --libdir alone only affects gconv/audit plugins; libc.so.6
111- # still ends up at $prefix/lib/ and pollutes consumers'
112- # LD_LIBRARY_PATH (incompatible with the host's older ld-linux).
113- - LIBDIR="{{prefix}}/lib/glibc-{{version.marketing}}"
114- - CFLAGS="-O2 -fPIC $EXTRA_CFLAGS"
115- libc_cv_slibdir="$LIBDIR"
116- libc_cv_rtlddir="$LIBDIR"
117- libc_cv_complocaledir="$LIBDIR/locale"
118- libc_cv_static_pie=no
119- ../configure $ARGS
143+ - EXTRA_CFLAGS="$EXTRA_CFLAGS -fno-PIE"
144+ - LDFLAGS="$LDFLAGS -no-pie"
145+ if : <2.25
146+ working-directory : ..
120147
121- - make --jobs {{ hw.concurrency }} CFLAGS-regexp.c=-fno-common
148+ # glibc < 2.32 has multiple tentative .bss definitions of __nss_*_database
149+ # that gcc 10+'s default -fno-common rejects. Add -fcommon for old glibc.
150+ - run : EXTRA_CFLAGS="$EXTRA_CFLAGS -fcommon -Wno-error"
151+ if : <2.32
152+
153+ # libc_cv_slibdir / libc_cv_rtlddir override the autoconf-cached
154+ # slibdir / rtlddir vars so libc.so.6 + ld-linux*.so go into
155+ # the sub-libdir alongside our other libs. Without this,
156+ # --libdir alone only affects gconv/audit plugins; libc.so.6
157+ # still ends up at $prefix/lib/ and pollutes consumers'
158+ # LD_LIBRARY_PATH (incompatible with the host's older ld-linux).
159+ - LIBDIR="{{prefix}}/lib/glibc-{{version.marketing}}"
160+ - CFLAGS="-O2 $EXTRA_CFLAGS -fPIC"
161+ CPP="gcc -E"
162+ LDFLAGS="$LDFLAGS"
163+ libc_cv_slibdir="$LIBDIR"
164+ libc_cv_rtlddir="$LIBDIR"
165+ libc_cv_complocaledir="$LIBDIR/locale"
166+ libc_cv_static_pie=no
167+ ../configure $ARGS
168+
169+ - run : MAKE_JOBS={{ hw.concurrency }}
170+ - run : rm -f libc_nonshared.a libc_pic.a libc_pic.os */stamp.os */stamp.oS
171+ if : <2.19
172+ - make --jobs $MAKE_JOBS CFLAGS-regexp.c=-fno-common CFLAGS-obstack.c=-fno-common
122173 - make install
123174
124175 # Self-relocate generated scripts so the bottle works at any prefix.
125- - run : |
126- for s in $SCRIPTS; do
127- test -f $s || continue
128- sed -i 's|{{prefix}}|"$(cd "$(dirname "$0")/.." \&\& pwd)"|' $s
129- done
176+ - run :
177+ - for s in $SCRIPTS; do
178+ - test -f $s || continue
179+ - sed -i 's|{{prefix}}|"$(cd "$(dirname "$0")/.." \&\& pwd)"|' $s
180+ - done
130181 working-directory : ${{prefix}}/bin
131182
132183 # Convenience: arch-agnostic ld.so symlink that points into the
@@ -139,17 +190,14 @@ build:
139190 # downstream `-L $LIBDIR -lc` works after the bottle relocates from
140191 # /opt to ~/.pkgx (or anywhere else). Detect via first-line marker,
141192 # not file(1) — not on the test-sandbox PATH.
142- - run : |
143- PREFIX_FINAL=$(echo "{{prefix}}" | sed 's/+brewing$//')
144- for f in $(find . -maxdepth 2 -type f -name '*.so'); do
145- if head -c 16 "$f" | grep -q "GNU ld script"; then
146- sed -i \
147- -e 's|{{prefix}}/lib/glibc-{{version.marketing}}/||g' \
148- -e "s|$PREFIX_FINAL/lib/glibc-{{version.marketing}}/||g" \
149- "$f"
150- echo "relocated linker script $f"
151- fi
152- done
193+ - run :
194+ - PREFIX_FINAL=$(echo "{{prefix}}" | sed 's/+brewing$//')
195+ - for f in $(find . -maxdepth 2 -type f -name '*.so'); do
196+ - if head -c 16 "$f" | grep -q "GNU ld script"; then
197+ - sed -i -e 's|{{prefix}}/lib/glibc-{{version.marketing}}/||g' -e "s|$PREFIX_FINAL/lib/glibc-{{version.marketing}}/||g" "$f"
198+ - echo "relocated linker script $f"
199+ - fi
200+ - done
153201 working-directory : ${{prefix}}/lib
154202
155203 # PT_INTERP is absolute and cannot use $ORIGIN or fall back. Do not
@@ -161,18 +209,18 @@ build:
161209 # Running an ELF through ld.so explicitly ignores the ELF's own
162210 # PT_INTERP, so the inner libexec binaries may keep whatever glibc's
163211 # build installed. The wrapper supplies --library-path explicitly.
164- - run : |
165- for dir in bin sbin; do
166- mkdir -p "{{prefix}}/libexec/glibc-$dir"
167- for f in "{{prefix}}/$dir"/*; do
168- [ -f "$f" ] && [ ! -L "$f" ] || continue
169- patchelf --print-interpreter "$f" >/dev/null 2>&1 || continue
170- mv "$f" "{{prefix}}/libexec/glibc-$dir"
171- sed -e "s/@LDSO@/$LDSO/g" -e "s/@DIR@/$dir/g" "$PROP" >$f
172- chmod 775 $f
173- echo "wrapped $f"
174- done
175- done
212+ - run :
213+ - for dir in bin sbin; do
214+ - mkdir -p "{{prefix}}/libexec/glibc-$dir"
215+ - for f in "{{prefix}}/$dir"/*; do
216+ - ' [ -f "$f" ] && [ ! -L "$f" ] || continue'
217+ - test "$(head -c 4 "$f" | od -An -tx1 | tr -d ' \n')" = "7f454c46" || continue
218+ - mv "$f" "{{prefix}}/libexec/glibc-$dir"
219+ - sed -e "s/@LDSO@/$LDSO/g" -e "s/@DIR@/$dir/g" "$PROP" > "$f"
220+ - chmod 755 "$f"
221+ - echo "wrapped $f"
222+ - done
223+ - done
176224 prop : |
177225 #!/bin/sh
178226
@@ -232,7 +280,7 @@ build:
232280# bin/* work after relocation.
233281test :
234282 dependencies :
235- gnu.org/gcc : " * "
283+ gnu.org/gcc : 14
236284 env :
237285 x86-64 :
238286 LDSO : ld-linux-x86-64.so.2
@@ -247,8 +295,10 @@ test:
247295 - test -L "{{prefix}}/bin/ld.so" || { echo "missing bin/ld.so symlink"; exit 1; }
248296
249297 # 2) Loader self-test (was SIGSEGV before the fix-patchelf skip).
250- - echo "--- ld.so --version ---"
251- - ' "$LIBDIR/$LDSO" --version | head -2'
298+ # Older loaders treat bare `--version` as the executable name, so execute
299+ # libc.so.6 through this bottle's loader instead.
300+ - echo "--- ld.so libc.so.6 --version ---"
301+ - ' "$LIBDIR/$LDSO" --library-path "$LIBDIR" "$LIBDIR/libc.so.6"'
252302
253303 # 3) Compile test.c dynamically against the bottle's headers /
254304 # libs / loader. -B $LIBDIR picks our Scrt1.o / crti.o / crtn.o
0 commit comments