Removing WITH_RUST=1 changed nothing -- cargo was still invoked:
CARGO target/release/libgitcore.a
/bin/sh: line 1: cargo: command not found
The Makefile reads `ifndef NO_RUST`, so Rust is built BY DEFAULT and the opt-out
is NO_RUST. WITH_RUST=1 sets a variable the Makefile never reads. Deleting it was
correct and insufficient, the worst combination: the hook reported success and the
build failed identically.
This is a stopgap, not a decision. Rust IS supportable here, and measured rather
than assumed: rust-1.90.0-s390x-unknown-linux-gnu.tar.xz answers 200, and the
host already carries rustc 1.85.1. The cost is llvm and clang, which Arch's rust
lists as makedepends -- large, not impossible.
It also cannot be avoided for long. ERPLibre's poetry.lock needs cryptography
46.0.5, jiter, orjson, pydantic-core and rpds-py, all of which build Rust from
source where no wheel exists -- and none exists for s390x.
--- FR ---
Retirer WITH_RUST=1 n'a rien changé — cargo était toujours appelé :
CARGO target/release/libgitcore.a
/bin/sh: line 1: cargo: command not found
Le Makefile dit `ifndef NO_RUST` : Rust est bâti PAR DÉFAUT et l'échappatoire est
NO_RUST. WITH_RUST=1 définit une variable que le Makefile ne lit jamais. La
supprimer était juste et insuffisant, la pire combinaison : le hook annonçait un
succès et la construction échouait à l'identique.
C'est un palliatif, pas une décision. Rust EST supportable ici, et mesuré plutôt
que supposé : rust-1.90.0-s390x-unknown-linux-gnu.tar.xz répond 200, et l'hôte
porte déjà rustc 1.85.1. Le coût est llvm et clang, que le rust d'Arch liste en
makedepends — lourd, pas impossible.
Et cela ne pourra pas être évité longtemps. Le poetry.lock d'ERPLibre exige
cryptography 46.0.5, jiter, orjson, pydantic-core et rpds-py, qui tous compilent
du Rust depuis les sources là où aucune roue n'existe — et il n'en existe pas pour
s390x.
Assisted-by: Claude Opus 5
nss failed with
/build/nss/PKGBUILD: line 55: ../certdata2pem.py: No such file or directory
on a file that was plainly there. makepkg links a PKGBUILD local source files
into srcdir, and having extracted on the HOST it wrote the host absolute path.
Inside the chroot that path does not exist; only /build does.
No such file or directory for an executable is usually its interpreter, which
sent the first guess to the shebang -- #!/usr/bin/python, with python, python3
and python3.14 all present. It was the script itself, reached through a link to
nowhere.
Only links under the work directory are repointed: a link to anywhere else was
not made by this mechanism and is not ours to redirect.
--- FR ---
nss echouait sur
/build/nss/PKGBUILD: line 55: ../certdata2pem.py: No such file or directory
pour un fichier bien present. makepkg lie les sources locales d un PKGBUILD dans
srcdir, et ayant extrait sur l HOTE il a ecrit le chemin absolu de l hote. Dans le
chroot ce chemin n existe pas ; seul /build existe.
No such file or directory pour un executable designe d ordinaire son interprete,
ce qui a envoye la premiere hypothese vers le shebang -- #!/usr/bin/python, avec
python, python3 et python3.14 tous presents. C etait le script lui-meme, atteint
par un lien vers nulle part.
Seuls les liens sous le repertoire de travail sont rediriges : un lien ailleurs n a
pas ete cree par ce mecanisme et ne nous appartient pas.
Assisted-by: Claude Opus 5
Emptying PROCESSEDEXAMPLEFILES_PS was not enough:
contrib/hdtbl/examples/mixed_pickles.roff:51: error: cannot open 'gnu.eps'
fatal error: PSPIC failed to include 'gnu.eps'
hdtbl renders its example tables to PostScript and one of them shows the GNU
logo. Rather than chase a third, the consumers were COUNTED: exactly two files
include it, doc/webpage.ms and mixed_pickles.roff. Both lists are emptied, and
the hook now fails loudly if a third ever appears -- so the next reader gets a
sentence instead of a PSPIC error.
Considered and rejected: supplying a placeholder gnu.eps. It would have ended the
whack-a-mole in one line, and it would have put a blank box where a logo belongs
in a document this port then ships. Not rendering the document at all is honest;
rendering it wrong is not.
--- FR ---
Vider PROCESSEDEXAMPLEFILES_PS ne suffisait pas :
contrib/hdtbl/examples/mixed_pickles.roff:51: error: cannot open 'gnu.eps'
fatal error: PSPIC failed to include 'gnu.eps'
hdtbl rend ses tables d'exemple en PostScript, et l'une montre le logo GNU.
Plutôt que d'en poursuivre un troisième, les consommateurs ont été COMPTÉS :
exactement deux fichiers l'incluent, doc/webpage.ms et mixed_pickles.roff. Les
deux listes sont vidées, et le hook échoue bruyamment si un troisième apparaît —
le prochain lecteur aura une phrase au lieu d'une erreur PSPIC.
Envisagé puis rejeté : fournir un gnu.eps de remplacement. Cela aurait clos la
poursuite en une ligne, et aurait mis un cadre vide là où un logo doit être, dans
un document que ce portage livre ensuite. Ne pas rendre le document est honnête ;
le rendre faux ne l'est pas.
Assisted-by: Claude Opus 5
p11-kit is the twelfth instance of removing a documentation build and leaving its
install: -D gtk_doc=false stopped the docs being made, and package() still ran
`_pick doc "$pkgdir"/usr/share/gtk-doc`. _pick is Arch's helper for moving a path
into a sub-package and it is as fatal on a missing path as a bare mv.
tpm2-tss had two obstacles and the first hid the second. Before autoconf-archive
existed it died on
configure.ac:139: error: undefined or overquoted macro: AC_MSG_WARN
naming a macro that exists -- an AX_* macro was missing, m4 quoting came apart,
and autoconf blamed the next thing it recognised. With the archive installed,
configure gets far enough to ask for cmocka, a C unit-test framework wanted only
for tests this pass does not run.
--- FR ---
p11-kit est la douzième occurrence du retrait d'une construction de documentation
sans son installation : -D gtk_doc=false a arrêté la production, et package()
exécutait toujours `_pick doc "$pkgdir"/usr/share/gtk-doc`. _pick est l'aide
d'Arch pour déplacer un chemin vers un sous-paquet, et elle est aussi fatale
qu'un mv nu sur un chemin absent.
tpm2-tss avait deux obstacles, et le premier masquait le second. Avant l'existence
d'autoconf-archive il mourait sur
configure.ac:139: error: undefined or overquoted macro: AC_MSG_WARN
nommant une macro qui existe — une macro AX_* manquait, la citation m4 s'est
défaite, et autoconf a accusé la chose suivante qu'il reconnaissait. L'archive
installée, configure va assez loin pour réclamer cmocka, cadre de tests unitaires
en C voulu seulement pour des tests que cette passe ne lance pas.
Assisted-by: Claude Opus 5
--disable-doc was added and doxygen still ran. The API reference sits behind its
own automake conditional, and the generated Makefile shows it plainly:
@COND_DOXYGEN_TRUE@$(top_builddir)/doc/api/index.html: ...
with the prefix stripped, so configure had set it true. Two conditionals in one
package: --disable-doc for the man pages, --disable-doxygen for the API
reference. This is the third documentation toolchain xz has asked for, after
po4a.
--disable-doxygen is NOT in configure's help text -- only --enable-doxygen is --
and it works anyway. That was checked rather than assumed: AC_ARG_ENABLE accepts
both forms, and `enable_doxygen` is a real variable the script tests. groff
taught the same lesson from the other side, where no such option existed and an
invented flag would have drawn a warning and changed nothing.
--- FR ---
--disable-doc avait été ajouté et doxygen tournait encore. La référence d'API est
derrière sa propre condition automake, et le Makefile généré le montre :
@COND_DOXYGEN_TRUE@$(top_builddir)/doc/api/index.html: ...
préfixe retiré, donc configure l'avait mise à vrai. Deux conditions dans un même
paquet : --disable-doc pour les pages de manuel, --disable-doxygen pour l'API.
Troisième chaîne de documentation que xz réclame, après po4a.
--disable-doxygen n'est PAS dans l'aide de configure — seul --enable-doxygen y
est — et fonctionne quand même. Cela a été vérifié plutôt que supposé :
AC_ARG_ENABLE accepte les deux formes, et `enable_doxygen` est une variable que
le script teste réellement. groff a enseigné la même leçon par l'autre bout, où
aucune option n'existait et où un drapeau inventé n'aurait tiré qu'un
avertissement sans rien changer.
Assisted-by: Claude Opus 5
pacman refused the rebuilt binutils:
binutils: <root>/usr/lib64 exists in filesystem (owned by filesystem)
binutils: <root>/usr/lib64/libiberty.a exists in filesystem
--libdir=/usr/lib was not enough. libiberty installs into
$(libdir)$(MULTIOSSUBDIR), and gcc reports ../lib64 for
-print-multi-os-directory on s390x. In the installed system that resolves
through the symlink filesystem now provides, so the file lands in /usr/lib --
but pkgdir has no symlink, so make creates a real pkg/usr/lib64/ and makepkg
records the literal path. The two fixes are not alternatives: the symlink is what
keeps meson and cmake choosing lib, and this moves the one file that still writes
through the multi-os subdirectory.
cmake is the eleventh instance of removing a documentation build and leaving its
cleanup: with Sphinx off there is no html, and the PKGBUILD deletes _sources from
it. rm -rf rather than deleted -- on a machine with Sphinx it is real.
The binutils hook also assumed package_binutils(). binutils is not a split
package; its own assertion caught that.
--- FR ---
pacman a refusé le binutils reconstruit :
binutils: <root>/usr/lib64 exists in filesystem (owned by filesystem)
binutils: <root>/usr/lib64/libiberty.a exists in filesystem
--libdir=/usr/lib ne suffisait pas. libiberty s'installe dans
$(libdir)$(MULTIOSSUBDIR), et gcc annonce ../lib64 pour
-print-multi-os-directory sur s390x. Dans le système installé cela se résout par
le lien que filesystem fournit désormais, donc le fichier atterrit dans
/usr/lib — mais pkgdir n'a pas de lien : make crée un vrai pkg/usr/lib64/ et
makepkg enregistre le chemin littéral. Les deux correctifs ne sont pas des
alternatives : le lien est ce qui fait choisir lib à meson et cmake, et celui-ci
déplace le seul fichier qui écrive encore par le sous-répertoire multi-os.
cmake est la onzième occurrence du retrait d'une documentation sans son nettoyage :
sans Sphinx il n'y a pas de html, et le PKGBUILD en supprime _sources. rm -rf
plutôt que supprimé — sur une machine dotée de Sphinx, il est réel.
Le hook binutils supposait aussi package_binutils(). binutils n'est pas un paquet
scindé ; sa propre assertion l'a arrêté.
Assisted-by: Claude Opus 5
from vcs_versioning import Configuration
ModuleNotFoundError: No module named vcs_versioning
setuptools-scm was split upstream and its own build imports the half that left.
The traceback runs through setuptools build_meta, so what the log showed for
several passes was
ERROR Backend subprocess exited when trying to invoke build_wheel
a backend complaint about a package that had been divided in two. Fifth Python
build-time package this port has had to add, after flit_core, setuptools,
poetry-core and hatchling.
--- FR ---
from vcs_versioning import Configuration
ModuleNotFoundError: No module named vcs_versioning
setuptools-scm a ete scinde en amont, et sa propre construction importe la moitie
partie. La trace passe par build_meta de setuptools : ce que le journal montrait
depuis plusieurs passes etait
ERROR Backend subprocess exited when trying to invoke build_wheel
une plainte de moteur au sujet d un paquet coupe en deux. Cinquieme paquet Python
de construction que ce portage doit ajouter, apres flit_core, setuptools,
poetry-core et hatchling.
Assisted-by: Claude Opus 5
The hook's guard reported "no tcl dir under usr/lib". What sqlite had created
instead was a directory literally named `zipfs:`
<pkgdir>/sqlite/zipfs:/lib/tcl/tcl_library/
The generated Makefile explains itself:
# TCLLIBDIR = where to install the tcl plugin. If this is empty, it
TCLLIBDIR = //zipfs:/lib/tcl/tcl_library/sqlite3.53.4
sqlite asks tcl where its library lives and installs the plugin beside it. In tcl
8.6 that was a real directory. tcl 9 ships its library INSIDE the executable, in
a zipfs mount, so the answer is a path only tcl can open -- and sqlite used it as
a filesystem path, creating a directory whose name contains a colon.
This is the deferred "libtcl8.6 versus our tcl 9.0" item in its final form: not a
version number to update but a change in what tcl considers a path. TCLLIBDIR now
points at a real directory, versioned from tclsh.
--- FR ---
Le garde du hook signalait « no tcl dir under usr/lib ». Ce que sqlite avait créé
était un répertoire littéralement nommé `zipfs:`
<pkgdir>/sqlite/zipfs:/lib/tcl/tcl_library/
Le Makefile généré s'explique lui-même :
# TCLLIBDIR = where to install the tcl plugin. If this is empty, it
TCLLIBDIR = //zipfs:/lib/tcl/tcl_library/sqlite3.53.4
sqlite demande à tcl où vit sa bibliothèque et installe le greffon à côté. En tcl
8.6 c'était un vrai répertoire. tcl 9 livre sa bibliothèque DANS l'exécutable, en
montage zipfs : la réponse est un chemin que seul tcl sait ouvrir, et sqlite l'a
traité comme un chemin de fichiers, créant un répertoire dont le nom contient
deux points.
C'est l'élément différé « libtcl8.6 contre notre tcl 9.0 » dans sa forme finale :
non pas un numéro de version à mettre à jour, mais un changement de ce que tcl
appelle un chemin. TCLLIBDIR vise désormais un vrai répertoire, sa version lue
depuis tclsh.
Assisted-by: Claude Opus 5
Emptying DOC_GNU_EPS stopped the GNU logo being built and left the document that
includes it:
doc/webpage.ms:45: error: cannot open gnu.eps
doc/webpage.ms:45: fatal error: PSPIC failed to include gnu.eps
Tenth time in this port, fourth of my own making. PROCESSEDEXAMPLEFILES_PS lists
webpage.ps and grnexmpl.ps, and the HTML variant directly above it is ALREADY
empty with its real value left as a comment -- groff configure empties that one
when the tools are missing. This does the same for PS, which is the decision
groff would have made had it checked.
--- FR ---
Vider DOC_GNU_EPS a empeche la construction du logo GNU et laisse en place le
document qui l inclut :
doc/webpage.ms:45: error: cannot open gnu.eps
doc/webpage.ms:45: fatal error: PSPIC failed to include gnu.eps
Dixieme fois dans ce portage, quatrieme de ma main. PROCESSEDEXAMPLEFILES_PS
liste webpage.ps et grnexmpl.ps, et la variante HTML juste au-dessus est DEJA
vide, sa vraie valeur laissee en commentaire — le configure de groff vide
celle-la quand les outils manquent. Ceci fait de meme pour PS : la decision que
groff aurait prise s il avait verifie.
Assisted-by: Claude Opus 5
Two install commands passed one --nodeps and looked like they were skipping
dependencies. pacman documents the difference: -d skips dependency VERSION
checks, -dd skips them entirely. So cython could not be installed --
warning: cannot resolve python-pygments, a dependency of cython
:: unable to satisfy dependency python-numpy required by cython
-- and the numbers matter. cython is wanted here only as a BUILD tool, for
libseccomp Python binding, while its declared RUNTIME dependencies are numpy and
pygments, and numpy brings BLAS and LAPACK. A single -d nearly bought a numerical
stack to compile one .pyx file.
The message named numpy and numpy was not the subject. The subject was a missing
letter d.
python-poetry-core joins the list: the fourth Python build backend needed here
after flit_core, setuptools and hatchling.
--- FR ---
Deux commandes d installation passaient un seul --nodeps et semblaient sauter les
dependances. pacman documente la difference : -d saute les controles de VERSION,
-dd les saute entierement. cython ne pouvait donc pas etre installe --
warning: cannot resolve python-pygments, a dependency of cython
:: unable to satisfy dependency python-numpy required by cython
-- et les chiffres comptent. cython n est voulu ici que comme OUTIL de
construction, pour la liaison Python de libseccomp, alors que ses dependances d
EXECUTION declarees sont numpy et pygments, et numpy tire BLAS et LAPACK. Un seul
-d a failli faire compiler une pile numerique pour un fichier .pyx.
Le message nommait numpy, et numpy n etait pas le sujet. Le sujet etait un d
manquant.
python-poetry-core rejoint la liste : quatrieme moteur de construction Python
necessaire ici, apres flit_core, setuptools et hatchling.
Assisted-by: Claude Opus 5
xz got past po4a and stopped on
../../../doxygen/update-doxygen: doxygen command not found
Two documentation toolchains in one package: po4a for the translated man pages,
doxygen for the liblzma API reference. --disable-doc is xz own switch, checked
present in configure before use.
libpsl stopped on
make: *** No rule to make target
/usr/share/publicsuffix/effective_tld_names.dat, needed by ...
publicsuffix-list is DATA. libpsl compiles the Public Suffix List into a lookup
table, so the list is an input to the build -- the first entry in this port whose
absence is neither a program nor a library, and it reads exactly like a broken
Makefile.
--- FR ---
xz a passe po4a et s est arrete sur
../../../doxygen/update-doxygen: doxygen command not found
Deux chaines de documentation dans un seul paquet : po4a pour les pages de manuel
traduites, doxygen pour la reference d API de liblzma. --disable-doc est son
propre interrupteur, verifie present dans configure avant usage.
libpsl s est arrete sur
make: *** No rule to make target
/usr/share/publicsuffix/effective_tld_names.dat, needed by ...
publicsuffix-list est une DONNEE. libpsl compile la Public Suffix List en table
de correspondance : la liste est une entree de la construction — premiere entree
de ce portage dont l absence n est ni un programme ni une bibliotheque, et elle se
lit exactement comme un Makefile casse.
Assisted-by: Claude Opus 5
CMake Error at Utilities/Sphinx/CMakeLists.txt:52 (message):
cmake builds its own manual and man pages with Sphinx, asked for by --sphinx-man
and --sphinx-html. python-sphinx is a large Python documentation stack and cmake
is wanted here as a build tool.
Both flags, and they are bootstrap arguments rather than -D options -- cmake
configures itself with its own script before it can run itself. Dropping one
leaves the other pulling Sphinx in and the error is identical, which is how a
half-fix looks like no fix.
--- FR ---
CMake Error at Utilities/Sphinx/CMakeLists.txt:52 (message):
cmake batit son propre manuel et ses pages de manuel avec Sphinx, reclames par
--sphinx-man et --sphinx-html. python-sphinx est une large pile de documentation
Python, et cmake est voulu ici comme outil de construction.
Les deux drapeaux, et ce sont des arguments d amorcage plutot que des options -D :
cmake se configure avec son propre script avant de pouvoir s executer lui-meme.
N en retirer qu un laisse l autre tirer Sphinx et l erreur est identique, ce qui
donne a une demi-correction l apparence d aucune.
Assisted-by: Claude Opus 5
This section was written twice, and the first version was wrong instructively.
gold would not link: s390.cc references gold::gold_error_at_location<32, true>,
and those instantiations exist only when a 32-bit s390 target is configured. The
PKGBUILD asked for --enable-targets=x86_64-pep, so the first fix translated that
to s390-linux-gnu -- the honest-looking equivalent. bfd's configure answered:
*** Specify --enable-obsolete to build it anyway.
*** Support will be REMOVED in the next major release of BINUTILS,
*** unless a maintainer comes forward.
32-bit s390 is obsolete in binutils. So gold cannot be built here without
enabling a target upstream has announced it is deleting -- and gold is itself
deprecated, with bfd ld already the default (--enable-ld=default). Turning on one
deprecated thing to build another is not a trade worth making.
gold is dropped and the extra target list keeps only bpf-unknown-none. What is
lost is /usr/bin/ld.gold, which nothing here invokes. Recorded rather than
hidden: the stage-2 binutils will not match Arch's file list, and this is why.
--- FR ---
Cette section a été écrite deux fois, et la première version se trompait de façon
instructive.
gold ne se liait pas : s390.cc référence gold::gold_error_at_location<32, true>,
instanciations qui n'existent que si une cible s390 32 bits est configurée. Le
PKGBUILD demandait --enable-targets=x86_64-pep, donc le premier correctif l'a
traduit en s390-linux-gnu — l'équivalent d'apparence honnête. Le configure de bfd
a répondu :
*** Specify --enable-obsolete to build it anyway.
*** Support will be REMOVED in the next major release of BINUTILS,
*** unless a maintainer comes forward.
Le s390 32 bits est obsolète dans binutils. gold ne peut donc pas être bâti ici
sans activer une cible dont l'amont annonce la suppression — et gold est lui-même
abandonné, ld de bfd étant déjà le défaut (--enable-ld=default). Activer un objet
déprécié pour en bâtir un autre n'est pas un échange qui vaille.
gold est retiré et la liste de cibles ne garde que bpf-unknown-none. Ce qui est
perdu est /usr/bin/ld.gold, que rien ici n'invoque. Consigné plutôt que masqué :
le binutils d'étage 2 ne correspondra pas à la liste de fichiers d'Arch, et voici
pourquoi.
Assisted-by: Claude Opus 5
python-jinja: ERROR Missing dependencies: flit_core<4
flit_core is installed and importable -- 4.0.2. jinja's pyproject.toml pins
flit_core<4, so build refuses before compiling anything. A new shape here, and
the mirror image of one already recorded: libxslt could not be built on the host
because Ubuntu's libxml2 was too OLD; this is our own package being too NEW for
another's ceiling. Both read as a missing dependency and neither is one.
--skip-dependency-check is what Arch's own python-packaging passes for the same
class of reason.
autoconf-archive: curl: (52) Empty reply from server
The tarball arrives fine from ftpmirror.gnu.org. What fails is one patch from
savannah's cgit /patch/?id= endpoint, which returns nothing while savannah's root
answers 302 -- measured on both, plus 200 and 2463 bytes from a git mirror for
the same commit hash. Asking a mirror for the SAME COMMIT changes where the bytes
come from, not which bytes they are.
Also: pkill -f "[c]url.*autoconf-arc" killed the shell running it, because the
pattern matched that shell's own command line. Fourth time in this port.
--- FR ---
python-jinja: ERROR Missing dependencies: flit_core<4
flit_core est installé et importable — 4.0.2. Le pyproject.toml de jinja épingle
flit_core<4 : build refuse avant de compiler. Forme nouvelle ici, et miroir d'une
déjà consignée : libxslt ne se bâtissait pas sur l'hôte car le libxml2 d'Ubuntu
était trop ANCIEN ; ici notre propre paquet est trop RÉCENT pour le plafond d'un
autre. Les deux se lisent comme une dépendance manquante, aucune ne l'est.
--skip-dependency-check est ce que passe le python-packaging d'Arch pour la même
raison.
autoconf-archive: curl: (52) Empty reply from server
L'archive arrive très bien de ftpmirror.gnu.org. Ce qui échoue est un correctif
tiré du point /patch/?id= de cgit chez savannah, qui ne renvoie rien alors que la
racine de savannah répond 302 — mesuré sur les deux, plus 200 et 2463 octets
depuis un miroir git pour le même commit. Demander le MÊME COMMIT à un miroir
change d'où viennent les octets, pas lesquels.
Aussi : pkill -f "[c]url.*autoconf-arc" a tué le shell qui l'exécutait, son motif
correspondant à la ligne de commande de ce shell. Quatrième fois dans ce portage.
Assisted-by: Claude Opus 5
libevent: mv: cannot stat '<pkgdir>/usr/share/doc': No such file or directory
pam: rm: cannot remove '.../Linux-PAM/*.pdf': No such file or directory
Both are hooks I wrote in this session, and both stopped a build in exactly the
way this port has documented eight times: the documentation build was disabled
and its install was left in place. Turning EVENT__DOXYGEN off does not stop
package() moving usr/share/doc into the libevent-doc split; -Ddocs=disabled does
not stop pam deleting PDFs it no longer produces.
fakeroot was the first one I made myself. This makes three, so the rule is worth
stating instead of rediscovering: after disabling documentation anywhere, search
package() for share/doc, man, and the split arrays before believing the hook is
finished.
pam's rm becomes tolerant rather than deleted -- on a machine with the DocBook
stack the PDFs are real, and the comment above the line says why they must go:
they are not reproducible.
--- FR ---
libevent: mv: cannot stat '<pkgdir>/usr/share/doc': No such file or directory
pam: rm: cannot remove '.../Linux-PAM/*.pdf': No such file or directory
Deux hooks que j'ai écrits dans cette session, et deux arrêts de construction de
la façon exacte que ce portage a documentée huit fois : la construction de la
documentation désactivée, son installation laissée en place. Éteindre
EVENT__DOXYGEN n'empêche pas package() de déplacer usr/share/doc vers le
sous-paquet libevent-doc ; -Ddocs=disabled n'empêche pas pam de supprimer des PDF
qu'il ne produit plus.
fakeroot fut le premier de ma main. Cela en fait trois : la règle mérite d'être
énoncée plutôt que redécouverte — après avoir désactivé une documentation,
chercher dans package() share/doc, man, et les tableaux de sous-paquets avant de
croire le hook terminé.
Le rm de pam devient tolérant plutôt que supprimé : sur une machine dotée de la
pile DocBook les PDF existent, et le commentaire au-dessus dit pourquoi ils
doivent partir — ils ne sont pas reproductibles.
Assisted-by: Claude Opus 5
Three gaps in the driver, all found by packages advancing to their next obstacle.
no checkout for python-jinja
Stage 2 could only rebuild what stage 1 had cloned -- wrong for every package
stage 2 builds and stage 1 cannot. libxslt was the first (Ubuntu's libxml2 is too
old to configure it), the Python set followed. They are named in
CHROOT_STAGE2_PKGS because only this stage can produce them, and this stage would
not fetch them. It clones now, pinned to upstream.lock.
error: problem setting DownloadUser 'alpm' (user does not exist)
The rebuilt pacman drops privileges for downloads to a user created by
sysusers.d, which `pacman --root` does not run -- the same reason the CA bundle
was never generated. Nothing in the chroot downloads anything.
:: zlib-ng-compat and zlib are in conflict
zlib-ng produces zlib-ng-compat, correct and belonging in repo2, uninstallable
beside the zlib this chroot uses. CHROOT_EXCLUDE already said so for populate;
the same list now applies to the per-package install.
--- FR ---
Trois lacunes du pilote, toutes révélées par des paquets parvenus à leur obstacle
suivant.
no checkout for python-jinja
L'étage 2 ne savait reconstruire que ce que l'étage 1 avait cloné — faux pour
tout paquet que l'étage 2 bâtit et que l'étage 1 ne peut pas. libxslt fut le
premier (le libxml2 d'Ubuntu est trop ancien), l'ensemble Python a suivi. Ils
figurent dans CHROOT_STAGE2_PKGS parce que seul cet étage les produit, et cet
étage refusait de les chercher. Il clone désormais, épinglé sur upstream.lock.
error: problem setting DownloadUser 'alpm' (user does not exist)
Le pacman reconstruit abaisse ses privilèges vers un utilisateur créé par
sysusers.d, que `pacman --root` n'exécute pas — la raison même pour laquelle le
faisceau de certificats n'était jamais généré. Rien ne télécharge dans ce chroot.
:: zlib-ng-compat et zlib sont en conflit
zlib-ng produit zlib-ng-compat, juste et à sa place dans repo2, ininstallable à
côté du zlib de ce chroot. CHROOT_EXCLUDE le disait déjà pour le peuplement ; la
même liste vaut maintenant pour l'installation par paquet.
Assisted-by: Claude Opus 5
meson.build:65:18: ERROR: Dependency "glib-2.0" not found
This was nearly a sub-project. glib2 is not in this port and adding it is not one
package: Arch glib2 wants gobject-introspection, which itself needs glib2 -- a
cycle to bootstrap -- plus libsysprof-capture, dconf and gi-docgen.
Reading where the requirement comes from changed the answer entirely. The file is
doc/manual/meson.build and the line is
glib_prefix = dependency("glib-2.0").get_variable(pkgconfig : "prefix")
glib is consulted to find where gtk-doc keeps its cross-reference files. It is
not linked, not called, and no p11-kit code touches it. -D gtk_doc=false drops
the subdirectory and the dependency with it. Six lines of context replaced
several packages and a dependency cycle.
--- FR ---
meson.build:65:18: ERROR: Dependency "glib-2.0" not found
C etait presque un sous-projet. glib2 n est pas dans ce portage et l ajouter n est
pas un paquet : le glib2 d Arch veut gobject-introspection, qui depend lui-meme de
glib2 -- un cycle a amorcer -- plus libsysprof-capture, dconf et gi-docgen.
Lire d ou vient reellement l exigence a change la reponse. Le fichier est
doc/manual/meson.build et la ligne est
glib_prefix = dependency("glib-2.0").get_variable(pkgconfig : "prefix")
glib est consulte pour trouver ou gtk-doc range ses references croisees. Il n est
ni lie, ni appele, et aucun code de p11-kit ne le touche. -D gtk_doc=false
supprime le sous-repertoire et la dependance avec lui. Six lignes de contexte ont
remplace plusieurs paquets et un cycle de dependances.
Assisted-by: Claude Opus 5
systemd generates source from jinja2 templates, and the Python set sits at the
end of packages.sh while systemd is in the middle. The list order is the runtime
closure, not the build order -- so the packages that must exist before another
one builds are named in STAGE2_FIRST rather than moved.
--- FR ---
systemd genere du code depuis des gabarits jinja2, et l ensemble Python figure en
fin de packages.sh quand systemd est au milieu. L ordre de la liste est la
fermeture d execution, pas celle de construction : les paquets qui doivent
exister avant qu un autre se batisse sont nommes dans STAGE2_FIRST plutot que
deplaces.
Assisted-by: Claude Opus 5
gnupg builds two architecture diagrams into its manual, one needing ImageMagick
and one transfig -- two toolchains for two pictures. --disable-doc is gnupg own
switch, verified present in configure before use.
The hook was written twice. The first version looked for a ./configure line
ending in a backslash and asserted its way out; gnupg uses an options ARRAY.
Both shapes appear in this port, so a hook has to read the file rather than
assume the house style.
systemd generates source from jinja2 templates and stops without it. Not
documentation this time -- the build cannot proceed.
--- FR ---
gnupg construit deux diagrammes dans son manuel, l un exigeant ImageMagick et
l autre transfig -- deux chaines d outils pour deux images. --disable-doc est son
propre interrupteur, verifie present dans configure avant usage.
Le hook a ete ecrit deux fois. La premiere version cherchait une ligne
./configure terminee par une contre-oblique et s est arretee sur son assertion ;
gnupg emploie un TABLEAU d options. Les deux formes existent dans ce portage : un
hook doit lire le fichier plutot que supposer le style maison.
systemd genere du code depuis des gabarits jinja2 et s arrete sans lui. Pas de la
documentation cette fois -- la construction ne peut pas avancer.
Assisted-by: Claude Opus 5
git and meson kept failing in stage 2 on exactly what their own hooks fix, while
the log said
hook skipped (stage-1 only)
Both were named in STAGE2_SKIP_HOOKS, correctly, when their whole content was a
host workaround: git dropped ZLIB_NG because the host had no zlib-ng headers,
meson moved a wheel out of /usr/local. Then each grew a second section that BOTH
stages need -- git's asciidoc man pages, meson's hotdoc reference manual -- and
the list skips the whole FILE, so the new sections never ran. Two hooks that were
by then two thirds relevant, silently ignored.
A list of filenames cannot say why a hook is listed, and cannot notice when that
reason stops covering the file. The hooks now read EL_STAGE and decide per
section, with the reason written beside each guard; the list is gone. libgcrypt
and libarchive keep a whole-file guard, which now states its reason instead of
being an entry somewhere else.
Verified at both stages: git drops its man pages in each, and keeps ZLIB_NG in
the chroot where zlib-ng exists.
--- FR ---
git et meson échouaient à l'étage 2 sur précisément ce que leurs propres hooks
corrigent, pendant que le journal disait
hook skipped (stage-1 only)
Tous deux étaient nommés dans STAGE2_SKIP_HOOKS, à juste titre quand tout leur
contenu était un contournement de l'hôte : git abandonnait ZLIB_NG faute
d'en-têtes zlib-ng, meson déplaçait une roue hors de /usr/local. Puis chacun a
gagné une seconde section utile aux DEUX étages — les pages asciidoc de git, le
manuel hotdoc de meson — et la liste saute le FICHIER entier : ces sections n'ont
jamais tourné. Deux hooks devenus pertinents aux deux tiers, ignorés en silence.
Une liste de noms de fichiers ne peut pas dire pourquoi un hook y figure, ni
remarquer que cette raison a cessé de couvrir le fichier. Les hooks lisent
désormais EL_STAGE et tranchent par section, la raison écrite à côté de chaque
garde ; la liste disparaît. libgcrypt et libarchive gardent une garde de fichier
entier, qui énonce sa raison au lieu d'être une entrée ailleurs.
Vérifié aux deux étages : git abandonne ses pages de manuel dans les deux, et
conserve ZLIB_NG dans le chroot, où zlib-ng existe.
Assisted-by: Claude Opus 5
Until now the honest description of this port was: it worked once, on one
machine. Every PKGBUILD comes from a `git clone --depth 1` of
gitlab.archlinux.org, and the 63 hooks assert exact strings -- deliberately, and
several have caught their own mistakes that way. But it means the port is written
against a moving target: someone starting over today gets what Arch has today,
not what these hooks were written against.
What closes that is not the 18 GB of build output -- regenerable packages, a
chroot wiped on every run, state files derived from the repository by design. It
is one commit per checkout: 155 lines. build_package now pins a fresh clone to
the locked commit, and says so when a package is NOT in the lock, because that is
how a lock quietly stops covering what it claims to.
RELAIS.md joins the repository, written without the build machine's alias,
address or account -- a successor needs the shape of the access, not its
coordinates. check-private.sh keeps it that way, and .env.example loses its
literal account name. Three of its patterns had to go on their first runs: they
flagged a systemd unit template, upstream maintainer headers, the localhost lines
of a generated /etc/hosts, and its own explanatory comment. A check that fails on
correct files is one somebody stops running.
--- FR ---
Jusqu'ici la description honnête de ce portage était : il a fonctionné une fois,
sur une machine. Chaque PKGBUILD vient d'un `git clone --depth 1` de
gitlab.archlinux.org, et les 63 hooks affirment des chaînes exactes — à dessein,
et plusieurs y ont attrapé leurs propres erreurs. Mais le portage est donc écrit
contre une cible mouvante : qui recommence aujourd'hui obtient l'Arch du jour.
Ce qui comble ce trou n'est pas les 18 Go de production — paquets régénérables,
chroot effacé à chaque passage, registres dérivés du dépôt par conception. C'est
un commit par arbre : 155 lignes. build_package épingle un nouveau clone sur le
commit verrouillé, et le DIT quand un paquet n'y figure pas, car c'est ainsi qu'un
verrou cesse discrètement de couvrir ce qu'il prétend.
RELAIS.md entre dans le dépôt, écrit sans l'alias, l'adresse ni le compte de la
machine — un successeur a besoin de la forme de l'accès, pas de ses coordonnées.
check-private.sh l'y maintient, et .env.example perd son nom de compte littéral.
Trois de ses motifs ont dû partir dès les premiers passages : ils signalaient un
gabarit d'unité systemd, des en-têtes de mainteneurs amont, les lignes localhost
d'un /etc/hosts généré, et son propre commentaire explicatif. Un contrôle qui
échoue sur des fichiers justes est un contrôle qu'on cesse de lancer.
Assisted-by: Claude Opus 5
gpgme is the one worth reading. It failed while BUILDING, not testing:
make[3]: Entering directory '.../gpgme/tests/gpg'
gpgconf: error running '/usr/bin/gpg-connect-agent': exit status 1
EL_NOCHECK skips check(), but `make all` still descends into tests/gpg and sets
up a throwaway GNUPGHOME, which means starting an agent -- and the chroot has no
dbus, no session and no tty. Third time this port has found that "no tests" and
"no test harness" are different requests.
groff needs xpmtoppm from netpbm to draw the GNU logo for its own manual. There
is no configure switch: groff has neither --without-doc nor --disable-doc, so
inventing a flag would have failed identically while the hook's check passed --
autoconf only warns about options it does not know. The generated Makefile's
DOC_GNU_EPS is emptied instead, and the verification runs inside build(), where
the generated file actually exists.
--- FR ---
gpgme mérite lecture. Il échouait en CONSTRUISANT, pas en testant :
make[3]: Entering directory '.../gpgme/tests/gpg'
gpgconf: error running '/usr/bin/gpg-connect-agent': exit status 1
EL_NOCHECK saute check(), mais `make all` descend quand même dans tests/gpg et
met en place un GNUPGHOME jetable, donc démarre un agent — or le chroot n'a ni
dbus, ni session, ni terminal. Troisième fois que ce portage constate que « pas
de tests » et « pas de harnais de test » sont deux demandes différentes.
groff a besoin de xpmtoppm, de netpbm, pour dessiner le logo GNU de son propre
manuel. Aucun interrupteur n'existe : ni --without-doc ni --disable-doc, donc
inventer un drapeau aurait échoué à l'identique pendant que le contrôle du hook
passait — autoconf ne fait qu'avertir des options qu'il ignore. La variable
DOC_GNU_EPS du Makefile généré est vidée, et la vérification tourne dans build(),
là où le fichier généré existe.
Assisted-by: Claude Opus 5
libaio is a real closure gap: lvm2 stops on "libaio.h: No such file or
directory". This port had already met that library from the other side, noting
Ubuntu's time64 rename to libaio.so.1t64 long before anything needed its headers.
fakeroot is the interesting one. The first hook removed the po4a call and nothing
else, so build() ended on a bare `cd doc` and package() failed on
install: cannot stat './faked.1': No such file or directory
The English man pages ARE shipped. What is not shipped are the translations:
doc/Makefile carries SUBDIRS = de es fr nl pt ro sv, each holding only Makefiles
whose man_MANS name files po4a was supposed to generate. Removing the generator
and leaving the recursion is the same mistake as removing a build target and
leaving its install target.
shadow needs distinguishing: xsltproc exists here now, from our libxslt. What is
missing is the DocBook XML data its stylesheets read -- the same as pam.
--- FR ---
libaio est un vrai trou de fermeture : lvm2 s'arrête sur « libaio.h: No such file
or directory ». Ce portage avait déjà croisé cette bibliothèque par l'autre bout,
en notant le renommage time64 d'Ubuntu en libaio.so.1t64 bien avant que ses
en-têtes servent.
fakeroot est le cas intéressant. Le premier hook retirait l'appel à po4a et rien
d'autre : build() finissait sur un `cd doc` nu et package() échouait sur
install: cannot stat './faked.1': No such file or directory
Les pages anglaises SONT livrées. Ce qui ne l'est pas, ce sont les traductions :
doc/Makefile porte SUBDIRS = de es fr nl pt ro sv, chacun ne contenant que des
Makefiles dont man_MANS nomme des fichiers que po4a devait générer. Retirer le
générateur en laissant la récursion est la même erreur que retirer une cible de
construction en laissant celle d'installation.
shadow mérite une distinction : xsltproc existe désormais, via notre libxslt. Ce
qui manque, ce sont les données DocBook que lisent ses feuilles de style — comme
pour pam.
Assisted-by: Claude Opus 5
gold failed to link with
s390.cc: undefined reference to `void gold::gold_error_at_location<32, true>'
Its s390 target file compiles code for both s390 and s390x and references
<32, true> instantiations, which exist only when a 32-bit s390 target is
configured. The PKGBUILD asks for --enable-targets=x86_64-pep,bpf-unknown-none.
x86_64-pep is the PE+ target for x86_64: it means nothing here, and on x86_64 it
is what happens to bring in the 32-bit instantiations gold's target files want.
So this was never a gold bug -- it is the -march=x86-64 story one layer further
in. s390-linux-gnu is the honest translation of that line.
gcc now compiles, Fortran front end included, and stopped in package_gcc() on
libstdc++'s doxygen man pages -- two places, build and install, the eighth time
this port has met that shape.
--- FR ---
gold ne se liait pas :
s390.cc: undefined reference to `void gold::gold_error_at_location<32, true>'
Son fichier de cible s390 compile pour s390 et s390x et référence des
instanciations <32, true>, qui n'existent que si une cible s390 32 bits est
configurée. Le PKGBUILD demande --enable-targets=x86_64-pep,bpf-unknown-none.
x86_64-pep est la cible PE+ d'x86_64 : elle ne veut rien dire ici, et sur x86_64
c'est elle qui amène par hasard les instanciations 32 bits que gold réclame. Ce
n'était donc pas un défaut de gold — c'est l'histoire du -march=x86-64 une couche
plus loin. s390-linux-gnu est la traduction honnête de cette ligne.
gcc compile désormais, front-end Fortran compris, et s'arrêtait dans
package_gcc() sur les pages de manuel doxygen de libstdc++ — deux endroits,
construction et installation, huitième fois que ce portage rencontre cette forme.
Assisted-by: Claude Opus 5
sqlite is the deferred item this port had written down long ago -- "libtcl8.6
versus our tcl 9.0" -- arriving as a missing directory:
mv: cannot stat '<pkgdir>/usr/lib/tcl8.6/sqlite*': No such file or directory
The version is read from the tree rather than written in, because the tcl package
decides it and hardcoding 9.0 puts the same trap back one release later.
The first attempt guarded with a blanket `grep tcl8.6` and condemned correct
code: the existing section of that hook names tcl8.6 on purpose, because it is
about the HOST's tcl. It also substituted $_tcldir into that older section,
before the variable was defined. The guard caught both.
util-linux is the seventh package to fail on a path at the end of package() after
a compile that worked. libpsl's error names its own fix.
--- FR ---
sqlite est l'élément différé que ce portage avait noté depuis longtemps —
« libtcl8.6 contre notre tcl 9.0 » — arrivant sous la forme d'un répertoire
absent :
mv: cannot stat '<pkgdir>/usr/lib/tcl8.6/sqlite*': No such file or directory
La version est lue dans l'arbre plutôt qu'écrite en dur, parce que c'est le
paquet tcl qui la décide et qu'inscrire 9.0 remettrait le même piège une version
plus tard.
La première tentative gardait par un `grep tcl8.6` global et condamnait du code
juste : la section existante de ce hook nomme tcl8.6 exprès, car elle traite du
tcl de l'HÔTE. Elle avait aussi injecté $_tcldir dans cette section antérieure,
avant que la variable soit définie. Le garde a attrapé les deux.
util-linux est le septième paquet à échouer sur un chemin en fin de package()
après une compilation réussie. L'erreur de libpsl nomme son propre correctif.
Assisted-by: Claude Opus 5
gcc failed at stage 2 with
gfortran: error: unrecognized argument in option '-march=x86-64'
configure: error: GNU Fortran is not working; please report a bug ...
Worth reading twice: gcc reported that its OWN freshly-built Fortran compiler was
not working, when the compiler was fine and had been handed another
architecture's flags. Everything about the message points at the wrong thing.
Arch splits makepkg.conf into /etc/makepkg.conf.d/*.conf, read AFTER the main
file. fortran.conf sets FFLAGS to the x86_64 list and FCFLAGS from it; rust.conf
does the same for RUSTFLAGS. So the override appended to makepkg.conf was itself
overridden -- silently, and only for the variables it did not mention. CFLAGS
survived by luck: no drop-in sets it.
Every flag variable now lives in a drop-in named to sort last, and the run prints
which drop-ins are still read after it. A drop-in that does not sort last does
nothing and looks like it worked.
--- FR ---
gcc a échoué à l'étage 2 sur
gfortran: error: unrecognized argument in option '-march=x86-64'
configure: error: GNU Fortran is not working; please report a bug ...
À lire deux fois : gcc annonçait que SON PROPRE compilateur Fortran fraîchement
bâti ne fonctionnait pas, alors qu'il allait bien et qu'on lui avait passé les
drapeaux d'une autre architecture. Tout dans le message désigne la mauvaise chose.
Arch éclate makepkg.conf en /etc/makepkg.conf.d/*.conf, lus APRÈS le fichier
principal. fortran.conf met FFLAGS à la liste x86_64 et FCFLAGS d'après lui ;
rust.conf fait de même pour RUSTFLAGS. Le remplacement ajouté en fin de
makepkg.conf était donc lui-même écrasé — silencieusement, et seulement pour les
variables qu'il ne nommait pas. CFLAGS a survécu par chance : aucun appoint ne le
définit.
Toutes les variables de drapeaux vivent maintenant dans un appoint nommé pour
passer en dernier, et la construction affiche quels appoints sont encore lus
après lui. Un appoint qui ne passe pas en dernier ne fait rien et en a l'air.
Assisted-by: Claude Opus 5
nlohmann-json is a real closure gap, not a documentation cut: both cmake and
cppdap stop on "Could NOT find nlohmann_json". It is a header-only C++ library,
one of the cheapest packages in the list, and cmake is not optional -- the
cmake/cppdap/jsoncpp/libuv group behind it is what several other packages build
with.
The other three are doxygen and sphinx again. jsoncpp's is the least readable
failure in the port so far: doxybuild.py is handed an empty doxygen path and
raises Exception('path is empty.'), so a missing tool arrives as a Python
traceback about a path.
libuv needed two places -- `make man -C docs` and the install of
docs/build/man/libuv.1 -- the same shape as libxml2's docs split and pam's PDFs:
a failure on a path at the end of package(), after a compile that worked.
--- FR ---
nlohmann-json est un vrai trou de fermeture, pas une coupe de documentation :
cmake et cppdap s'arrêtent tous deux sur « Could NOT find nlohmann_json ». C'est
une bibliothèque C++ d'en-têtes seuls, l'un des paquets les moins chers de la
liste, et cmake n'est pas optionnel — le groupe cmake/cppdap/jsoncpp/libuv
derrière lui est ce avec quoi plusieurs autres se bâtissent.
Les trois autres sont encore doxygen et sphinx. Celui de jsoncpp est l'échec le
moins lisible du portage jusqu'ici : doxybuild.py reçoit un chemin de doxygen
vide et lève Exception('path is empty.'), donc un outil manquant arrive sous la
forme d'une trace Python parlant d'un chemin.
libuv demandait deux endroits — `make man -C docs` et l'installation de
docs/build/man/libuv.1 — même forme que le découpage de libxml2 et les PDF de
pam : un échec sur un chemin en fin de package(), après une compilation réussie.
Assisted-by: Claude Opus 5
lib/crypt-gost-yescrypt.c:134:16: error: initialization discards 'const'
qualifier from pointer target type
A warning, promoted by libxcrypt's own -Werror. Our gcc is 16.2.1 and libxcrypt
4.5.2 was released against considerably older ones; the same code warns the same
way on x86_64 with the same compiler, so this says nothing about s390x.
--disable-werror is libxcrypt's own switch. Patching the source would mean
carrying a diff against upstream C for a const-correctness nit in an
implementation of a Russian hash standard nothing here uses. Declining to treat
warnings as errors is what a distribution does when its compiler is ahead of a
release.
Both configure calls: libxcrypt is built twice, once for the obsolete-API compat
library. Fixing only the first leaves the second failing identically, which reads
as if the flag had done nothing.
--- FR ---
lib/crypt-gost-yescrypt.c:134:16: error: initialization discards 'const'
qualifier from pointer target type
Un avertissement, promu par le -Werror de libxcrypt lui-même. Notre gcc est en
16.2.1 et libxcrypt 4.5.2 est sorti face à bien plus anciens ; le même code
avertit de la même façon sur x86_64 avec le même compilateur — cela ne dit rien
de s390x.
--disable-werror est l'interrupteur de libxcrypt. Corriger la source
supposerait de porter un correctif contre du C amont pour une vétille de
const-correction dans une implémentation d'une norme de hachage russe dont rien
ici ne se sert. Refuser de traiter les avertissements en erreurs est ce que fait
une distribution quand son compilateur devance une version.
Les deux appels à configure : libxcrypt est bâti deux fois, dont une pour la
bibliothèque de compatibilité. Ne corriger que le premier laisse le second
échouer à l'identique, ce qui se lit comme un drapeau sans effet.
Assisted-by: Claude Opus 5
git, xz, meson and pam. Each uses the project's own switch where one exists.
git is the one worth reading: `man` appears as a make target twice and
`install-man` twice, once each for git proper and once for contrib/subtree.
Removing the build targets and leaving the install targets gives "No rule to
make target 'install-man'", which reads like a broken Makefile. Four places,
again.
pam is different in kind from the others: xmllint EXISTS here, from our own
libxml2. It fails because pam validates its DocBook sources against DTDs that
are not installed and --nonet forbids fetching them. Shipping the DocBook XML
data would be a package; disabling the documentation is a flag.
--- FR ---
git, xz, meson et pam. Chacun par l'interrupteur du projet lui-même, quand il
existe.
git mérite lecture : `man` figure deux fois comme cible make et `install-man`
deux fois, une paire pour git et une pour contrib/subtree. Retirer les cibles de
construction en laissant celles d'installation donne « No rule to make target
'install-man' », ce qui se lit comme un Makefile cassé. Quatre endroits, encore.
pam diffère en nature : xmllint EXISTE ici, il vient de notre libxml2. Il échoue
parce que pam valide ses sources DocBook contre des DTD non installées, et que
--nonet interdit de les chercher. Livrer les données DocBook serait un paquet ;
désactiver la documentation est un drapeau.
Assisted-by: Claude Opus 5
CHROOT_PKGS grew one name at a time, each added because a build asked for it. It
reached 151 of the 190 packages stage 1 had produced, and the absent ones broke
builds without ever being named:
openldap: configure: error: --enable_argon2=yes requires --with-argon2
while the PKGBUILD already passes --with-argon2=libsodium and libsodium sat in
repo/s390x, simply not installed. configure looked for a library, did not find
it, and reported a missing OPTION. krb5's "libldap not found", libsasl's "Could
not locate OpenLDAP", lvm2's "libudev >= 143" and audit's undefined SASL symbol
are the same sentence in different words.
Stage 2 builds with --nodeps, so nothing installs a build dependency for it.
Dropping --nodeps would need a working in-chroot pacman, and that pacman is one
of the packages being rebuilt. So: install the distribution we have. Four names
out of 190 cannot coexist -- two of them only visible to a real install, since
-Syp says nothing about file conflicts. 187 packages installed, no fallback.
--- FR ---
CHROOT_PKGS a grandi un nom à la fois, chacun ajouté parce qu'une construction le
demandait. Il atteignait 151 des 190 paquets produits par l'étage 1, et les
absents cassaient des constructions sans jamais être nommés :
openldap: configure: error: --enable_argon2=yes requires --with-argon2
alors que le PKGBUILD passe déjà --with-argon2=libsodium et que libsodium était
dans repo/s390x, simplement pas installé. configure cherchait une bibliothèque,
ne la trouvait pas, et signalait une OPTION manquante. Le « libldap not found »
de krb5, le « Could not locate OpenLDAP » de libsasl, le « libudev >= 143 » de
lvm2 et le symbole SASL indéfini d'audit sont la même phrase autrement dite.
L'étage 2 bâtit avec --nodeps : rien n'installe de dépendance de compilation pour
lui. Y renoncer exigerait un pacman fonctionnel dans le chroot, et ce pacman est
l'un des paquets à rebâtir. Donc : installer la distribution que nous avons.
Quatre noms sur 190 ne peuvent coexister — dont deux visibles seulement à
l'installation réelle, -Syp ne disant rien des conflits de fichiers. 187 paquets
installés, aucun repli.
Assisted-by: Claude Opus 5
Two more documentation-and-toolchain cuts, both using the project's own switch.
systemd asked for libbpf, which this port does not package -- and packaging it
means clang and llvm, an entire second compiler toolchain for unit features
nothing here uses yet. pacman asked for asciidoc, the same Python documentation
stack already declined for doxygen, asciidoctor and a2x.
pacman is worth naming out loud: it is the package manager, so its man pages are
the ones a user reaches for first. This is the most visible of the documentation
cuts and the strongest single argument for restoring them at stage 3.
--- FR ---
Deux coupes de plus, documentation et chaîne d'outils, chacune par l'interrupteur
prévu par le projet lui-même.
systemd réclamait libbpf, que ce portage ne paquette pas — et le paqueter suppose
clang et llvm, soit une seconde chaîne de compilation entière pour des fonctions
d'unité dont rien ici ne se sert encore. pacman réclamait asciidoc, la même pile
Python déjà écartée pour doxygen, asciidoctor et a2x.
pacman mérite d'être nommé : c'est le gestionnaire de paquets, donc ses pages de
manuel sont les premières qu'un utilisateur cherche. C'est la plus visible de ces
coupes, et le meilleur argument pour les restaurer à l'étage 3.
Assisted-by: Claude Opus 5
Four packages failed in prepare() on
Failed to clone 'gl-mod/bootstrap' a second time, aborting
The first diagnosis was DNS, and it was right: the chroot had no resolv.conf.
Copying it made resolution work -- `getent hosts github.com` answers -- and the
clones still failed, now on
error adding trust anchors from file: /etc/ssl/certs/ca-certificates.crt
Everything needed was already installed: the symlink, the Mozilla trust source,
update-ca-trust, p11-kit's trust. What was missing is that the bundle they
produce is made by an ALPM HOOK, and `pacman --root` does not run hooks. So the
target of that symlink never existed, and a package list cannot tell a dangling
symlink from a working installation.
Generated from our own trust source, not copied from the host, and counted
rather than trusted: update-ca-trust exits 0 on an empty source, and what that
hides is an https failure hours later. 121 certificates; the clone works.
--- FR ---
Quatre paquets ont échoué dans prepare() sur
Failed to clone 'gl-mod/bootstrap' a second time, aborting
Le premier diagnostic était le DNS, et il était juste : le chroot n'avait pas de
resolv.conf. Le copier a rétabli la résolution — `getent hosts github.com`
répond — et les clones échouaient toujours, désormais sur
error adding trust anchors from file: /etc/ssl/certs/ca-certificates.crt
Tout le nécessaire était installé : le lien, la source de confiance Mozilla,
update-ca-trust, le trust de p11-kit. Ce qui manquait, c'est que le faisceau
qu'ils produisent est fabriqué par un hook ALPM, et `pacman --root` n'exécute pas
les hooks. La cible du lien n'a donc jamais existé, et une liste de paquets ne
distingue pas un lien mort d'une installation valide.
Généré depuis notre propre source de confiance, non copié de l'hôte, et compté
plutôt que cru : update-ca-trust sort en 0 sur une source vide, et ce que cela
masque est un échec https des heures plus tard. 121 certificats ; le clone passe.
Assisted-by: Claude Opus 5
The PGO fix broke the build it was meant to repair:
/build/binutils/PKGBUILD: line 107: --enable-plugins: command not found
The line it commented out ended in a backslash. A comment inside a
backslash-continued command does not comment out an option -- it breaks the
continuation, and the next option becomes a command of its own. This port had
already documented the mirror image, where commenting the FIRST line of a
multi-line assignment leaves the continuations live; same fact, other side.
The line is deleted now, and nothing is put in its place: any comment inside the
./configure invocation would break it again. The explanation belongs in the hook.
Also removed from that hook: a check ending in `|| true`, which passes always. A
guard that cannot fail is worse than no guard, because it reads like
verification.
--- FR ---
Le correctif PGO a cassé la construction qu'il devait réparer :
/build/binutils/PKGBUILD: line 107: --enable-plugins: command not found
La ligne commentée finissait par une contre-oblique. Un commentaire dans une
commande continuée ne supprime pas une option — il brise la continuation, et
l'option suivante devient une commande. Ce portage avait déjà documenté l'image
inverse, où commenter la PREMIÈRE ligne d'une affectation multiligne laisse les
continuations actives ; même fait, autre face.
La ligne est désormais supprimée, et rien ne la remplace : tout commentaire dans
l'appel à ./configure le briserait de nouveau. L'explication appartient au hook.
Retiré aussi de ce hook : un contrôle finissant par `|| true`, donc toujours
satisfait. Une garde incapable d'échouer est pire qu'aucune garde, car elle se
lit comme une vérification.
Assisted-by: Claude Opus 5
python-build, python-wheel and python-pyproject-hooks were built on the host,
reported OK, and installed everything under usr/lib/python3/dist-packages --
Debian's name for site-packages. Our python 3.14 never looks there, so every
module in them was unreachable. Nothing about them looked wrong.
Their package() computes install paths from the RUNNING python:
local site_packages=$(python -c "import site; print(site.getsitepackages()[0])")
rm "$pkgdir/$site_packages/$_name"/*.exe
which is why the other three in the same batch FAILED -- on `rm` finding
nothing. Those failures were protective. All six are built by stage 2 now, where
python is ours; a stage-1 run is expected to report them as failed, like libxslt.
The ARTEFACT check said the repository was clean throughout, truthfully: it only
ever asked about C library directories. It now also counts dist-packages and
usr/local paths, so the next time this happens it says so.
--- FR ---
python-build, python-wheel et python-pyproject-hooks ont été bâtis sur l'hôte,
déclarés OK, et ont tout installé sous usr/lib/python3/dist-packages — le nom
Debian de site-packages. Notre python 3.14 n'y regarde jamais : chaque module
était inatteignable. Rien en eux n'avait l'air faux.
Leur package() calcule les chemins depuis le python COURANT :
local site_packages=$(python -c "import site; print(site.getsitepackages()[0])")
rm "$pkgdir/$site_packages/$_name"/*.exe
d'où l'échec des trois autres du même lot — sur un `rm` qui ne trouvait rien. Ces
échecs étaient protecteurs. Les six sont désormais bâtis par l'étage 2, où le
python est le nôtre ; une passe d'étage 1 doit les déclarer en échec, comme
libxslt.
Le test ARTEFACT affirmait un dépôt propre, véridiquement : il n'interrogeait que
les répertoires de bibliothèques C. Il compte maintenant aussi dist-packages et
usr/local, pour le dire la prochaine fois.
Assisted-by: Claude Opus 5
Three stage-2 builds -- brotli, libseccomp, meson -- stopped on
/usr/bin/python: No module named build
and building python-build means running `python -m build`. Its dependencies are
the same cycle: packaging and pyproject-hooks are flit_core-backed, installing a
wheel wants python-installer, and none of the six exist yet.
On the host the cycle was already broken -- apt had python3-build -- so stage 1
never met it. Breaking it there again is not possible: apt has no
python3-flit-core at all, so the backend all six need cannot be installed on the
host by any means.
Arch had already solved it, in the PKGBUILDs: `_bootstrap=1` selects a vendored
builder that needs none of the six. That is upstream's supported path through
exactly this situation, and it replaced a half-written alternative here -- three
bespoke hooks calling `python -m flit_core.wheel` and unzipping into $pkgdir --
which would have reimplemented what the PKGBUILD already does properly.
--- FR ---
Trois constructions d'étage 2 — brotli, libseccomp, meson — se sont arrêtées sur
/usr/bin/python: No module named build
et bâtir python-build suppose d'exécuter `python -m build`. Ses dépendances sont
le même cycle : packaging et pyproject-hooks passent par flit_core, installer une
roue demande python-installer, et aucun des six n'existe encore.
Sur l'hôte le cycle était déjà rompu — apt fournissait python3-build — donc
l'étage 1 ne l'a jamais rencontré. Le rompre à nouveau là est impossible : apt
n'a aucun python3-flit-core, donc le moteur dont les six ont besoin ne peut être
installé sur l'hôte par aucun moyen.
Arch l'avait déjà résolu, dans les PKGBUILD : `_bootstrap=1` sélectionne un
constructeur embarqué qui n'a besoin d'aucun des six. C'est la voie prévue en
amont pour exactement cette situation, et elle a remplacé une solution
à demi écrite ici — trois hooks sur mesure appelant `python -m flit_core.wheel`
puis dézippant dans $pkgdir — qui aurait réimplémenté ce que le PKGBUILD fait
déjà correctement.
Assisted-by: Claude Opus 5
Four packages -- m4, libtool, groff, libnghttp2 -- failed in prepare() on
fatal: unable to access 'https://github.com/...': Could not resolve host
Failed to clone 'gl-mod/bootstrap' a second time, aborting
Arch takes its sources from git and these fetch gnulib as a submodule, so a
chroot with no resolv.conf cannot start the build at all. The retry line is what
makepkg prints; the reason sits one line above it.
Six more stopped on wget, which links libnettle.so.8 -- Ubuntu's soname, where
ours is .9. Our gnutls is already a stage-2 package and correctly wants .9; wget
was the last thing holding the old one, and gnulib's bootstrap fetches
translation catalogues WITH wget, so the tool it needed to fix itself was itself.
It joins libxml2 in STAGE2_HOST_EXTRACT: the host, which has a working wget, runs
prepare(); the chroot compiles.
Also fixed: my own ca-certificates hook left build() containing nothing but a
comment, which bash reports as a syntax error on the closing brace.
--- FR ---
Quatre paquets — m4, libtool, groff, libnghttp2 — ont échoué dans prepare() sur
fatal: unable to access 'https://github.com/...': Could not resolve host
Failed to clone 'gl-mod/bootstrap' a second time, aborting
Arch tire ses sources de git et ceux-là récupèrent gnulib en sous-module : un
chroot sans resolv.conf ne peut pas même commencer. La ligne de reprise est ce
qu'affiche makepkg ; la raison est juste au-dessus.
Six autres se sont arrêtés sur wget, qui lie libnettle.so.8 — le soname
d'Ubuntu, quand le nôtre est .9. Notre gnutls est déjà un paquet d'étage 2 et
demande bien .9 ; wget était le dernier à retenir l'ancien, et le bootstrap de
gnulib récupère les catalogues de traduction AVEC wget : l'outil dont il avait
besoin pour se réparer était lui-même. Il rejoint libxml2 dans
STAGE2_HOST_EXTRACT — l'hôte, qui a un wget valide, exécute prepare() ; le chroot
compile.
Corrigé aussi : mon propre hook ca-certificates laissait build() avec un seul
commentaire, ce que bash signale comme une erreur de syntaxe sur l'accolade.
Assisted-by: Claude Opus 5
Built at stage 1, failed at stage 2, in gold:
<artificial>:(.text+0xc44e): undefined reference to
`void gold::gold_error_at_location<32, true>(...)'
`<artificial>` and the .ltrans object names are LTO's, and it does not come from
makepkg -- the chroot carries !lto with an empty LTOFLAGS. It comes from the
PKGBUILD: --enable-pgo-build=lto. gold's explicitly-instantiated templates do
not survive it here. Stage 1 got away with it because the host's GCC did the
work; stage 2 uses ours, at -O2 -march=z13 where stage 1 passed no flags.
PGO and LTO are build-time optimisations: what changes is how long binutils
takes to compile and how fast the linker runs, not what it can do. The
alternatives were removing gold, a linker Arch ships, or debugging LTO template
instantiation in a linker upstream has deprecated.
The first attempt at this hook looked for --with-build-config=bootstrap-lto,
which is in gcc's PKGBUILD, not binutils'. Its own assertion caught it.
--- FR ---
Bâti à l'étage 1, échoué à l'étage 2, dans gold :
<artificial>:(.text+0xc44e): undefined reference to
`void gold::gold_error_at_location<32, true>(...)'
`<artificial>` et les noms d'objets .ltrans sont ceux du LTO, et il ne vient pas
de makepkg — le chroot porte !lto avec un LTOFLAGS vide. Il vient du PKGBUILD :
--enable-pgo-build=lto. Les gabarits explicitement instanciés de gold n'y
survivent pas. L'étage 1 s'en tirait car le GCC de l'hôte faisait le travail ;
l'étage 2 utilise le nôtre, à -O2 -march=z13 là où l'étage 1 ne passait rien.
PGO et LTO sont des optimisations de construction : ce qui change, c'est la durée
de compilation et la vitesse du lieur, pas ce qu'il sait faire. Les options
étaient de retirer gold, un lieur qu'Arch livre, ou de déboguer une instanciation
de gabarit sous LTO dans un lieur abandonné en amont.
La première version de ce hook cherchait --with-build-config=bootstrap-lto, qui
est dans le PKGBUILD de gcc, pas de binutils. Sa propre assertion l'a arrêtée.
Assisted-by: Claude Opus 5
39 of 39 packages failed on the same line:
bsdtar: error while loading shared libraries: libicuuc.so.76
libarchive is in STAGE2_SKIP_HOOKS, so stage 2 rebuilt it as Arch does -- with
xar, linking whatever libxml2 was installed at that moment: the stage-1 one,
which wants the host's ICU 76 while ours ships 78. bsdtar is what makepkg uses
to extract sources and write packages, so nothing could come out, including
libxml2 itself. The stage-1 fix does not reach in here.
No new mechanism was needed. libarchive is dropped from stage2.state, so the
restore falls back to the stage-1 build that has no xar and therefore no libxml2
at all; libxml2 is hoisted and rebuilt against our icu; libarchive is rebuilt
later with xar, against a libxml2 whose ICU now agrees. Verified: bsdtar 3.8.9
runs, and libxml2 is the first OK of the pass.
The libgpgme.so.11 errors in five logs were noise -- makepkg carries on past a
failed .BUILDINFO. Reading the FIRST error in a log had attributed five failures
to the wrong cause; the last error before the abort is the one that matters.
--- FR ---
39 paquets sur 39 ont échoué sur la même ligne :
bsdtar: error while loading shared libraries: libicuuc.so.76
libarchive figure dans STAGE2_SKIP_HOOKS : l'étage 2 l'a donc rebâti comme le
fait Arch — avec xar, contre le libxml2 installé à cet instant, celui de
l'étage 1, qui veut l'ICU 76 de l'hôte quand le nôtre livre la 78. bsdtar est ce
dont makepkg se sert pour extraire et pour écrire les paquets : plus rien ne
sortait, libxml2 compris. Le correctif d'étage 1 n'atteint pas l'intérieur.
Aucun mécanisme nouveau. libarchive quitte stage2.state, donc la restauration
retombe sur la construction d'étage 1, sans xar et donc sans libxml2 ; libxml2
est hissé et rebâti contre notre icu ; libarchive est rebâti plus tard avec xar,
contre un libxml2 dont l'ICU concorde. Vérifié : bsdtar 3.8.9 démarre, et
libxml2 est le premier OK de la passe.
Les erreurs libgpgme.so.11 de cinq journaux étaient du bruit — makepkg poursuit
après un .BUILDINFO manqué. Lire la PREMIÈRE erreur d'un journal avait attribué
cinq échecs à la mauvaise cause ; c'est la dernière avant l'abandon qui compte.
Assisted-by: Claude Opus 5
Removing a name from stage2.state means its stage-2 artefact is not trusted --
that is the whole meaning of removing it. The restore ignored that and put the
package back anyway, undoing the fix that motivated the removal before the
rebuild could run.
It happened twice. binutils had to be moved out of repo2 by hand. filesystem
was worse because it was invisible: its pass-one build predates the hook adding
s390x's lib64 symlinks, so restoring it REMOVED the symlink stage 1 had just
installed. /usr/lib64 was absent again and the fix looked like it had failed.
pkgbase, not pkgname: stage2.state records what was built, and libxml2-docs is
not in it under that name.
The diagnosis also took a wrong turn worth recording. `test -L` failing was
reported as "a real directory", but it fails just as readily on a path that does
not exist -- which was the actual state. The check now says what the path IS.
--- FR ---
Retirer un nom de stage2.state signifie que son artefact d'étage 2 n'est plus de
confiance — c'est tout le sens du retrait. La restauration l'ignorait et le
réinstallait quand même, défaisant le correctif qui avait motivé le retrait avant
que la reconstruction puisse tourner.
Deux fois. binutils a dû être écarté de repo2 à la main. filesystem était pire
car invisible : sa construction de la passe 1 précède le hook ajoutant les liens
lib64 de s390x, donc le restaurer SUPPRIMAIT le lien que l'étage 1 venait de
poser. /usr/lib64 disparaissait et le correctif semblait inopérant.
pkgbase, pas pkgname : stage2.state enregistre ce qui a été bâti, et
libxml2-docs n'y figure pas sous ce nom.
Le diagnostic a aussi pris un mauvais chemin qui mérite d'être noté. L'échec de
`test -L` était rapporté comme « vrai répertoire », alors qu'il échoue tout
autant sur un chemin absent — l'état réel. Le test dit maintenant ce que le
chemin EST.
Assisted-by: Claude Opus 5
Arch creates them for one architecture:
[[ $CARCH = 'x86_64' ]] && {
symlinks["lib64"]="usr/lib"
symlinks["usr/lib64"]="lib"
}
Correct for Arch, and the root of the pkg-config failure fixed in the previous
commit -- which was fixed one build system at a time, and this is the one place
it belongs. s390x's toolchain reports ../lib64 for -print-multi-os-directory,
and libiberty installs into $(libdir)$(MULTIOSSUBDIR). With no symlink there,
one static library CREATES /usr/lib64 as a real directory, and meson's default
libdir test is `isdir and not islink`.
With the symlink, /usr/lib/../lib64 resolves to /usr/lib and the test sees a
link. Verified: the package now ships both, and pkgconf rebuilt with zero paths
under usr/lib64.
Not an invention -- it is Arch's own model, one library directory with lib64 as
compatibility. Ubuntu s390x has no /usr/lib64 at all, which is why nothing on
the host ever hinted at this.
--- FR ---
Arch ne les crée que pour une architecture :
[[ $CARCH = 'x86_64' ]] && {
symlinks["lib64"]="usr/lib"
symlinks["usr/lib64"]="lib"
}
Juste pour Arch, et racine de la panne pkg-config corrigée au commit précédent
— corrigée un système de construction à la fois, alors que voici le seul endroit
qui lui revient. La chaîne s390x annonce ../lib64 pour
-print-multi-os-directory, et libiberty s'installe dans $(libdir)$(MULTIOSSUBDIR).
Sans lien, une seule bibliothèque statique CRÉE /usr/lib64 en vrai répertoire,
et le test de meson est « isdir et non islink ».
Avec le lien, /usr/lib/../lib64 se résout vers /usr/lib et le test voit un lien.
Vérifié : le paquet livre les deux, et pkgconf rebâti n'a plus aucun chemin sous
usr/lib64.
Rien d'inventé : c'est le modèle d'Arch lui-même, un seul répertoire de
bibliothèques avec lib64 en compatibilité. Ubuntu s390x n'a pas de /usr/lib64
du tout, d'où l'absence de tout indice sur l'hôte.
Assisted-by: Claude Opus 5
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
Stage-2 pass two never reached its first package:
unable to satisfy dependency 'perl-locale-gettext' required by help2man
stage2: populate failed
help2man had built cleanly the moment before. Stage 1 builds with --nodeps, so
a successful build says nothing about whether the repository is complete -- and
this is the failure that says it out loud, by refusing to assemble the chroot.
Asked the resolver for the whole closure rather than fixing one name and trying
again: pacman stops at the first unsatisfiable dependency, so the count matters
more than the first line. One gap, then 148 packages resolved with --nodeps off,
up from 101 before the tools went in.
--- FR ---
La deuxième passe de l'étage 2 n'a jamais atteint son premier paquet :
unable to satisfy dependency 'perl-locale-gettext' required by help2man
stage2: populate failed
help2man venait de se bâtir sans une erreur. L'étage 1 bâtit avec --nodeps :
une construction réussie ne dit rien de la complétude du dépôt — et voici
l'échec qui le dit tout haut, en refusant d'assembler le chroot.
Le résolveur a été interrogé sur toute la fermeture, plutôt que de corriger un
nom et de réessayer : pacman s'arrête au premier manque, donc le compte importe
plus que la première ligne. Un seul trou, puis 148 paquets résolus avec --nodeps
éteint, contre 101 avant l'ajout des outils.
Assisted-by: Claude Opus 5
Six built on the host. libxslt will not: its configure demands libxml2 2.15.1
and Ubuntu ships 2.14.5. Ours is 2.15.3 and exists only inside the stage-2
chroot, so that chroot is the only place libxslt can come from -- built BY
stage 2 rather than installed into it, and hoisted so it precedes shadow, which
died on `xsltproc is missing`.
That is a shape worth naming: a package the host cannot build because the host
is behind. Not contamination and not a closure gap -- the wrong machine.
Three more tools were asked for and refused: po4a for fakeroot, a2x for
ca-certificates, asciidoctor for cryptsetup. Perl, Python and Ruby respectively,
each to render a man page. Hooks instead.
--- FR ---
Six se bâtissent sur l'hôte. Pas libxslt : son configure exige libxml2 2.15.1 et
Ubuntu livre 2.14.5. Le nôtre est en 2.15.3 et n'existe que dans le chroot de
l'étage 2 : ce chroot est donc le seul endroit d'où libxslt puisse venir — bâti
PAR l'étage 2 plutôt qu'installé dedans, et hissé pour précéder shadow, mort sur
`xsltproc is missing`.
La forme mérite un nom : un paquet que l'hôte ne peut pas bâtir parce que l'hôte
est en retard. Ni contamination ni trou de fermeture — la mauvaise machine.
Trois autres outils réclamés et refusés : po4a pour fakeroot, a2x pour
ca-certificates, asciidoctor pour cryptsetup. Perl, Python et Ruby
respectivement, chacun pour rendre une page de manuel. Des hooks à la place.
Assisted-by: Claude Opus 5
zlib stopped on '__builtin_s390_vec_unpackl' requires '-mvx', after its own
configure had detected vector support and defined -DHAVE_S390X_VX. Both halves
were right, so it was worth measuring rather than patching:
host gcc (Ubuntu) --with-arch=z13 --with-tune=z16 default -march=arch11
our gcc nothing default -march=arch5
arch5 is z900, from 2000. Arch's PKGBUILD names no s390x baseline because Arch
has no s390x, so ours fell back to the oldest machine imaginable while zlib went
on detecting a CPU the compiler had been told to forget. Every distribution
picks one of these; this port had never said which, and silence chose 2000.
z13 is what Ubuntu s390x already requires, so nothing that runs today stops.
Set in two places: makepkg.conf, how this distribution is compiled, and gcc's
--with-arch, what the compiler we ship assumes with no flags at all.
--- FR ---
zlib s'est arrêté sur '__builtin_s390_vec_unpackl' requires '-mvx', après que
son propre configure avait détecté le support vectoriel et défini
-DHAVE_S390X_VX. Les deux moitiés avaient raison : il fallait mesurer, pas
rustiner.
gcc de l'hôte --with-arch=z13 --with-tune=z16 défaut -march=arch11
notre gcc rien défaut -march=arch5
arch5, c'est z900, de l'an 2000. Le PKGBUILD d'Arch ne nomme aucune base s390x
puisque Arch n'a pas de s390x : le nôtre retombait sur la machine la plus
ancienne imaginable pendant que zlib détectait un processeur qu'on avait dit au
compilateur d'oublier. Toute distribution en choisit une ; ce portage ne l'avait
jamais dit, et le silence a choisi 2000.
z13 est ce qu'Ubuntu s390x exige déjà : rien qui tourne aujourd'hui ne cesse de
tourner. Posé aux deux endroits : makepkg.conf, comment cette distribution est
compilée, et le --with-arch de gcc, ce que suppose le compilateur qu'on livre.
Assisted-by: Claude Opus 5
Measured once rather than discovered a package at a time: dpkg says what each
of the 110 apt packages ships in /usr/bin, and each of those is tested against
the chroot. Two had already been found the slow way, rsync and makeinfo, and
each cost a full build to surface.
Sorted by what it means: ten are build tools that will each block something,
eleven are documentation already settled by --auto-features auto, and eight are
not gaps at all -- bison.yacc, fakeroot-tcp, automake-1.17, ncurses6-config and
the like are Debian's alternative names for tools that are present under Arch's.
Counting those as missing would have meant building packages that exist.
--- FR ---
Mesuré une fois plutôt que découvert un paquet à la fois : dpkg dit ce que
chacun des 110 paquets apt livre dans /usr/bin, et chacun est testé contre le
chroot. Deux avaient déjà été trouvés par la voie lente, rsync et makeinfo, au
prix d'une construction complète chacun.
Classé par ce que cela signifie : dix sont des outils de construction qui
bloqueront chacun quelque chose, onze sont de la documentation déjà tranchée par
--auto-features auto, et huit ne sont pas des manques -- bison.yacc,
fakeroot-tcp, automake-1.17, ncurses6-config et compagnie sont les noms
alternatifs de Debian pour des outils présents sous ceux d'Arch. Les compter
comme absents aurait fait bâtir des paquets qui existent.
Assisted-by: Claude Opus 5
glibc rebuilt inside the chroot; binutils died on `make info-recursive`, and
makeinfo said why: its XS module was compiled against the host's perl 5.40 and
our perl is 5.42. Stage-1 texinfo cannot run in there. Everything that builds
.info documentation needs it, and it sat near the end of the list because that
is where its own dependencies are, so stage 2 hoists it.
linux-api-headers stopped earlier on `rsync: command not found` -- the kernel's
headers_install runs it. apt had put it there and a build that finds its tool
says nothing, so stage 1 never mentioned it. Its man pages come from Markdown
the git tag does not pre-render, hence --disable-md2man.
An inventory of the 110 apt packages against the chroot found 84 more such
binaries. Most are documentation; the rest wait until something needs them.
--- FR ---
glibc a été rebâti dans le chroot ; binutils est mort sur `make info-recursive`,
et makeinfo en donne la raison : son module XS a été compilé contre le perl 5.40
de l'hôte, or le nôtre est en 5.42. Le texinfo de l'étage 1 ne peut pas tourner
là-dedans. Tout ce qui bâtit de la documentation .info en dépend, et il figurait
en fin de liste, là où sont ses propres dépendances : l'étage 2 le remonte.
linux-api-headers s'était arrêté avant sur `rsync: command not found` — le
headers_install du noyau l'appelle. apt l'avait posé, et une construction qui
trouve son outil n'en dit rien : l'étage 1 ne l'a jamais mentionné. Ses pages de
manuel viennent d'un Markdown que l'étiquette git ne rend pas, d'où
--disable-md2man.
Un inventaire des 110 paquets apt face au chroot a trouvé 84 autres binaires du
même genre. La plupart sont de la documentation ; le reste attendra qu'un paquet
les réclame.
Assisted-by: Claude Opus 5
Stage 2 could rebuild one named package. It could not rebuild a hundred and
thirty-three, for reasons that were all about the driver.
The order is not re-derived: it is the closure stage 1 arrived at over four
rounds of resolver output and then confirmed by 179 builds, so it moves to
packages.sh and both stages read it. make_rootfs wipes the chroot every run,
which is what makes it reproducible and what made stage 2 unresumable --
stage2.state outlived the packages it named. Its output is now put back.
The stall guard is shared rather than copied: stage 2 needs it more, since a
test suite is the likeliest thing in a build to wait forever. Build trees are
removed after a package installs, never after it fails.
--- FR ---
L'étage 2 savait rebâtir un paquet nommé. Il ne savait pas en rebâtir cent
trente-trois, pour des raisons qui tenaient toutes au pilote.
L'ordre n'est pas réinventé : c'est la fermeture obtenue à l'étage 1 en quatre
tours de sortie du résolveur, puis confirmée par 179 constructions. Il passe
donc dans packages.sh, que les deux étages lisent. make_rootfs efface le chroot
à chaque passage — ce qui le rend reproductible et rendait l'étage 2
irreprenable, stage2.state survivant aux paquets qu'il nommait. Sa production y
est désormais réinstallée.
La garde d'immobilité est partagée plutôt que recopiée : l'étage 2 en a plus
besoin, une suite de tests étant ce qui attend le plus volontiers pour
toujours. Les arbres de compilation sont effacés après installation, jamais
après un échec.
Assisted-by: Claude Opus 5
Stage 2 could build and could not deliver. Four obstacles, all in the tail of
package(), after a compile that had already succeeded.
Our meson ships arch-meson and it passes --auto-features enabled, so each of
the nine documentation tools this chroot lacks was a hard error, not a skipped
feature. A wrapper appends --auto-features auto; meson honours the last one.
Building those tools was the alternative and it is not close -- doxygen alone
wants clang, fmt, spdlog, llvm-libs.
Then bsdtar would not start: stage-1 libxml2 asks for the host's
libicuuc.so.76, our icu ships 78, and bsdtar is what writes the package. The
package that would fix it was the one being built. libarchive only links
libxml2 for xar, which nothing here reads, so stage 1 drops it.
Verified: libxml2 rebuilt against libicuuc.so.78, provides libxml2.so=16-64,
zero multiarch paths.
--- FR ---
L'étage 2 savait bâtir et ne savait pas livrer. Quatre obstacles, tous dans la
queue de package(), après une compilation déjà réussie.
Notre meson livre arch-meson, qui passe --auto-features enabled : chacun des
neuf outils de documentation absents de ce chroot devenait une erreur franche
au lieu d'une option écartée. Une enveloppe ajoute --auto-features auto, meson
retenant la dernière occurrence. Bâtir ces outils était l'autre voie et l'écart
est net -- doxygen seul réclame clang, fmt, spdlog, llvm-libs.
Puis bsdtar ne démarrait plus : le libxml2 de l'étage 1 réclame le
libicuuc.so.76 de l'hôte, notre icu livre le 78, et bsdtar est ce qui écrit le
paquet. Le paquet qui corrigeait cela était celui qu'on bâtissait. libarchive
ne lie libxml2 que pour xar, que rien ici ne lit : l'étage 1 l'abandonne.
Vérifié : libxml2 rebâti sur libicuuc.so.78, fournit libxml2.so=16-64, aucun
chemin multiarch.
Assisted-by: Claude Opus 5
Two failures three packages apart, both from the same place: our pacman
package ships Arch's configuration verbatim, and Arch's is for x86_64.
libxml2/meson.build:1:0: ERROR: Unable to detect linker for compiler
`cc ... -march=x86-64 -mtune=generic ...`
configure_chroot fixed CARCH, CHOST, MAKEFLAGS and OPTIONS and left CFLAGS
alone. They are emptied rather than translated, because that is what stage 1
used -- the host's makepkg.conf has no CFLAGS line at all -- and 179 working
packages are the evidence. s390x tuning is a deliberate later choice.
Emptied by APPENDING, not commenting. The first attempt put a # in front of
each assignment, and CFLAGS spans several lines: commenting the first left the
continuations active and the quote unbalanced, so makepkg would not start.
Then readline. Its .pc says `Requires.private: termcap` and this repository
ships tinfo.pc; nothing provides termcap.pc. Nothing failed at build time --
a .pc is data, and pkg-config only follows Requires.private when a consumer
asks. The first consumer to ask was libxml2, in the chroot, one stage and
three packages from the cause.
--- FR ---
Deux échecs à trois paquets d'écart, de la même origine : notre paquet pacman
livre la configuration d'Arch telle quelle, et celle d'Arch vise x86_64.
libxml2/meson.build:1:0: ERROR: Unable to detect linker for compiler
`cc ... -march=x86-64 -mtune=generic ...`
configure_chroot corrigeait CARCH, CHOST, MAKEFLAGS et OPTIONS, et laissait
CFLAGS. Ils sont vidés plutôt que traduits, car c'est ce qu'a utilisé l'étage
1 — le makepkg.conf de l'hôte n'a aucune ligne CFLAGS — et 179 paquets
fonctionnels en sont la preuve. Le réglage pour s390x est un choix ultérieur
délibéré.
Vidés par AJOUT, non par commentaire. La première tentative mettait un # devant
chaque affectation, et CFLAGS s'étend sur plusieurs lignes : commenter la
première laissait les continuations actives et le guillemet déséquilibré, si
bien que makepkg ne démarrait plus.
Puis readline. Son .pc dit « Requires.private: termcap » alors que ce dépôt
livre tinfo.pc ; personne ne fournit termcap.pc. Rien n'échouait à la
compilation — un .pc est une donnée, et pkg-config ne suit Requires.private
que si un consommateur le demande. Le premier à demander fut libxml2, dans le
chroot, à une étape et trois paquets de la cause.
Assisted-by: Claude Opus 5