From ca355190c0db7ce25da5db616d3455533d0ac30d Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Sat, 22 Aug 2026 21:52:39 -0400 Subject: [PATCH] [FIX] binutils' extra targets were x86_64's, and gcc only wanted man pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gold failed to link with s390.cc: undefined reference to `void gold::gold_error_at_location<32, true>' Its s390 target file compiles code for both s390 and s390x and references <32, true> instantiations, which exist only when a 32-bit s390 target is configured. The PKGBUILD asks for --enable-targets=x86_64-pep,bpf-unknown-none. x86_64-pep is the PE+ target for x86_64: it means nothing here, and on x86_64 it is what happens to bring in the 32-bit instantiations gold's target files want. So this was never a gold bug -- it is the -march=x86-64 story one layer further in. s390-linux-gnu is the honest translation of that line. gcc now compiles, Fortran front end included, and stopped in package_gcc() on libstdc++'s doxygen man pages -- two places, build and install, the eighth time this port has met that shape. --- FR --- gold ne se liait pas : s390.cc: undefined reference to `void gold::gold_error_at_location<32, true>' Son fichier de cible s390 compile pour s390 et s390x et référence des instanciations <32, true>, qui n'existent que si une cible s390 32 bits est configurée. Le PKGBUILD demande --enable-targets=x86_64-pep,bpf-unknown-none. x86_64-pep est la cible PE+ d'x86_64 : elle ne veut rien dire ici, et sur x86_64 c'est elle qui amène par hasard les instanciations 32 bits que gold réclame. Ce n'était donc pas un défaut de gold — c'est l'histoire du -march=x86-64 une couche plus loin. s390-linux-gnu est la traduction honnête de cette ligne. gcc compile désormais, front-end Fortran compris, et s'arrêtait dans package_gcc() sur les pages de manuel doxygen de libstdc++ — deux endroits, construction et installation, huitième fois que ce portage rencontre cette forme. Assisted-by: Claude Opus 5 --- patches/pkgbuild/binutils.sh | 34 ++++++++++++++++++++++++++++++++++ patches/pkgbuild/gcc.sh | 28 ++++++++++++++++++++++++++++ scripts/build-stage2.sh | 4 +++- scripts/packages.sh | 9 +++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/patches/pkgbuild/binutils.sh b/patches/pkgbuild/binutils.sh index 661e155..d0f07e9 100755 --- a/patches/pkgbuild/binutils.sh +++ b/patches/pkgbuild/binutils.sh @@ -97,3 +97,37 @@ ZZPY 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" + +# --- the extra targets are x86_64's -------------------------------------------- +# +# s390.cc:(.text+0x2d76): undefined reference to +# `void gold::gold_error_at_location<32, true>(...)' +# +# gold's s390 target file compiles code for BOTH s390 (32-bit) and s390x, and +# references template instantiations for <32, true>. Those exist only if a +# 32-bit s390 target is configured -- and the PKGBUILD asks for +# +# --enable-targets=x86_64-pep,bpf-unknown-none +# +# x86_64-pep is the PE+ target for x86_64. It means nothing on this machine, and +# its presence is why gold linked on Arch and not here: on x86_64 that line +# happens to bring in the 32-bit instantiations gold's target files want. +# +# So this is not a workaround for a gold bug -- it is the same x86_64 assumption +# as the -march=x86-64 in makepkg.conf, one layer further in. s390-linux-gnu is +# the honest translation of that line, and it is what makes the templates exist. +# bpf-unknown-none stays: it is architecture-neutral. +set -euo pipefail +python3 - <<'ZZPY' +import io +s = io.open("PKGBUILD", encoding="utf-8").read() +old = "--enable-targets=x86_64-pep,bpf-unknown-none" +assert s.count(old) == 1, "binutils: expected one --enable-targets, got %d" % s.count(old) +s = s.replace(old, "--enable-targets=s390-linux-gnu,bpf-unknown-none", 1) +io.open("PKGBUILD", "w", encoding="utf-8").write(s) +ZZPY +grep -q -- "--enable-targets=s390-linux-gnu" PKGBUILD || { + echo "binutils: the target list was not translated" >&2; exit 1; } +grep -q "x86_64-pep" PKGBUILD && { + echo "binutils: an x86_64 target survived" >&2; exit 1; } +echo "binutils: extra targets translated to s390 (gold needs the 32-bit one)" diff --git a/patches/pkgbuild/gcc.sh b/patches/pkgbuild/gcc.sh index 49e85dd..6d5c5e8 100755 --- a/patches/pkgbuild/gcc.sh +++ b/patches/pkgbuild/gcc.sh @@ -445,3 +445,31 @@ grep -q -- '--with-arch=z13' PKGBUILD || { echo "gcc: baseline not set" >&2; exi grep -A1 -E -- '--enable-languages=' PKGBUILD | grep -q -- '--with-arch=z13' || { echo "gcc: --with-arch is in the file but not on the configure line" >&2; exit 1; } echo "gcc: baseline z13, tune z16" + +# --- no libstdc++ man pages ---------------------------------------------------- +# +# make: *** [Makefile:890: doc-install-man] Error 1 +# ==> ERROR: A failure occurred in package_gcc() +# +# gcc now COMPILES here -- what remained was libstdc++'s API documentation, built +# with doxygen. TWO PLACES: doc-man-doxygen in build() and doc-install-man in +# package(). Removing only the first fails on the second, which is the shape this +# port has now hit eight times. +# +# Worth noting how close this was to the end: the whole of gcc, including the +# Fortran front end that had failed for six passes, built successfully and then +# stopped on man pages. +python3 - <<'ZZPY' +import io, re +lines = io.open("PKGBUILD", encoding="utf-8").read().split("\n") +hit = [i for i, l in enumerate(lines) + if re.search(r"doc-man-doxygen|doc-install-man", l)] +assert len(hit) == 2, "gcc: expected two libstdc++ doc lines, got %d" % len(hit) +for i in reversed(hit): + ind = re.match(r"^[ \t]*", lines[i]).group(0) + lines[i] = ind + ": # libstdc++ man pages need doxygen, which this port lacks." +io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(lines)) +ZZPY +grep -qE "doc-man-doxygen|doc-install-man" PKGBUILD && { + echo "gcc: a libstdc++ doc target survived" >&2; exit 1; } +echo "gcc: libstdc++ man pages dropped" diff --git a/scripts/build-stage2.sh b/scripts/build-stage2.sh index c45b4f5..8b45040 100755 --- a/scripts/build-stage2.sh +++ b/scripts/build-stage2.sh @@ -717,7 +717,8 @@ NOTE # the host, whose python would bake dist-packages into every one of them. STAGE2_FIRST=(texinfo libxml2 binutils pkgconf wget libxslt python-packaging python-pyproject-hooks python-build - python-installer python-setuptools python-wheel) + python-installer python-setuptools python-wheel + python-setuptools-scm) # Packages the chroot needs that can only come from repo2. # @@ -777,6 +778,7 @@ CHROOT_STAGE2_PKGS=( # dist-packages so it can say so next time. python-packaging python-pyproject-hooks python-build python-installer python-setuptools python-wheel + python-setuptools-scm ) STAGE2_SKIP_HOOKS=(libgcrypt git meson libarchive) diff --git a/scripts/packages.sh b/scripts/packages.sh index 404cc84..9627bf0 100644 --- a/scripts/packages.sh +++ b/scripts/packages.sh @@ -270,6 +270,15 @@ STAGE1_PACKAGES=( # list -- and cmake is not optional here: the whole cmake/cppdap/jsoncpp/ # libuv group behind it is what several other packages build with. nlohmann-json + # python-setuptools-scm: python-tqdm's build stops on + # + # setuptools-scm[toml]>=3.4 + # + # which is a requirements line, not an error message -- pip printing what it + # could not find. Built by stage 2 with the rest of the Python set, for the + # same reason: its package() would take Debian's dist-packages from the + # host's python. + python-setuptools-scm # libxslt stays in the list because it is part of the distribution, but # STAGE 1 CANNOT BUILD IT: #