[FIX] one stray .a file broke every pkg-config lookup
libxslt reported configure: error: Package requirements (python-3.14) were not met: Package 'python-3.14' not found with python 3.14.7 installed and /usr/lib/pkgconfig/python-3.14.pc present. The chain, none of whose links resembles the others: binutils installs libiberty.a into /usr/lib64, because s390x's default MULTILIB_OSDIRNAME is lib64, creating that path as a REAL directory. meson chooses its default libdir by inspecting the system, and 64-bit plus a real /usr/lib64 means lib64 -- a symlink does not count, which is why Arch never sees this and arch-meson passes no --libdir at all. pkgconf is a meson package, so it installed there and COMPILED IN /usr/lib64/pkgconfig as its search path. Every .pc in the distribution is in /usr/lib/pkgconfig. Fixed at all three levels: binutils pinned to --libdir=/usr/lib, the chroot's arch-meson wrapper pins --libdir lib as a backstop, and the ARTEFACT check -- which said "no Debian multiarch libdir anywhere", truthfully and uselessly -- now also counts paths under usr/lib64. --- FR --- libxslt annonçait configure: error: Package requirements (python-3.14) were not met: Package 'python-3.14' not found avec python 3.14.7 installé et /usr/lib/pkgconfig/python-3.14.pc bien présent. La chaîne, dont aucun maillon ne ressemble aux autres : binutils dépose libiberty.a dans /usr/lib64, le MULTILIB_OSDIRNAME par défaut de s390x, et crée donc ce chemin comme VRAI répertoire. meson choisit son libdir par défaut en inspectant le système : 64 bits plus un vrai /usr/lib64 donne lib64 — un lien ne compte pas, d'où le fait qu'Arch ne voit jamais cela et qu'arch-meson ne passe aucun --libdir. pkgconf étant un paquet meson, il s'y est installé et a COMPILÉ /usr/lib64/pkgconfig comme chemin de recherche. Or tous les .pc de la distribution sont dans /usr/lib/pkgconfig. Corrigé aux trois niveaux : binutils épinglé à --libdir=/usr/lib, l'enveloppe arch-meson du chroot épingle --libdir lib en filet, et le test ARTEFACT — qui répondait « aucun libdir multiarch Debian », véridiquement et inutilement — compte désormais aussi les chemins sous usr/lib64. Assisted-by: Claude Opus 5
This commit is contained in:
parent
c164b59ca6
commit
f380f3fd66
3 changed files with 122 additions and 20 deletions
|
|
@ -1,16 +1,45 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# binutils: drop the gold linker.
|
# binutils: install into /usr/lib, not /usr/lib64.
|
||||||
#
|
#
|
||||||
# make[1]: *** [Makefile:6798: all-gold] Error 2
|
# THIS IS THE ROOT OF A CHAIN, and the chain is worth writing down because
|
||||||
|
# nothing in it looks related to anything else in it:
|
||||||
#
|
#
|
||||||
# gold is x86-centric, deprecated upstream since binutils 2.44, and it is not
|
# 1. On s390x, GCC's and binutils' default MULTILIB_OSDIRNAME is lib64, so
|
||||||
# built for s390x by any distribution that ships this architecture. Nothing
|
# binutils installs libiberty.a into /usr/lib64 -- creating that directory
|
||||||
# links with it here: ld.bfd is the linker on Z.
|
# as a REAL directory. On Arch, /usr/lib64 is a SYMLINK to lib.
|
||||||
|
# 2. meson chooses its default libdir by looking at the system: 64-bit plus a
|
||||||
|
# real /usr/lib64 means "lib64". A symlink does not count, which is why
|
||||||
|
# Arch never sees this and arch-meson passes no --libdir at all.
|
||||||
|
# 3. pkgconf is a meson package, so it installed into /usr/lib64 -- and
|
||||||
|
# COMPILED IN its search path as /usr/lib64/pkgconfig.
|
||||||
|
# 4. Every .pc file in the distribution is in /usr/lib/pkgconfig. So every
|
||||||
|
# pkg-config lookup inside the chroot failed. libxslt reported it as
|
||||||
#
|
#
|
||||||
# Dropped rather than debugged, because fixing gold for s390x would be work
|
# configure: error: Package requirements (python-3.14) were not met:
|
||||||
# spent on a component upstream is removing.
|
# Package 'python-3.14' not found
|
||||||
|
#
|
||||||
|
# with python 3.14.7 installed and /usr/lib/pkgconfig/python-3.14.pc
|
||||||
|
# sitting right there.
|
||||||
|
#
|
||||||
|
# Step 4 reads as a missing dependency. Step 1 is a linker library nobody
|
||||||
|
# thinks about. Fixing only the visible end -- pkgconf's search path -- would
|
||||||
|
# leave the real /usr/lib64 there, and the next meson package would land in it.
|
||||||
|
#
|
||||||
|
# --libdir is set explicitly rather than left to the target default, which is
|
||||||
|
# what Arch's layout means: one library directory, /usr/lib, with lib64 as a
|
||||||
|
# compatibility symlink.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
sed -i 's/--enable-gold[^ \\]*//' PKGBUILD
|
python3 - <<'ZZPY'
|
||||||
sed -i 's/^\(\s*\)--enable-gold.*$/\1--disable-gold \\/' PKGBUILD
|
import io, re
|
||||||
grep -q -- '--enable-gold' PKGBUILD && { echo "binutils: gold still enabled" >&2; exit 1; }
|
lines = io.open("PKGBUILD", encoding="utf-8").read().split("\n")
|
||||||
echo "binutils: gold linker disabled (deprecated upstream, absent on s390x)"
|
hit = [i for i, l in enumerate(lines) if re.search(r"/configure\b", l) and "#" not in l.split("/configure")[0]]
|
||||||
|
assert len(hit) == 1, "binutils: expected one configure call, got %d" % len(hit)
|
||||||
|
i = hit[0]
|
||||||
|
indent = re.match(r"^[ \t]*", lines[i]).group(0)
|
||||||
|
assert lines[i].rstrip().endswith("\\"), "binutils: configure does not continue"
|
||||||
|
lines.insert(i + 1, indent + " --libdir=/usr/lib \\")
|
||||||
|
io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(lines))
|
||||||
|
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)"
|
||||||
|
|
|
||||||
|
|
@ -164,9 +164,37 @@ EOF
|
||||||
# files directly, so --nodeps installs exactly these and not a resolved
|
# files directly, so --nodeps installs exactly these and not a resolved
|
||||||
# closure -- correct here, since stage 1 already supplied the closure just
|
# closure -- correct here, since stage 1 already supplied the closure just
|
||||||
# above.
|
# above.
|
||||||
|
# ONLY WHAT WAS ALREADY THERE. Restoring everything in repo2 fails:
|
||||||
|
#
|
||||||
|
# :: zlib-ng-compat-2.3.3-1 and zlib-1:1.3.2-3 are in conflict
|
||||||
|
# stage2: restoring stage-2 output failed
|
||||||
|
#
|
||||||
|
# Both are legitimate stage-2 output -- zlib-ng's PKGBUILD produces
|
||||||
|
# zlib-ng-compat, and zlib is its own package. A REPOSITORY holds both
|
||||||
|
# happily; an installed system cannot, because zlib-ng-compat replaces
|
||||||
|
# zlib. Stage 1 chose zlib for this chroot, and that choice is not stage
|
||||||
|
# 2's to revisit while it is rebuilding.
|
||||||
|
#
|
||||||
|
# So the filter is not a conflict list, which would need extending every
|
||||||
|
# time a package like this appeared. It is the intent stated exactly: put
|
||||||
|
# back the stage-2 build OF WHAT IS INSTALLED. A stage-2 package for
|
||||||
|
# something the chroot does not have was never part of this chroot, and
|
||||||
|
# installing it would quietly grow the build environment past what
|
||||||
|
# CHROOT_PKGS defines.
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
local back=("$REPO2"/*.pkg.tar.*)
|
local cand=("$REPO2"/*.pkg.tar.*)
|
||||||
shopt -u nullglob
|
shopt -u nullglob
|
||||||
|
local back=() inst f pn
|
||||||
|
if [ "${#cand[@]}" -gt 0 ]; then
|
||||||
|
inst=$(sudo pacman --root "$ROOT" --config "$CONF" -Qq 2>/dev/null)
|
||||||
|
for f in "${cand[@]}"; do
|
||||||
|
pn=$(bsdtar -xOf "$f" .PKGINFO 2>/dev/null | sed -n 's/^pkgname = //p')
|
||||||
|
[ -n "$pn" ] || continue
|
||||||
|
grep -qxF "$pn" <<< "$inst" && back+=("$f")
|
||||||
|
done
|
||||||
|
printf ' %s of %s stage-2 package(s) are installed here\n' \
|
||||||
|
"${#back[@]}" "${#cand[@]}"
|
||||||
|
fi
|
||||||
if [ "${#back[@]}" -gt 0 ]; then
|
if [ "${#back[@]}" -gt 0 ]; then
|
||||||
sudo pacman --root "$ROOT" --config "$CONF" --cachedir "$CACHE" \
|
sudo pacman --root "$ROOT" --config "$CONF" --cachedir "$CACHE" \
|
||||||
--noconfirm --nodeps -U "${back[@]}" \
|
--noconfirm --nodeps -U "${back[@]}" \
|
||||||
|
|
@ -302,10 +330,28 @@ EOC
|
||||||
sudo install -d -m0755 "$ROOT/usr/local/bin"
|
sudo install -d -m0755 "$ROOT/usr/local/bin"
|
||||||
sudo tee "$ROOT/usr/local/bin/arch-meson" > /dev/null <<'EOW'
|
sudo tee "$ROOT/usr/local/bin/arch-meson" > /dev/null <<'EOW'
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# stage 2: this chroot has none of Arch's optional documentation tools, so a
|
# stage 2, two overrides, both appended because meson honours the last
|
||||||
# feature that cannot be built should be skipped rather than fatal. Appended,
|
# occurrence of an option.
|
||||||
# because meson honours the last occurrence.
|
#
|
||||||
exec /usr/bin/arch-meson "$@" --auto-features auto
|
# --auto-features auto This chroot has none of Arch's optional documentation
|
||||||
|
# tools, so a feature that cannot be built should be
|
||||||
|
# skipped rather than fatal.
|
||||||
|
#
|
||||||
|
# --libdir lib meson picks its default libdir by inspecting the
|
||||||
|
# system: 64-bit plus a REAL /usr/lib64 means "lib64".
|
||||||
|
# On Arch /usr/lib64 is a symlink, so it never triggers
|
||||||
|
# and arch-meson passes no --libdir at all. In here
|
||||||
|
# binutils had created a real /usr/lib64 (s390x's
|
||||||
|
# default MULTILIB_OSDIRNAME), so meson flipped, pkgconf
|
||||||
|
# installed there, and pkgconf COMPILED IN
|
||||||
|
# /usr/lib64/pkgconfig as its search path -- while every
|
||||||
|
# .pc file in the distribution is in /usr/lib/pkgconfig.
|
||||||
|
# Result: every pkg-config lookup in the chroot failed,
|
||||||
|
# reported by libxslt as a missing python-3.14 that was
|
||||||
|
# installed. binutils is pinned too; this is the
|
||||||
|
# backstop, because the heuristic will fire again the
|
||||||
|
# moment anything else creates that directory.
|
||||||
|
exec /usr/bin/arch-meson "$@" --auto-features auto --libdir lib
|
||||||
EOW
|
EOW
|
||||||
sudo chmod 755 "$ROOT/usr/local/bin/arch-meson"
|
sudo chmod 755 "$ROOT/usr/local/bin/arch-meson"
|
||||||
printf ' arch-meson: wrapped with --auto-features auto\n'
|
printf ' arch-meson: wrapped with --auto-features auto\n'
|
||||||
|
|
@ -468,7 +514,18 @@ NOTE
|
||||||
# and Ubuntu ships 2.14.5. Ours is 2.15.3 and lives only in here, so this is
|
# and Ubuntu ships 2.14.5. Ours is 2.15.3 and lives only in here, so this is
|
||||||
# the only place libxslt can come from -- built by stage 2, not installed
|
# the only place libxslt can come from -- built by stage 2, not installed
|
||||||
# into it. It has to precede shadow, which the list order does not do.
|
# into it. It has to precede shadow, which the list order does not do.
|
||||||
STAGE2_FIRST=(texinfo libxslt)
|
#
|
||||||
|
# binutils, then pkgconf -- in that order, and both before anything that uses
|
||||||
|
# pkg-config. Stage 1's repository is clean of /usr/lib64; the stage-2
|
||||||
|
# binutils build created it, because s390x's default MULTILIB_OSDIRNAME is
|
||||||
|
# lib64. meson then chose lib64 as its default libdir (it inspects the system,
|
||||||
|
# and a REAL /usr/lib64 flips it -- Arch's is a symlink), pkgconf installed
|
||||||
|
# there, and pkgconf compiled in /usr/lib64/pkgconfig as its search path while
|
||||||
|
# every .pc in the distribution sits in /usr/lib/pkgconfig. Every pkg-config
|
||||||
|
# lookup in the chroot then failed. binutils first so the directory is gone
|
||||||
|
# before pkgconf builds; the arch-meson wrapper pins --libdir lib as the
|
||||||
|
# backstop.
|
||||||
|
STAGE2_FIRST=(texinfo binutils pkgconf libxslt)
|
||||||
|
|
||||||
STAGE2_SKIP_HOOKS=(libgcrypt git meson libarchive)
|
STAGE2_SKIP_HOOKS=(libgcrypt git meson libarchive)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,13 +96,29 @@ else
|
||||||
fi
|
fi
|
||||||
sudo rm -rf "$ROOT.probe"
|
sudo rm -rf "$ROOT.probe"
|
||||||
|
|
||||||
note "2. ARTEFACT -- host contamination that raises no error"
|
note "2. ARTEFACT -- wrong library directories, which raise no error"
|
||||||
|
# TWO wrong libdirs, not one.
|
||||||
|
#
|
||||||
|
# This check was written for Debian's multiarch layout, lib/s390x-linux-gnu,
|
||||||
|
# because that was the contamination stage 1 kept producing. It reported "no
|
||||||
|
# Debian multiarch libdir anywhere" while binutils and pkgconf were shipping
|
||||||
|
# files in /usr/lib64 -- true, and useless, because it was answering a narrower
|
||||||
|
# question than the one it appeared to answer.
|
||||||
|
#
|
||||||
|
# usr/lib64 matters for a reason that is not symmetry. On Arch it is a SYMLINK
|
||||||
|
# to lib; a package that ships it as a real directory changes what meson picks
|
||||||
|
# as its default libdir, which changed where pkgconf installed, which changed
|
||||||
|
# pkgconf's compiled-in search path, which broke every pkg-config lookup in the
|
||||||
|
# chroot. One stray .a file at the bottom of that.
|
||||||
n=0
|
n=0
|
||||||
for f in "$REPO"/*.pkg.tar.*; do
|
for f in "$REPO"/*.pkg.tar.*; do
|
||||||
c=$(bsdtar -tf "$f" 2>/dev/null | grep -c 's390x-linux-gnu/')
|
_l=$(bsdtar -tf "$f" 2>/dev/null)
|
||||||
|
c=$(grep -c 's390x-linux-gnu/' <<< "$_l")
|
||||||
[ "$c" -gt 0 ] && { bad "$(basename "$f"): $c multiarch paths"; n=$((n + 1)); }
|
[ "$c" -gt 0 ] && { bad "$(basename "$f"): $c multiarch paths"; n=$((n + 1)); }
|
||||||
|
c=$(grep -c '^usr/lib64/' <<< "$_l")
|
||||||
|
[ "$c" -gt 0 ] && { bad "$(basename "$f"): $c paths under usr/lib64"; n=$((n + 1)); }
|
||||||
done
|
done
|
||||||
[ "$n" -eq 0 ] && good "no Debian multiarch libdir anywhere"
|
[ "$n" -eq 0 ] && good "every library is under usr/lib -- no multiarch, no lib64"
|
||||||
|
|
||||||
note "3. SONAME -- what binaries ask for versus what the repository ships"
|
note "3. SONAME -- what binaries ask for versus what the repository ships"
|
||||||
# Two passes over the packages: collect the soname each shared library
|
# Two passes over the packages: collect the soname each shared library
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue