From bda5fe67c57262661fa87b6b6f38a7c23231d1a9 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Mon, 17 Aug 2026 02:37:46 -0400 Subject: [PATCH] [FIX] gcc: a dropped component is removed in a fifth place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The repository already knew four: pkgname, the build block, the _pick lines, the explicit make targets. There is a fifth, and it is the only one that fails silently -- the depends= array of a DIFFERENT sub-package. --nodeps means makepkg never checks, so gcc-libs built, passed, and went into the repository declaring a dependency on libhwasan, which this architecture never produces. Nothing said a word. pacman did, the first time anything tried to install it: :: unable to satisfy dependency 'libhwasan' required by gcc-libs This was already paid for once: an earlier pass hit it with libquadmath and pruned that one name by hand. libhwasan joined the drop set afterwards and the pruning was not extended. Pruning one name at a time was the bug. The set that decides what is not built now also decides what is not depended on, and an assertion refuses to let the two drift again. --- FR --- Le dépôt en connaissait déjà quatre : pkgname, le bloc de build, les lignes _pick, les cibles make explicites. Il y en a un cinquième, et c'est le seul qui échoue en silence — le tableau depends= d'un AUTRE sous-paquet. --nodeps veut dire que makepkg ne vérifie jamais : gcc-libs s'est construit, a été accepté, et est entré dans le dépôt en déclarant une dépendance envers libhwasan, que cette architecture ne produit jamais. Rien n'a bronché. pacman, si, à la première tentative d'installation : :: unable to satisfy dependency 'libhwasan' required by gcc-libs C'était déjà payé une fois : un passage antérieur avait rencontré le piège avec libquadmath et élagué ce seul nom à la main. libhwasan a rejoint la liste des retraits ensuite, sans que l'élagage suive. Élaguer nom par nom était le vrai défaut. L'ensemble qui décide de ce qui n'est pas construit décide désormais aussi de ce dont on ne dépend pas, et une assertion interdit aux deux de diverger. Assisted-by: Claude Opus 5 --- patches/pkgbuild/gcc.sh | 65 +++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/patches/pkgbuild/gcc.sh b/patches/pkgbuild/gcc.sh index 44bcde5..42aad10 100755 --- a/patches/pkgbuild/gcc.sh +++ b/patches/pkgbuild/gcc.sh @@ -238,12 +238,59 @@ echo "gcc: front ends reduced, multilib off, lib32 removed" sed -i '0,/^build() {$/s//build() {\n export MAKEFLAGS="-j8"/' PKGBUILD grep -A1 '^build() {' PKGBUILD | head -2 | sed 's/^/ /' -# A depends= entry on libquadmath survives in another sub-package. Left in -# place, the built package would declare a dependency that can never be -# satisfied on this architecture -- harmless at build time with --nodeps, -# fatal at install time. The unused package_libquadmath() function can stay: -# makepkg never calls a function whose name is absent from pkgname. -sed -i "/^\s*libquadmath$/d" PKGBUILD -if sed -n "/^depends=(/,/^)/p" PKGBUILD | grep -q libquadmath; then - echo "gcc: libquadmath still declared as a dependency" >&2; exit 1 -fi +# THE FIFTH PLACE. The repository already knew a component is removed in four +# independent places -- pkgname, the build block, the _pick lines and the +# explicit make targets. There is a fifth: the depends= array of a DIFFERENT +# sub-package. +# +# It is the only one that fails silently. --nodeps means makepkg never checks, +# so the build succeeds and the package goes into the repository declaring a +# dependency on something this architecture will never produce. Nothing says a +# word until an install is attempted, which for a bootstrap is much later: +# +# :: unable to satisfy dependency 'libhwasan' required by gcc-libs +# +# This was already paid for once. A previous pass hit it with libquadmath and +# pruned that one name by hand; libhwasan was added to the drop set afterwards +# and the pruning was not extended, so gcc-libs shipped uninstallable. Pruning +# one name at a time is the bug, not the missing name. +# +# So the same `drop` set that decides what is NOT built now also decides what +# is not depended on, and the check below asserts it rather than trusting it. +# Adding a name to that set is now enough, in one place. +# +# Both spellings occur: a bare name in a sub-package's depends, and the +# versioned "libhwasan=$pkgver-$pkgrel" form in gcc's own. The unused +# package_libhwasan() function can stay -- makepkg never calls a function +# whose name is absent from pkgname. +python3 - <<'PY' +import io, re +drop = ["libhwasan", "libquadmath", "lib32-gcc-libs", + "libgm2", "libgo", "libgphobos", "libgcobol"] +s = io.open("PKGBUILD", encoding="utf-8").read() + +def prune(block): + out = [] + for ln in block.splitlines(True): + bare = ln.strip().strip('"\'') + name = bare.split("=")[0] + if name in drop and (bare == name or bare.startswith(name + "=")): + continue + out.append(ln) + return "".join(out) + +# Every depends array in the file: the top-level one and each sub-package's. +s = re.sub(r"(?<=depends=\()[^)]*(?=\))", lambda m: prune(m.group(0)), s) +io.open("PKGBUILD", "w", encoding="utf-8").write(s) + +# Assert, do not hope. Any dropped name still inside a depends array is a +# package we would ship unable to install. +left = [] +for m in re.finditer(r"depends=\(([^)]*)\)", s): + for ln in m.group(1).splitlines(): + bare = ln.strip().strip('"\'').split("=")[0] + if bare in drop: + left.append(bare) +assert not left, "gcc: dropped names still depended on: %s" % sorted(set(left)) +print("gcc: depends pruned of %d dropped components" % len(drop)) +PY