From a42e43bcf13d741136df92ad31ff39c8f17a9dd0 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Fri, 21 Aug 2026 04:16:20 -0400 Subject: [PATCH] [FIX] binutils: no PGO+LTO build, so gold links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Built at stage 1, failed at stage 2, in gold: :(.text+0xc44e): undefined reference to `void gold::gold_error_at_location<32, true>(...)' `` and the .ltrans object names are LTO's, and it does not come from makepkg -- the chroot carries !lto with an empty LTOFLAGS. It comes from the PKGBUILD: --enable-pgo-build=lto. gold's explicitly-instantiated templates do not survive it here. Stage 1 got away with it because the host's GCC did the work; stage 2 uses ours, at -O2 -march=z13 where stage 1 passed no flags. PGO and LTO are build-time optimisations: what changes is how long binutils takes to compile and how fast the linker runs, not what it can do. The alternatives were removing gold, a linker Arch ships, or debugging LTO template instantiation in a linker upstream has deprecated. The first attempt at this hook looked for --with-build-config=bootstrap-lto, which is in gcc's PKGBUILD, not binutils'. Its own assertion caught it. --- FR --- Bâti à l'étage 1, échoué à l'étage 2, dans gold : :(.text+0xc44e): undefined reference to `void gold::gold_error_at_location<32, true>(...)' `` et les noms d'objets .ltrans sont ceux du LTO, et il ne vient pas de makepkg — le chroot porte !lto avec un LTOFLAGS vide. Il vient du PKGBUILD : --enable-pgo-build=lto. Les gabarits explicitement instanciés de gold n'y survivent pas. L'étage 1 s'en tirait car le GCC de l'hôte faisait le travail ; l'étage 2 utilise le nôtre, à -O2 -march=z13 là où l'étage 1 ne passait rien. PGO et LTO sont des optimisations de construction : ce qui change, c'est la durée de compilation et la vitesse du lieur, pas ce qu'il sait faire. Les options étaient de retirer gold, un lieur qu'Arch livre, ou de déboguer une instanciation de gabarit sous LTO dans un lieur abandonné en amont. La première version de ce hook cherchait --with-build-config=bootstrap-lto, qui est dans le PKGBUILD de gcc, pas de binutils. Sa propre assertion l'a arrêtée. Assisted-by: Claude Opus 5 --- patches/pkgbuild/binutils.sh | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/patches/pkgbuild/binutils.sh b/patches/pkgbuild/binutils.sh index 3c25017..454df82 100755 --- a/patches/pkgbuild/binutils.sh +++ b/patches/pkgbuild/binutils.sh @@ -43,3 +43,46 @@ ZZPY grep -A1 -E "/configure( |\\\\)" PKGBUILD | grep -q -- '--libdir=/usr/lib' || { echo "binutils: --libdir is not on the configure line" >&2; exit 1; } echo "binutils: libdir pinned to /usr/lib (keeps /usr/lib64 a symlink)" + +# --- no PGO+LTO build --------------------------------------------------------- +# +# binutils built at stage 1 and failed at stage 2, in gold: +# +# :(.text+0xc44e): undefined reference to +# `void gold::gold_error_at_location<32, true>(...)' +# collect2: error: ld returned 1 exit status +# +# `` and the .ltrans object names are LTO's. It does not come from +# makepkg -- the chroot's OPTIONS carry !lto and LTOFLAGS is empty. It comes +# from the PKGBUILD itself: --enable-pgo-build=lto, a profile-guided build with +# link-time optimisation, which passes -flto=jobserver. gold's +# explicitly-instantiated templates do not survive it here. +# +# Stage 1 got away with it because the host's GCC did the work. Stage 2 uses +# ours, on s390x, at -O2 -march=z13 where stage 1 passed no flags at all. +# +# PGO and LTO are BUILD-TIME optimisations: dropping them changes how long +# binutils takes to compile and how fast the resulting linker runs, not what it +# can do. The alternatives were disabling gold -- removing a linker Arch ships +# -- or debugging an LTO template instantiation bug in a linker upstream has +# deprecated. For a bootstrap, a binutils that works beats a binutils that is +# five percent faster; PGO also roughly triples the build, which this port pays +# for on every stage. +python3 - <<'ZZPY' +import io, re +lines = io.open("PKGBUILD", encoding="utf-8").read().split("\n") +hit = [i for i, l in enumerate(lines) if "--enable-pgo-build" in l] +assert len(hit) == 1, "binutils: expected one --enable-pgo-build line, got %d" % len(hit) +i = hit[0] +assert lines[i].strip().startswith("--enable-pgo-build"), \ + "binutils: --enable-pgo-build shares its line: %r" % lines[i] +ind = re.match(r"^[ \t]*", lines[i]).group(0) +lines[i] = ind + "# --enable-pgo-build=lto removed: gold's templates do not survive" +lines.insert(i + 1, ind + "# LTO here, and PGO is build-time only -- no feature is lost.") +io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(lines)) +ZZPY +grep -q "enable-pgo-build=lto removed" PKGBUILD || { + echo "binutils: the PGO line was not commented" >&2; exit 1; } +grep -qE "^[[:space:]]*--enable-pgo-build" PKGBUILD && { + echo "binutils: an active --enable-pgo-build line survived" >&2; exit 1; } +echo "binutils: PGO+LTO build dropped"