[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# Prove the repository, by installing it and running it.
|
|
|
|
|
#
|
|
|
|
|
# WHY THIS IS A SCRIPT AND NOT A PROCEDURE
|
|
|
|
|
#
|
|
|
|
|
# Sixty-eight successful builds said nothing that turned out to be true about
|
|
|
|
|
# whether the port worked. One chroot did -- it found the missing dynamic
|
|
|
|
|
# linker and the missing packages in a single run. That test was then done by
|
|
|
|
|
# hand, so it was not repeatable, and the next question ("is it still true?")
|
|
|
|
|
# had no cheap answer.
|
|
|
|
|
#
|
|
|
|
|
# It has one now. Three things are checked, and they fail for different
|
|
|
|
|
# reasons, so they are reported separately rather than as one verdict:
|
|
|
|
|
#
|
|
|
|
|
# 1. RESOLVE -- pacman's own dependency resolver, with --nodeps OFF. This
|
|
|
|
|
# is the check the bootstrap deliberately skips all the way
|
|
|
|
|
# through stage 1, so it is the first time anything asks
|
|
|
|
|
# whether the repository is internally complete.
|
|
|
|
|
# 2. ARTEFACT -- static audit of every package for host contamination that
|
|
|
|
|
# does not raise an error: Debian multiarch libdirs, files
|
|
|
|
|
# under /usr/local, binaries linked to libselinux.
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
# 3. SONAME -- every library any shipped binary ASKS for, minus every
|
|
|
|
|
# library the repository SHIPS. This is the check that reads
|
|
|
|
|
# binaries instead of declarations, and it is the only one
|
|
|
|
|
# that can see an under-declared dependency: kbd's loadkeys
|
|
|
|
|
# needed libxkbcommon.so.0 while kbd declared glibc, gzip
|
|
|
|
|
# and pam. RESOLVE was satisfied, the rootfs installed, and
|
|
|
|
|
# loadkeys could not start.
|
|
|
|
|
# 4. RUN -- chroot in and execute the binaries. The only check that
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
# can catch a missing ld.so, because a package whose
|
|
|
|
|
# interpreter is absent installs perfectly.
|
|
|
|
|
#
|
|
|
|
|
# Read-only with respect to repo/s390x. Wipes and rebuilds its own rootfs.
|
|
|
|
|
set -uo pipefail
|
|
|
|
|
|
|
|
|
|
WORK="${WORK:-$HOME/work/arch-s390x}"
|
|
|
|
|
REPO="${REPO:-$WORK/repo/s390x}"
|
|
|
|
|
ROOT="${ROOT:-$WORK/rootfs-test}"
|
|
|
|
|
CONF="$WORK/pacman-test.conf"
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
# A cache of its own, wiped every run.
|
|
|
|
|
#
|
|
|
|
|
# pacman's default cache is /var/cache/pacman/pkg, which is HOST-WIDE and
|
|
|
|
|
# survives between runs. A package rebuilt at the same pkgver-pkgrel -- which
|
|
|
|
|
# every fix in this port does -- leaves the old file there while core.db
|
|
|
|
|
# records the new checksum, and the next install stops on
|
|
|
|
|
#
|
|
|
|
|
# File .../coreutils-9.11-2-s390x.pkg.tar.gz is corrupted
|
|
|
|
|
# (invalid or corrupted package (checksum))
|
|
|
|
|
#
|
|
|
|
|
# which reads like a damaged build rather than a stale copy. The shared cache
|
|
|
|
|
# is also not this test's to empty: other work on this host uses it.
|
|
|
|
|
CACHE="$WORK/pacman-test.cache"
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
|
|
|
|
|
# The set a rootfs needs to reach a shell prompt and manage itself. filesystem
|
|
|
|
|
# is not optional and not obvious: its usr-merge symlinks are what create
|
|
|
|
|
# /lib/ld64.so.1, and without that path nothing starts at all -- the error is
|
|
|
|
|
# "chroot: No such file or directory" on a binary that is plainly there.
|
|
|
|
|
PKGS=(filesystem glibc bash coreutils tar sed grep findutils gawk pacman)
|
|
|
|
|
|
|
|
|
|
fail=0
|
|
|
|
|
note() { printf '\n== %s ==\n' "$*"; }
|
|
|
|
|
bad() { printf ' FAIL %s\n' "$*"; fail=$((fail + 1)); }
|
|
|
|
|
good() { printf ' ok %s\n' "$*"; }
|
|
|
|
|
|
|
|
|
|
note "Repository index"
|
|
|
|
|
[ -f "$REPO/core.db.tar.gz" ] || { bad "no core.db in $REPO"; exit 1; }
|
|
|
|
|
printf ' %s packages\n' "$(ls "$REPO"/*.pkg.tar.* 2>/dev/null | wc -l)"
|
|
|
|
|
|
|
|
|
|
cat > "$CONF" <<EOF
|
|
|
|
|
[options]
|
|
|
|
|
Architecture = s390x
|
|
|
|
|
SigLevel = Never
|
|
|
|
|
[core]
|
|
|
|
|
Server = file://$REPO
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
note "1. RESOLVE -- pacman's own dependency check, --nodeps OFF"
|
|
|
|
|
# -p prints what it would do and installs nothing. If the repository is
|
|
|
|
|
# incomplete, pacman names the missing package here, precisely, for free.
|
|
|
|
|
#
|
|
|
|
|
# The root and its dbpath must EXIST before alpm will initialise -- pacman
|
|
|
|
|
# reports that as "failed to resolve path ... passed to --root", which reads
|
|
|
|
|
# like a bad argument rather than a directory it declined to create.
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
sudo rm -rf "$ROOT.probe" "$CACHE"; sudo mkdir -p "$ROOT.probe/var/lib/pacman" "$CACHE"
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
# -Syp, not -Sp. A fresh dbpath has no sync database, and without -y pacman
|
|
|
|
|
# reports every package as "target not found" -- which reads like an empty
|
|
|
|
|
# repository rather than an unread index.
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
if sudo pacman --root "$ROOT.probe" --config "$CONF" --cachedir "$CACHE" \
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
--noconfirm -Syp "${PKGS[@]}" > "$WORK/resolve.txt" 2>&1; then
|
|
|
|
|
good "resolver satisfied ($(grep -c '^file://' "$WORK/resolve.txt") packages)"
|
|
|
|
|
else
|
|
|
|
|
bad "unresolved dependencies:"
|
|
|
|
|
grep -E "unable to satisfy|target not found" "$WORK/resolve.txt" \
|
|
|
|
|
| sed 's/.*dependency //; s/ required by.*//' | sort -u | tr '\n' ' ' \
|
|
|
|
|
| fold -sw 68 | sed 's/^/ /'
|
|
|
|
|
fi
|
|
|
|
|
sudo rm -rf "$ROOT.probe"
|
|
|
|
|
|
[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
2026-08-21 00:47:09 -04:00
|
|
|
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.
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
n=0
|
|
|
|
|
for f in "$REPO"/*.pkg.tar.*; do
|
[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
2026-08-21 00:47:09 -04:00
|
|
|
_l=$(bsdtar -tf "$f" 2>/dev/null)
|
|
|
|
|
c=$(grep -c 's390x-linux-gnu/' <<< "$_l")
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
[ "$c" -gt 0 ] && { bad "$(basename "$f"): $c multiarch paths"; n=$((n + 1)); }
|
[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
2026-08-21 00:47:09 -04:00
|
|
|
c=$(grep -c '^usr/lib64/' <<< "$_l")
|
|
|
|
|
[ "$c" -gt 0 ] && { bad "$(basename "$f"): $c paths under usr/lib64"; n=$((n + 1)); }
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
done
|
[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
2026-08-21 00:47:09 -04:00
|
|
|
[ "$n" -eq 0 ] && good "every library is under usr/lib -- no multiarch, no lib64"
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
note "3. SONAME -- what binaries ask for versus what the repository ships"
|
|
|
|
|
# Two passes over the packages: collect the soname each shared library
|
|
|
|
|
# DECLARES, and every soname each binary REQUESTS. The difference is a set of
|
|
|
|
|
# libraries that will be missing at runtime on the target.
|
|
|
|
|
#
|
|
|
|
|
# Most entries here are the ordinary stage-1 artefact -- the host's soname
|
|
|
|
|
# version rather than Arch's, e.g. libgpgme.so.11 where our gpgme package
|
|
|
|
|
# ships .45 -- and stage 2 resolves those by rebuilding inside the chroot.
|
|
|
|
|
# What must not be ignored is the other kind: a library no package in the
|
|
|
|
|
# repository provides at any version.
|
|
|
|
|
_sa=$(mktemp -d)
|
|
|
|
|
: > "$_sa/have"; : > "$_sa/want"
|
|
|
|
|
for f in "$REPO"/*.pkg.tar.*; do
|
|
|
|
|
rm -rf "$_sa/x"; mkdir -p "$_sa/x"
|
|
|
|
|
bsdtar -xf "$f" -C "$_sa/x" usr 2>/dev/null || continue
|
|
|
|
|
_pn=$(bsdtar -xOf "$f" .PKGINFO 2>/dev/null | sed -n 's/^pkgname = //p')
|
|
|
|
|
while IFS= read -r b; do
|
|
|
|
|
readelf -d "$b" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p' >> "$_sa/have"
|
|
|
|
|
readelf -d "$b" 2>/dev/null | sed -n 's/.*Shared library: \[\(.*\)\].*/\1/p' \
|
|
|
|
|
| sed "s|^|$_pn |" >> "$_sa/want"
|
|
|
|
|
done < <(find "$_sa/x" -type f 2>/dev/null)
|
[FIX] test-chroot: an audit that classifies, and one that was wrong
The soname check reported seventeen missing libraries. Four were false: it
built its "shipped" set from DT_SONAME alone, and tcl's libtcl9.0.so records
no SONAME at all. The file sits in usr/lib and ld.so resolves it by name, so
the check was calling a correct package broken -- which would have sent the
next reader hunting for a packaging bug that does not exist. Shipped filenames
and symlinks now count as supplied.
The remaining twelve needed separating, because an unclassified list is only
alarming. A missing soname whose library exists at a DIFFERENT version is
stage 1 working as designed: it linked the host, and stage 2 dissolves it. A
missing soname with no provider at any version is a closure gap. Nine and
three.
The three are each understood: pylibmount's cp313 extension (inert, no python
is shipped), makedb's libselinux (deliberate), and libtcl8.6 against our tcl
9.0 -- which is the honest cost of a decision made an hour before on closure
size without looking at ABI.
TODO.md records all twelve, with the note that stage 2 must install using the
host's pacman, because pacman inside the stage-1 rootfs cannot start.
--- FR ---
La vérification de sonames annonçait dix-sept bibliothèques manquantes. Quatre
étaient fausses : elle construisait son ensemble « livré » à partir du seul
DT_SONAME, et le libtcl9.0.so de tcl n'enregistre aucun SONAME. Le fichier est
dans usr/lib et ld.so le résout par son nom : la vérification déclarait donc
défectueux un paquet correct — de quoi envoyer le lecteur suivant chasser un
défaut d'empaquetage inexistant. Les noms de fichiers et les liens livrés
comptent désormais comme fournis.
Les douze restants demandaient d'être séparés, une liste non classée n'étant
qu'alarmante. Un soname manquant dont la bibliothèque existe à une AUTRE
version, c'est l'étage 1 fonctionnant comme prévu : il a lié l'hôte, et
l'étage 2 le dissout. Un soname sans aucun fournisseur est un trou de
fermeture. Neuf et trois.
Les trois sont compris : l'extension cp313 de pylibmount (inerte, aucun python
livré), le libselinux de makedb (délibéré), et libtcl8.6 contre notre tcl 9.0
— coût honnête d'une décision prise une heure plus tôt sur la taille de la
fermeture, sans regarder l'ABI.
TODO.md consigne les douze, avec la note que l'étage 2 devra installer avec le
pacman de l'hôte, celui du rootfs d'étage 1 ne pouvant pas démarrer.
Assisted-by: Claude Opus 5
2026-08-19 06:40:50 -04:00
|
|
|
# Shipped FILENAMES count as supplied, not only recorded SONAMEs. ld.so
|
|
|
|
|
# resolves a DT_NEEDED entry by looking for a file of that name, and a
|
|
|
|
|
# library is free to record no DT_SONAME at all -- tcl's libtcl9.0.so does
|
|
|
|
|
# exactly that. Counting only SONAMEs reported it as missing while the file
|
|
|
|
|
# sat in usr/lib, which would have sent the next reader hunting for a
|
|
|
|
|
# packaging bug that does not exist. Symlinks count too: they are what
|
|
|
|
|
# ld.so follows.
|
|
|
|
|
find "$_sa/x" \( -type f -o -type l \) -name '*.so*' -printf '%f\n' \
|
|
|
|
|
2>/dev/null >> "$_sa/have"
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
done
|
|
|
|
|
sort -u "$_sa/have" > "$_sa/have.s"
|
|
|
|
|
awk '{print $2}' "$_sa/want" | sort -u > "$_sa/want.s"
|
[FIX] test-chroot: an audit that classifies, and one that was wrong
The soname check reported seventeen missing libraries. Four were false: it
built its "shipped" set from DT_SONAME alone, and tcl's libtcl9.0.so records
no SONAME at all. The file sits in usr/lib and ld.so resolves it by name, so
the check was calling a correct package broken -- which would have sent the
next reader hunting for a packaging bug that does not exist. Shipped filenames
and symlinks now count as supplied.
The remaining twelve needed separating, because an unclassified list is only
alarming. A missing soname whose library exists at a DIFFERENT version is
stage 1 working as designed: it linked the host, and stage 2 dissolves it. A
missing soname with no provider at any version is a closure gap. Nine and
three.
The three are each understood: pylibmount's cp313 extension (inert, no python
is shipped), makedb's libselinux (deliberate), and libtcl8.6 against our tcl
9.0 -- which is the honest cost of a decision made an hour before on closure
size without looking at ABI.
TODO.md records all twelve, with the note that stage 2 must install using the
host's pacman, because pacman inside the stage-1 rootfs cannot start.
--- FR ---
La vérification de sonames annonçait dix-sept bibliothèques manquantes. Quatre
étaient fausses : elle construisait son ensemble « livré » à partir du seul
DT_SONAME, et le libtcl9.0.so de tcl n'enregistre aucun SONAME. Le fichier est
dans usr/lib et ld.so le résout par son nom : la vérification déclarait donc
défectueux un paquet correct — de quoi envoyer le lecteur suivant chasser un
défaut d'empaquetage inexistant. Les noms de fichiers et les liens livrés
comptent désormais comme fournis.
Les douze restants demandaient d'être séparés, une liste non classée n'étant
qu'alarmante. Un soname manquant dont la bibliothèque existe à une AUTRE
version, c'est l'étage 1 fonctionnant comme prévu : il a lié l'hôte, et
l'étage 2 le dissout. Un soname sans aucun fournisseur est un trou de
fermeture. Neuf et trois.
Les trois sont compris : l'extension cp313 de pylibmount (inerte, aucun python
livré), le libselinux de makedb (délibéré), et libtcl8.6 contre notre tcl 9.0
— coût honnête d'une décision prise une heure plus tôt sur la taille de la
fermeture, sans regarder l'ABI.
TODO.md consigne les douze, avec la note que l'étage 2 devra installer avec le
pacman de l'hôte, celui du rootfs d'étage 1 ne pouvant pas démarrer.
Assisted-by: Claude Opus 5
2026-08-19 06:40:50 -04:00
|
|
|
comm -13 "$_sa/have.s" "$_sa/want.s" > "$_sa/miss"
|
|
|
|
|
# CLASSIFY, because the two kinds need different work and an unclassified list
|
|
|
|
|
# is just alarming. A missing soname whose library exists in the repository at
|
|
|
|
|
# a DIFFERENT version is the ordinary stage-1 artefact: the binary linked the
|
|
|
|
|
# host's copy, and stage 2 dissolves it by rebuilding in the chroot. A missing
|
|
|
|
|
# soname with no provider at any version is a CLOSURE GAP -- a package that
|
|
|
|
|
# still has to be built, or a dependency nobody declared.
|
|
|
|
|
: > "$_sa/drift"; : > "$_sa/gap"
|
|
|
|
|
while read -r m; do
|
|
|
|
|
_base=${m%%.so*}
|
|
|
|
|
if grep -q "^${_base}\.so" "$_sa/have.s"; then
|
|
|
|
|
echo "$m" >> "$_sa/drift"
|
|
|
|
|
else
|
|
|
|
|
echo "$m" >> "$_sa/gap"
|
|
|
|
|
fi
|
|
|
|
|
done < "$_sa/miss"
|
|
|
|
|
_report() {
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
while read -r m; do
|
|
|
|
|
printf ' %-24s <- %s\n' "$m" \
|
|
|
|
|
"$(awk -v m="$m" '$2==m {print $1}' "$_sa/want" | sort -u | tr '\n' ' ')"
|
[FIX] test-chroot: an audit that classifies, and one that was wrong
The soname check reported seventeen missing libraries. Four were false: it
built its "shipped" set from DT_SONAME alone, and tcl's libtcl9.0.so records
no SONAME at all. The file sits in usr/lib and ld.so resolves it by name, so
the check was calling a correct package broken -- which would have sent the
next reader hunting for a packaging bug that does not exist. Shipped filenames
and symlinks now count as supplied.
The remaining twelve needed separating, because an unclassified list is only
alarming. A missing soname whose library exists at a DIFFERENT version is
stage 1 working as designed: it linked the host, and stage 2 dissolves it. A
missing soname with no provider at any version is a closure gap. Nine and
three.
The three are each understood: pylibmount's cp313 extension (inert, no python
is shipped), makedb's libselinux (deliberate), and libtcl8.6 against our tcl
9.0 -- which is the honest cost of a decision made an hour before on closure
size without looking at ABI.
TODO.md records all twelve, with the note that stage 2 must install using the
host's pacman, because pacman inside the stage-1 rootfs cannot start.
--- FR ---
La vérification de sonames annonçait dix-sept bibliothèques manquantes. Quatre
étaient fausses : elle construisait son ensemble « livré » à partir du seul
DT_SONAME, et le libtcl9.0.so de tcl n'enregistre aucun SONAME. Le fichier est
dans usr/lib et ld.so le résout par son nom : la vérification déclarait donc
défectueux un paquet correct — de quoi envoyer le lecteur suivant chasser un
défaut d'empaquetage inexistant. Les noms de fichiers et les liens livrés
comptent désormais comme fournis.
Les douze restants demandaient d'être séparés, une liste non classée n'étant
qu'alarmante. Un soname manquant dont la bibliothèque existe à une AUTRE
version, c'est l'étage 1 fonctionnant comme prévu : il a lié l'hôte, et
l'étage 2 le dissout. Un soname sans aucun fournisseur est un trou de
fermeture. Neuf et trois.
Les trois sont compris : l'extension cp313 de pylibmount (inerte, aucun python
livré), le libselinux de makedb (délibéré), et libtcl8.6 contre notre tcl 9.0
— coût honnête d'une décision prise une heure plus tôt sur la taille de la
fermeture, sans regarder l'ABI.
TODO.md consigne les douze, avec la note que l'étage 2 devra installer avec le
pacman de l'hôte, celui du rootfs d'étage 1 ne pouvant pas démarrer.
Assisted-by: Claude Opus 5
2026-08-19 06:40:50 -04:00
|
|
|
done < "$1"
|
|
|
|
|
}
|
|
|
|
|
if [ -s "$_sa/gap" ]; then
|
|
|
|
|
bad "$(wc -l < "$_sa/gap") soname(s) with NO provider at any version:"
|
|
|
|
|
_report "$_sa/gap"
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
else
|
[FIX] test-chroot: an audit that classifies, and one that was wrong
The soname check reported seventeen missing libraries. Four were false: it
built its "shipped" set from DT_SONAME alone, and tcl's libtcl9.0.so records
no SONAME at all. The file sits in usr/lib and ld.so resolves it by name, so
the check was calling a correct package broken -- which would have sent the
next reader hunting for a packaging bug that does not exist. Shipped filenames
and symlinks now count as supplied.
The remaining twelve needed separating, because an unclassified list is only
alarming. A missing soname whose library exists at a DIFFERENT version is
stage 1 working as designed: it linked the host, and stage 2 dissolves it. A
missing soname with no provider at any version is a closure gap. Nine and
three.
The three are each understood: pylibmount's cp313 extension (inert, no python
is shipped), makedb's libselinux (deliberate), and libtcl8.6 against our tcl
9.0 -- which is the honest cost of a decision made an hour before on closure
size without looking at ABI.
TODO.md records all twelve, with the note that stage 2 must install using the
host's pacman, because pacman inside the stage-1 rootfs cannot start.
--- FR ---
La vérification de sonames annonçait dix-sept bibliothèques manquantes. Quatre
étaient fausses : elle construisait son ensemble « livré » à partir du seul
DT_SONAME, et le libtcl9.0.so de tcl n'enregistre aucun SONAME. Le fichier est
dans usr/lib et ld.so le résout par son nom : la vérification déclarait donc
défectueux un paquet correct — de quoi envoyer le lecteur suivant chasser un
défaut d'empaquetage inexistant. Les noms de fichiers et les liens livrés
comptent désormais comme fournis.
Les douze restants demandaient d'être séparés, une liste non classée n'étant
qu'alarmante. Un soname manquant dont la bibliothèque existe à une AUTRE
version, c'est l'étage 1 fonctionnant comme prévu : il a lié l'hôte, et
l'étage 2 le dissout. Un soname sans aucun fournisseur est un trou de
fermeture. Neuf et trois.
Les trois sont compris : l'extension cp313 de pylibmount (inerte, aucun python
livré), le libselinux de makedb (délibéré), et libtcl8.6 contre notre tcl 9.0
— coût honnête d'une décision prise une heure plus tôt sur la taille de la
fermeture, sans regarder l'ABI.
TODO.md consigne les douze, avec la note que l'étage 2 devra installer avec le
pacman de l'hôte, celui du rootfs d'étage 1 ne pouvant pas démarrer.
Assisted-by: Claude Opus 5
2026-08-19 06:40:50 -04:00
|
|
|
good "every requested soname has a provider in the repository"
|
|
|
|
|
fi
|
|
|
|
|
if [ -s "$_sa/drift" ]; then
|
|
|
|
|
printf ' note %s soname(s) at the host version, provider present at another\n' \
|
|
|
|
|
"$(wc -l < "$_sa/drift")"
|
|
|
|
|
printf ' (stage-1 artefact by construction -- stage 2 rebuilds these)\n'
|
|
|
|
|
_report "$_sa/drift"
|
[ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.
Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.
One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.
Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.
--- FR ---
Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.
Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.
Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.
Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.
Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
|
|
|
fi
|
|
|
|
|
rm -rf "$_sa"
|
|
|
|
|
|
|
|
|
|
note "4. RUN -- install for real, then chroot"
|
|
|
|
|
sudo rm -rf "$ROOT" "$CACHE"; sudo mkdir -p "$ROOT/var/lib/pacman" "$CACHE"
|
|
|
|
|
if ! sudo pacman --root "$ROOT" --config "$CONF" --cachedir "$CACHE" \
|
|
|
|
|
--noconfirm -Sy "${PKGS[@]}" \
|
[ADD] test-chroot: the test that proved the port, made repeatable
Sixty-eight successful builds said nothing true about whether the port
worked. One chroot found the missing dynamic linker and the missing
packages in a single run -- and it was done by hand, so "is it still true?"
had no cheap answer.
Three checks, kept apart because they fail for different reasons. RESOLVE
runs pacman's own resolver with --nodeps OFF, the check the whole bootstrap
skips. ARTEFACT greps every package for host contamination that raises no
error. RUN installs for real and executes the binaries -- the only one that
can catch an absent ld.so, since a package whose interpreter is missing
installs perfectly.
It earned itself immediately. ARTEFACT is clean across all 86 packages, and
RESOLVE named the next milestone precisely: about forty packages are still
missing, from pcre2 and libxcrypt to python and perl.
--- FR ---
Soixante-huit compilations réussies n'ont rien dit de vrai sur le
fonctionnement du portage. Un seul chroot a trouvé l'interpréteur dynamique
absent et les paquets manquants — et il avait été fait à la main, si bien
que « est-ce toujours vrai ? » n'avait pas de réponse bon marché.
Trois vérifications, tenues séparées parce qu'elles échouent pour des
raisons différentes. RESOLVE lance le résolveur de pacman avec --nodeps
DÉSACTIVÉ, le contrôle que tout l'amorçage saute. ARTEFACT inspecte chaque
paquet pour les contaminations de l'hôte qui ne lèvent aucune erreur. RUN
installe pour de vrai et exécute les binaires — seul capable de détecter un
ld.so absent, puisqu'un paquet dont l'interpréteur manque s'installe
parfaitement.
Il s'est rentabilisé aussitôt. ARTEFACT est propre sur les 86 paquets, et
RESOLVE a nommé l'étape suivante avec précision : une quarantaine de paquets
manquent encore, de pcre2 et libxcrypt jusqu'à python et perl.
Assisted-by: Claude Opus 5
2026-08-17 02:37:46 -04:00
|
|
|
> "$WORK/install.txt" 2>&1; then
|
|
|
|
|
bad "install failed, see $WORK/install.txt"
|
|
|
|
|
tail -15 "$WORK/install.txt" | sed 's/^/ /'
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
good "installed $(sudo ls "$ROOT/var/lib/pacman/local" | wc -l) packages"
|
|
|
|
|
|
|
|
|
|
# Each command answers a different question, so each is reported on its own.
|
|
|
|
|
# `tar` and `find` are here because stage 2 runs makepkg inside this rootfs
|
|
|
|
|
# and makepkg calls both -- a failure here stops stage 2 before its first
|
|
|
|
|
# package, and would otherwise be discovered much further from its cause.
|
|
|
|
|
while read -r desc cmd; do
|
|
|
|
|
out=$(sudo chroot "$ROOT" /usr/bin/env -i PATH=/usr/bin sh -c "$cmd" 2>&1)
|
|
|
|
|
rc=$?
|
|
|
|
|
if [ "$rc" -eq 0 ]; then good "$desc: ${out%%$'\n'*}"
|
|
|
|
|
else bad "$desc: rc=$rc ${out%%$'\n'*}"; fi
|
|
|
|
|
done <<'CHECKS'
|
|
|
|
|
bash bash --version
|
|
|
|
|
arch uname -m
|
|
|
|
|
libc ldd --version
|
|
|
|
|
ls ls /usr/bin >/dev/null && echo listed
|
|
|
|
|
tar tar --version
|
|
|
|
|
find find /usr/bin -maxdepth 1 -name sh >/dev/null && echo searched
|
|
|
|
|
sed echo x | sed s/x/y/
|
|
|
|
|
pacman pacman --version
|
|
|
|
|
CHECKS
|
|
|
|
|
|
|
|
|
|
note "Verdict"
|
|
|
|
|
if [ "$fail" -eq 0 ]; then
|
|
|
|
|
echo " the repository resolves, is clean, and runs."
|
|
|
|
|
else
|
|
|
|
|
echo " $fail check(s) failed -- see above."
|
|
|
|
|
fi
|
|
|
|
|
exit "$fail"
|