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
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
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
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
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
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
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
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
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 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
Debian patches sysconfig to prefer the "posix_local" scheme, so every
wheel-installing PKGBUILD ships /usr/local -- a tree Arch reserves and whose
every path the filesystem package owns. pacman refuses the transaction:
error: failed to commit transaction (conflicting files)
/usr/local/share/man exists in both 'filesystem' and 'meson'
Four packages hit it. Two were dropped for other reasons. Rather than write a
third and fourth relocation hook, build_package now exports
DEB_PYTHON_INSTALL_LAYOUT=deb_system, which moves the default from
/usr/local/lib/python3.13/dist-packages to /usr/lib/python3/dist-packages and
scripts from /usr/local/bin to /usr/bin. One line, every python package,
including ones not built yet.
It does not finish the job: deb_system still says dist-packages and Arch reads
site-packages. That move stays per-package, because only modules actually
imported on the target need it. meson does, and its hook does it -- targeting
the version of the python PACKAGE in repo/s390x, not the interpreter running
the build. Installed under the host's 3.13, /usr/bin/meson runs in the chroot
and then says ModuleNotFoundError, because the chroot's python is our 3.14 and
never looks in 3.13.
--- FR ---
Debian modifie sysconfig pour préférer le schéma « posix_local » : tout
PKGBUILD installant une roue livre donc /usr/local, arbre qu'Arch réserve et
dont le paquet filesystem possède chaque chemin. pacman refuse la transaction :
error: failed to commit transaction (conflicting files)
/usr/local/share/man exists in both 'filesystem' et 'meson'
Quatre paquets l'ont rencontré. Deux ont été écartés pour d'autres raisons.
Plutôt que d'écrire un troisième et un quatrième crochet de relocalisation,
build_package exporte désormais DEB_PYTHON_INSTALL_LAYOUT=deb_system, qui
déplace le défaut de /usr/local/lib/python3.13/dist-packages vers
/usr/lib/python3/dist-packages, et les scripts de /usr/local/bin vers /usr/bin.
Une ligne, tous les paquets python, y compris ceux pas encore bâtis.
Cela ne termine pas le travail : deb_system dit encore dist-packages quand
Arch lit site-packages. Ce déplacement reste par paquet, car seuls les modules
réellement importés sur la cible en ont besoin. meson en fait partie, et son
crochet le fait — en visant la version du PAQUET python de repo/s390x, non
l'interpréteur qui exécute la compilation. Installé sous le 3.13 de l'hôte,
/usr/bin/meson démarre dans le chroot puis annonce ModuleNotFoundError, le
python du chroot étant notre 3.14, qui ne regarde jamais dans 3.13.
Assisted-by: Claude Opus 5
Ten of the 159 PKGBUILDs call arch-meson and four call cmake, so a chroot
without them could rebuild most of the repository and then stop. Neither is a
dependency of anything in the repository, which is why no closure round ever
named them -- the same shape as fakeroot and bison, one layer up.
python returns with meson, and that is not the earlier decision being
reversed. Dropping python at stage 1 was about what the REPOSITORY must
supply: it was wanted only by two wheels Arch's own python could not load.
This is about what the BUILD ENVIRONMENT must contain, and meson is written in
Python. Different question, different answer.
python needed two fixes of its own. Its xvfb loop is in build() AND in
check(); stage 1 never ran the second because of --nocheck, but stage 2 drops
--nocheck on purpose, so it would have spun there too. And Python 3.13 removed
the vendored libmpdec, so --with-system-libmpdec is the only way to build and
needs the host headers -- reported nine hundred lines in as a missing make
rule for a file that used to be vendored.
cmake wanted rhash, then jsoncpp, then cppdap, one at a time. That is a queue,
and the rule in install_host_deps says a queue is a feature to disable. Not
applied here, deliberately: each exists as an Ubuntu package, so the queue
ends. The rule is for queues that do not, like dbus reaching a documentation
tool that needed Qt. Its Qt GUI is dropped -- a dialog box on a headless
mainframe.
--- FR ---
Dix des 159 PKGBUILD appellent arch-meson et quatre appellent cmake : un
chroot sans eux pourrait reconstruire l'essentiel du dépôt puis s'arrêter.
Aucun des deux n'est une dépendance de quoi que ce soit dans le dépôt, ce qui
explique qu'aucun tour de fermeture ne les ait nommés — même forme que
fakeroot et bison, une couche plus haut.
python revient avec meson, et ce n'est pas un revirement. L'écarter à l'étage
1 portait sur ce que le DÉPÔT doit fournir : il n'était voulu que par deux
roues que le python d'Arch ne pouvait pas charger. Ici il s'agit de ce que
l'ENVIRONNEMENT DE BUILD doit contenir, et meson est écrit en Python. Autre
question, autre réponse.
python a demandé deux correctifs propres. Sa boucle xvfb est dans build() ET
dans check() ; l'étage 1 n'a jamais exécuté la seconde grâce à --nocheck, mais
l'étage 2 l'abandonne exprès — elle y aurait tourné aussi. Et Python 3.13 a
retiré le libmpdec embarqué : --with-system-libmpdec est la seule voie et
réclame les en-têtes de l'hôte, signalé neuf cents lignes plus loin comme une
règle make manquante pour un fichier autrefois embarqué.
cmake a réclamé rhash, puis jsoncpp, puis cppdap, un par un. C'est une file, et
la règle d'install_host_deps dit qu'une file est une fonctionnalité à
désactiver. Non appliquée ici, délibérément : chacun existe en paquet Ubuntu,
donc la file se termine. La règle vise celles qui ne terminent pas, comme dbus
atteignant un outil de documentation qui exigeait Qt. Son interface Qt est
retirée — une boîte de dialogue sur un mainframe sans écran.
Assisted-by: Claude Opus 5
The loop applies each hook on the HOST -- /build is the same directory from
both sides, so makepkg in the chroot reads the patched PKGBUILD and nothing is
duplicated inside. It drops --nocheck: stage 1 skipped the test suites because
they ran against the host's libraries, and here they test what was built.
Each rebuilt package is installed into the chroot before the next one, with
the host's pacman and --root, because the chroot's own pacman will not start
until stage 2 has rebuilt it.
Two hooks must NOT run there, and both for the same satisfying reason: the
condition they work around does not exist in the chroot. libgcrypt.sh points
at a host prefix holding our libgpg-error, which the chroot has installed
properly. git.sh drops ZLIB_NG=1 because Ubuntu ships no zlib-ng headers,
while our own zlib-ng package ships them.
git is here because STAGE 2 needs it, not the repository: 51 of the 159
PKGBUILDs take their sources from git+https, and makepkg validates that clone
even under --noextract. Nothing depends on git. Its three -- perl-error,
perl-mailtools with perl-timedate, zlib-ng -- were read from the depends array
rather than from my own tool, which had reported `zsh` as a dependency of git.
It is not; the tool's regex was catching a neighbouring array.
--- FR ---
La boucle applique chaque crochet sur l'HÔTE — /build est le même répertoire
des deux côtés, donc makepkg dans le chroot lit le PKGBUILD corrigé et rien
n'est dupliqué dedans. Elle abandonne --nocheck : l'étage 1 sautait les suites
de tests parce qu'elles s'exécutaient contre les bibliothèques de l'hôte ; ici
elles éprouvent ce qui a été bâti. Chaque paquet reconstruit est installé dans
le chroot avant le suivant, avec le pacman de l'hôte et --root, celui du
chroot ne démarrant pas avant que l'étage 2 ne l'ait reconstruit.
Deux crochets ne doivent PAS y tourner, et pour la même raison satisfaisante :
la condition qu'ils contournent n'existe pas dans le chroot. libgcrypt.sh
pointe sur un préfixe hôte contenant notre libgpg-error, que le chroot a
installé correctement. git.sh retire ZLIB_NG=1 parce qu'Ubuntu ne livre pas
les en-têtes zlib-ng, alors que notre propre paquet zlib-ng les livre.
git est là parce que l'ÉTAGE 2 en a besoin, pas le dépôt : 51 des 159
PKGBUILD prennent leurs sources en git+https, et makepkg valide ce clone même
sous --noextract. Rien ne dépend de git. Ses trois dépendances — perl-error,
perl-mailtools avec perl-timedate, zlib-ng — ont été lues dans le tableau
depends plutôt que dans mon propre outil, qui annonçait `zsh` comme dépendance
de git. Elle ne l'est pas : la regex de l'outil attrapait un tableau voisin.
Assisted-by: Claude Opus 5
Our gcc package was built a dozen times and never once used to compile
anything -- stage 1 compiles with Ubuntu's gcc. The first program it was ever
asked to link was in the stage-2 chroot, and it failed twice.
collect2: fatal error: cannot find 'ld'
/usr/bin/ld was present, executable, on PATH, and ran as the same user. -B,
COMPILER_PATH and three symlinks changed nothing. strace settled it in one
line: it was looking for s390x-linux-gnu-ld, the DEBIAN triplet, and printing
the generic name. gcc's configure had recorded Ubuntu's copy, a file no Arch
system will ever have. --with-ld and --with-as now pin absolute paths, correct
on the host, in the chroot and on the target alike.
/usr/bin/ld: cannot find -lgcc_s
package_gcc() moves libgcc_s{,_asneeded}.so three directories deeper. The
asneeded one is a linker script and survives; libgcc_s.so is a symlink naming
its target relative to /usr/lib, so after the move it points at nothing. The
only libgcc_s.so on the system was dangling, so -lgcc_s could not resolve and
nothing linked at all -- not even int main(void){return 0;}.
Verified: the chroot now compiles and runs a program.
--- FR ---
Notre paquet gcc a été bâti une douzaine de fois sans jamais servir à
compiler : l'étage 1 compile avec le gcc d'Ubuntu. Le premier programme qu'on
lui a demandé de lier l'a été dans le chroot d'étage 2, et il a échoué deux
fois.
collect2: fatal error: cannot find 'ld'
/usr/bin/ld était présent, exécutable, dans le PATH, et répondait pour le même
utilisateur. -B, COMPILER_PATH et trois liens symboliques n'ont rien changé.
strace a tranché en une ligne : il cherchait s390x-linux-gnu-ld, le triplet
DEBIAN, en affichant le nom générique. La configuration de gcc avait
enregistré la copie d'Ubuntu, un fichier qu'aucun système Arch n'aura jamais.
--with-ld et --with-as épinglent désormais des chemins absolus, corrects sur
l'hôte, dans le chroot et sur la cible.
/usr/bin/ld: cannot find -lgcc_s
package_gcc() déplace libgcc_s{,_asneeded}.so trois répertoires plus bas.
Le second est un script ld et survit ; libgcc_s.so est un symlink dont la
cible est relative à /usr/lib, si bien qu'après le déplacement il ne pointe
plus sur rien. Le seul libgcc_s.so du système pendait dans le vide : -lgcc_s
ne pouvait se résoudre et plus rien ne se liait — pas même
int main(void){return 0;}.
Vérifié : le chroot compile et exécute désormais un programme.
Assisted-by: Claude Opus 5
The fourth closure round asked for libaio and thin-provisioning-tools, both
wanted by lvm2 alone. thin-provisioning-tools is Rust now, so a language
runtime was arriving through a fourth-order dependency.
Nothing in the repository wants `lvm2`. Checked across every .PKGINFO:
cryptsetup wants device-mapper, and device-mapper is the other package this
same source produces. Dropping the sub-package removed both entries and the
Rust question with them.
The measurement is the argument, and it went the other way an hour earlier.
tcl, unixodbc and libmicrohttpd each cost zero new packages, so building them
beat dropping sub-packages. This one costs a language runtime, so dropping
wins. The rule is not to prefer either -- it is to measure each time.
device-mapper had also picked up the host's libselinux, silently. Seventh
package to do it, second found by reading binaries rather than by a build.
35 packages, then 19, then 2, then 0.
--- FR ---
Le quatrième tour de fermeture réclamait libaio et thin-provisioning-tools,
tous deux voulus par lvm2 seul. thin-provisioning-tools est en Rust
désormais : un environnement de langage arrivait par une dépendance de
quatrième ordre.
Rien dans le dépôt ne veut `lvm2`. Vérifié sur chaque .PKGINFO : cryptsetup
veut device-mapper, et device-mapper est l'autre paquet que cette même source
produit. Écarter le sous-paquet a retiré les deux entrées et la question Rust
avec elles.
La mesure est l'argument, et elle avait tranché dans l'autre sens une heure
plus tôt. tcl, unixodbc et libmicrohttpd coûtaient zéro paquet nouveau : les
bâtir valait mieux qu'écarter des sous-paquets. Celui-ci coûte un
environnement de langage : écarter gagne. La règle n'est de préférer ni l'un
ni l'autre — c'est de mesurer chaque fois.
device-mapper avait aussi ramassé le libselinux de l'hôte, en silence.
Septième paquet à le faire, deuxième trouvé en lisant des binaires plutôt que
par une compilation.
35 paquets, puis 19, puis 2, puis 0.
Assisted-by: Claude Opus 5
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
e2fsprogs builds fuse2fs, deletes it, and repackages it. Without fuse3 on the
host it was never compiled, so the delete aborted package() after a clean
build -- and its sub-package declares fuse3, which this port does not ship, so
even a success would have been uninstallable. Three reasons, one direction.
libsasl said `libpq-fe.h: No such file or directory` about a file that is
there, in /usr/include/postgresql. mysql.h is in /usr/include/mariadb, the
same shape one step behind it. Two headers that exist on paths configure does
not try is a queue, and this port already wrote down what a queue means: a
single missing library is a host dependency, a queue of them is a feature to
disable. Arch declares depends=(glibc) for libsasl and says why -- the SQL
plugins are dlopened, never linked.
python-audit and python-capng go the way python-brotli went, but the reason is
stated differently on purpose. Cost was the argument then; measured now,
python costs three packages rather than a subtree, so that argument no longer
holds. The ABI does: both are cp313 wheels and Arch ships 3.14.
--- FR ---
e2fsprogs bâtit fuse2fs, le supprime, puis le rempaquette. Sans fuse3 sur
l'hôte il n'a jamais été compilé : la suppression interrompait donc package()
après une compilation propre — et son sous-paquet déclare fuse3, que ce
portage ne livre pas, si bien qu'une réussite aurait été ininstallable. Trois
raisons, une seule direction.
libsasl annonçait « libpq-fe.h: No such file or directory » à propos d'un
fichier présent, sous /usr/include/postgresql. mysql.h est sous
/usr/include/mariadb, même forme un cran derrière. Deux en-têtes qui existent
sur des chemins que configure n'essaie pas font une file d'attente, et ce
dépôt a déjà consigné ce qu'une file signifie : une bibliothèque manquante est
une dépendance hôte, une file en est une fonctionnalité à désactiver. Arch
déclare depends=(glibc) pour libsasl et explique pourquoi — les greffons SQL
sont chargés dynamiquement, jamais liés.
python-audit et python-capng suivent python-brotli, mais le motif est énoncé
autrement à dessein. C'était le coût alors ; mesuré maintenant, python coûte
trois paquets et non un sous-arbre, cet argument ne tient donc plus. L'ABI,
si : les deux sont des roues cp313 quand Arch livre la 3.14.
Assisted-by: Claude Opus 5
The first package the host is too OLD for rather than missing something.
libgcrypt 1.12.2 wants libgpg-error >= 1.56; Ubuntu ships 1.51. No -dev
package fixes a version floor.
We built 1.61 ourselves, so the material exists -- but using it crosses a
line worth naming: consuming stage 1's own output is the property that
defines stage 2. The alternative was deferring libgcrypt, which gnupg and
systemd both declare, leaving the repository unresolvable. Using our own is
also what a bootstrap does, and stage 2 erases the distinction anyway.
--with-libgpg-error-prefix looks like the mechanism and is not: it sets
GPG_ERROR_CONFIG to $prefix/bin/gpg-error-config, a program 1.61 no longer
ships. It would have named an absent file, fallen back to PATH, found 1.51
again, and the error would not have moved. GPGRT_CONFIG is what configure
consults. Verified on a copy: version >= 1.56 yes (1.61-unknown), rc=0.
The artefact carries no RPATH and no reference to the scratch prefix; it
links the bare soname, which the target resolves from its own /usr/lib.
--- FR ---
Le premier paquet pour lequel l'hôte est trop VIEUX plutôt qu'incomplet.
libgcrypt 1.12.2 veut libgpg-error >= 1.56 ; Ubuntu livre la 1.51. Aucun
paquet -dev ne corrige un plancher de version.
Nous avons bâti la 1.61 nous-mêmes, le matériel existe donc — mais l'employer
franchit une limite qu'il faut nommer : consommer la sortie de l'étage 1 est
la propriété qui définit l'étage 2. L'alternative était de reporter libgcrypt,
que gnupg et systemd déclarent tous deux, laissant le dépôt insoluble.
Employer le nôtre est aussi ce que fait un amorçage, et l'étage 2 efface la
distinction de toute façon.
--with-libgpg-error-prefix a l'air d'être le mécanisme et ne l'est pas : il
fixe GPG_ERROR_CONFIG à $prefix/bin/gpg-error-config, programme que la 1.61 ne
livre plus. Il aurait nommé un fichier absent, on serait retombé sur le PATH,
retrouvé la 1.51, et l'erreur n'aurait pas bougé. C'est GPGRT_CONFIG que
configure consulte. Vérifié sur une copie : version >= 1.56 yes
(1.61-unknown), rc=0.
L'artefact ne porte ni RPATH ni référence au préfixe temporaire ; il lie le
soname nu, que la cible résout depuis son propre /usr/lib.
Assisted-by: Claude Opus 5
Five packages, one shape: a default computed from this machine rather than
from Arch, and arch-meson's --auto-features enabled turning what was optional
into a requirement.
dbus taught the method. It stopped three times in a row on a different
documentation tool -- ducktype, then yelp-build, then qhelpgenerator. The
first two were installed. The third needs Qt, so the chain had no end. All
three are `auto` features promoted to mandatory; pinned off, they cost
nothing. A single missing library is a host dependency. A queue of them is a
feature that should be disabled.
pinentry wanted Qt6 for a passphrase prompt; tty and curses remain.
krb5 asked for a system ss library Ubuntu ships no headers for, and said
"cannot run test program" instead of saying so.
sqlite found tcl, then installed into share/tcltk because Ubuntu's
tclConfig.sh says so and Arch's says lib.
gettext linked the host's libselinux, silently -- the sixth package to do it,
and the first the audit caught rather than a build.
--- FR ---
Cinq paquets, une seule forme : une valeur par défaut calculée depuis cette
machine plutôt que depuis Arch, et le --auto-features enabled d'arch-meson qui
transforme l'optionnel en exigence.
dbus a enseigné la méthode. Il s'est arrêté trois fois de suite sur un outil
de documentation différent — ducktype, puis yelp-build, puis qhelpgenerator.
Les deux premiers ont été installés. Le troisième exige Qt : la chaîne ne
terminait nulle part. Les trois sont des features `auto` promues en
obligations ; épinglées à disabled, elles ne coûtent rien. Une bibliothèque
manquante est une dépendance hôte. Une file d'attente en est une
fonctionnalité à désactiver.
pinentry réclamait Qt6 pour une invite de mot de passe ; tty et curses
suffisent.
krb5 demandait une bibliothèque ss système dont Ubuntu ne livre aucun
en-tête, et annonçait « cannot run test program » plutôt que de le dire.
sqlite trouvait tcl, puis installait dans share/tcltk parce que le
tclConfig.sh d'Ubuntu le dit là où celui d'Arch dit lib.
gettext liait le libselinux de l'hôte, en silence — sixième paquet à le
faire, et le premier que l'audit a pris plutôt qu'une compilation.
Assisted-by: Claude Opus 5
An audit of every missing dependency spelled as a soname, asking the ARTEFACT
whether the package that declares it actually links it. It contradicted my
guesses: curl's krb5, ssh2 and idn2 are all real. Two were not.
make readelf -d usr/bin/make -> libc.so.6, and nothing else
gcc configure recorded ISLLIBS='' ISLINC=''; zero libisl in the tree
Both are false in our build environment and true in Arch's. --nodeps means
makepkg never checks, so each shipped a package asking for something this
port will never contain -- and only pacman ever notices, at install time.
Building isl was the first plan. Its Arch packaging repo was last touched in
2017 and its only source URL is isl.gforge.inria.fr, dead with INRIA's
GForge. There is nothing to build; the declaration goes instead, and Graphite
goes with it.
gnutls found the same shape from the other direction: --with-leancrypto
stopped configure, and 'leancrypto' sat in depends= where nothing checks it.
--- FR ---
Un audit de chaque dépendance manquante écrite en soname, demandant à
l'ARTEFACT si le paquet qui la déclare la lie vraiment. Il a contredit mes
suppositions : les krb5, ssh2 et idn2 de curl sont bien réels. Deux ne
l'étaient pas.
make readelf -d usr/bin/make -> libc.so.6, et rien d'autre
gcc configure a noté ISLLIBS='' ISLINC='' ; aucun libisl dans l'arbre
Les deux sont fausses dans notre environnement et vraies dans celui d'Arch.
--nodeps veut dire que makepkg ne vérifie jamais : chacun livrait donc un
paquet réclamant ce que ce portage ne contiendra jamais — et seul pacman s'en
aperçoit, à l'installation.
Bâtir isl était le premier plan. Son dépôt de packaging Arch n'a pas bougé
depuis 2017 et sa seule source pointe isl.gforge.inria.fr, morte avec le
GForge d'INRIA. Il n'y a rien à bâtir : c'est la déclaration qui part, et
Graphite avec elle.
gnutls a montré la même forme par l'autre bout : --with-leancrypto arrêtait
configure, et 'leancrypto' figurait dans depends= où rien ne le vérifie.
Assisted-by: Claude Opus 5
pacman's resolver named 70 unresolved dependencies. Excluding python-brotli
alone took that to 47 and removed `python` outright, with libffi, mpdecimal
and gdbm behind it. python-libseccomp would have re-admitted the same tree,
and nothing across 135 packages depends on either.
Both wheels are unusable on the target anyway: built by the host's python
3.13, ABI-tagged cpython-313, while Arch ships 3.14. Stage 2 produces real
ones.
systemd-ukify is different -- it is architectural. ukify assembles a PE
binary and its EFI_ARCH_MAP has no s390x entry, so guess_efi_arch() raises
ValueError on this machine. Shipping it would put a program in the repository
that cannot start. systemd-tests followed it out: a test suite behind
--nocheck, and the only reason five more python packages were wanted.
The dropped artefacts were still indexed in core.db afterwards. repo-add only
adds, so a sub-package removed from pkgname leaves its last build installable
forever. Removed by hand; TODO.md records the gap.
--- FR ---
Le résolveur de pacman nommait 70 dépendances non résolues. Écarter le seul
python-brotli a ramené le compte à 47 et retiré `python` d'un coup, avec
libffi, mpdecimal et gdbm derrière. python-libseccomp aurait réadmis le même
arbre, et rien parmi 135 paquets ne dépend de l'un ou de l'autre.
Les deux roues sont de toute façon inutilisables sur la cible : bâties par le
python 3.13 de l'hôte, marquées cpython-313, quand Arch livre la 3.14.
L'étage 2 en produira de vraies.
systemd-ukify est d'une autre nature — architectural. ukify assemble un
binaire PE et son EFI_ARCH_MAP n'a pas d'entrée s390x : guess_efi_arch() lève
donc ValueError sur cette machine. Le livrer mettrait au dépôt un programme
incapable de démarrer. systemd-tests l'a suivi : une suite de tests derrière
--nocheck, et la seule raison de réclamer cinq paquets python de plus.
Les artefacts écartés restaient indexés dans core.db. repo-add n'ajoute que :
un sous-paquet retiré de pkgname laisse sa dernière compilation installable à
jamais. Retirés à la main ; TODO.md consigne le manque.
Assisted-by: Claude Opus 5
The repository already knew four: pkgname, the build block, the _pick
lines, the explicit make targets. There is a fifth, and it is the only one
that fails silently -- the depends= array of a DIFFERENT sub-package.
--nodeps means makepkg never checks, so gcc-libs built, passed, and went
into the repository declaring a dependency on libhwasan, which this
architecture never produces. Nothing said a word. pacman did, the first
time anything tried to install it:
:: unable to satisfy dependency 'libhwasan' required by gcc-libs
This was already paid for once: an earlier pass hit it with libquadmath and
pruned that one name by hand. libhwasan joined the drop set afterwards and
the pruning was not extended. Pruning one name at a time was the bug.
The set that decides what is not built now also decides what is not
depended on, and an assertion refuses to let the two drift again.
--- FR ---
Le dépôt en connaissait déjà quatre : pkgname, le bloc de build, les lignes
_pick, les cibles make explicites. Il y en a un cinquième, et c'est le seul
qui échoue en silence — le tableau depends= d'un AUTRE sous-paquet.
--nodeps veut dire que makepkg ne vérifie jamais : gcc-libs s'est construit,
a été accepté, et est entré dans le dépôt en déclarant une dépendance envers
libhwasan, que cette architecture ne produit jamais. Rien n'a bronché.
pacman, si, à la première tentative d'installation :
:: unable to satisfy dependency 'libhwasan' required by gcc-libs
C'était déjà payé une fois : un passage antérieur avait rencontré le piège
avec libquadmath et élagué ce seul nom à la main. libhwasan a rejoint la
liste des retraits ensuite, sans que l'élagage suive. Élaguer nom par nom
était le vrai défaut.
L'ensemble qui décide de ce qui n'est pas construit décide désormais aussi
de ce dont on ne dépend pas, et une assertion interdit aux deux de diverger.
Assisted-by: Claude Opus 5
--auto-features enabled turns every auto feature into a requirement, so
installing a tool switches on code that never compiled here. Three of the
fifty host packages did exactly that, and only one failed for the reason
it named.
expat had built clean the day before. asciidoc pulled docbook-utils in as
an automatic dependency; it owns docbook2man, the third name in expat's
find_program list, so docs defaulted ON twenty-nine hours before anything
rebuilt. That tool is the SGML pipeline: on DocBook XML it writes nothing
and still exits 0, and the mv it feeds is what reported the failure. Arch
ships no xmlwf.1 either, so OFF is parity.
systemd's split-bin probes the BUILD host's /usr/sbin. Ubuntu's is a real
directory, so six binaries went where package() does not look -- and
arch-meson's --sbindir is ignored, systemd computes its own.
util-linux needed no option: poman-translate.sh greps po4a for the English
"Discard" and this host answers "Rejet de". The locale belongs to the host,
so it is pinned once on the makepkg line.
--- FR ---
--auto-features enabled fait de chaque fonction « auto » une exigence :
installer un outil active donc du code jamais compilé ici. Trois des
cinquante paquets hôte l'ont fait, et un seul a échoué pour la raison
qu'il annonçait.
expat compilait proprement la veille. asciidoc avait tiré docbook-utils en
dépendance automatique ; il fournit docbook2man, troisième nom de la liste
find_program d'expat, et la doc est passée à ON vingt-neuf heures avant
toute reconstruction. Cet outil est le pipeline SGML : sur du DocBook XML
il n'écrit rien et sort quand même 0, et le mv qu'il alimente est ce qui a
signalé la panne. Arch ne livre pas xmlwf.1 non plus : OFF, c'est la parité.
Le split-bin de systemd sonde le /usr/sbin de la machine de BUILD. Celui
d'Ubuntu est un vrai répertoire, donc six binaires sont partis là où
package() ne regarde pas — et le --sbindir d'arch-meson est ignoré, systemd
calcule le sien.
util-linux n'avait besoin d'aucune option : poman-translate.sh cherche le
« Discard » anglais de po4a, et cet hôte répond « Rejet de ». La locale
appartient à l'hôte : elle est épinglée une fois, sur la ligne makepkg.
Assisted-by: Claude Opus 5
--nodeps means every makedepend must be named here by hand. Seven builds
stopped on one, each naming a different tool: itstool, convert, fig2dev,
asciidoctor, libnsl, python -m build, libbpf, history.
The list was also a lie by omission. libreadline-dev, libncurses-dev,
zlib1g-dev, python3-dev, doxygen, xsltproc, docbook-xsl, elinks and
libcap2-bin were on this VM by hand and never declared. They made the
builds pass here and would fail on a fresh Ubuntu, for reasons that have
nothing to do with s390x.
history.pc is generated rather than copied: our own readline package
ships a correct one, but its libdir names /usr/lib, which on a multiarch
host holds no libhistory. The .pc has to describe THIS host.
Three hooks for what apt cannot buy. systemd asks for an EFI arch s390x
does not have -- and says "python3 is missing modules: elftools", which
sends you to apt for four lines before admitting the real reason.
--- FR ---
--nodeps veut dire que chaque makedepend doit être nommé ici à la main.
Sept compilations se sont arrêtées sur l'une d'elles, chacune désignant
un outil différent : itstool, convert, fig2dev, asciidoctor, libnsl,
python -m build, libbpf, history.
La liste mentait aussi par omission. libreadline-dev, libncurses-dev,
zlib1g-dev, python3-dev, doxygen, xsltproc, docbook-xsl, elinks et
libcap2-bin étaient posés à la main sur cette VM, jamais déclarés. Ils
faisaient passer les compilations ici et auraient échoué sur un Ubuntu
neuf, pour des raisons étrangères à s390x.
history.pc est généré et non copié : notre propre paquet readline en
livre un correct, mais son libdir nomme /usr/lib, qui sur un hôte
multiarch ne contient aucun libhistory. Le .pc doit décrire CET hôte-ci.
Trois crochets pour ce qu'apt n'achète pas. systemd réclame une
architecture EFI que s390x n'a pas — et annonce « python3 is missing
modules: elftools », ce qui envoie chez apt pour quatre lignes avant
d'avouer la vraie raison.
Assisted-by: Claude Opus 5
The previous commit read the chroot's "coreutils needs libselinux.so.1"
as a missing package. It is not one. Arch has no libselinux at all -- the
clone 404s -- and Arch's coreutils declares no selinux dependency,
because its build chroot has no selinux/selinux.h to find.
Ours found one. Ubuntu carries libselinux1-dev, gnulib probes for the
header unconditionally, and the audit names every victim:
coreutils 13 binaries findutils find sed tar glibc makedb
--without-selinux per package, which is what Arch gets for free. Arch
ships neither chcon nor runcon either, so this converges with Arch rather
than diverging. tar and find matter most: stage 2 runs makepkg inside
this rootfs, and makepkg calls both.
glibc is deliberately left alone. Nothing runs makedb, and rebuilding
glibc would relink the foundation under sixty-nine other packages; stage
2 does it in a chroot where the header cannot be found.
--- FR ---
Le commit précédent a lu le « coreutils réclame libselinux.so.1 » du
chroot comme un paquet manquant. Ce n'en est pas un. Arch n'a aucun
libselinux — le clone rend un 404 — et son coreutils ne déclare aucune
dépendance selinux, faute de selinux/selinux.h dans son chroot de
construction.
Le nôtre en a trouvé un. Ubuntu embarque libselinux1-dev, gnulib sonde
l'en-tête sans condition, et l'audit nomme chaque victime :
coreutils 13 binaires findutils find sed tar glibc makedb
--without-selinux par paquet, ce qu'Arch obtient gratuitement. Arch ne
livre ni chcon ni runcon non plus : on converge donc vers Arch au lieu de
s'en écarter. tar et find sont les plus critiques — l'étage 2 lance
makepkg dans ce rootfs, et makepkg les appelle tous deux.
glibc est laissé tel quel, délibérément. Rien n'exécute makedb, et le
reconstruire relierait la fondation sous soixante-neuf autres paquets ;
l'étage 2 s'en charge dans un chroot où l'en-tête est introuvable.
Assisted-by: Claude Opus 5
meson and cmake both ask the HOST where libraries go. On Ubuntu the
answer is lib/s390x-linux-gnu, so five packages already in the repository
ship theirs where Arch's ld.so and pkgconf never look. Measured:
expat 12 lz4 6 pacman 6 pkgconf 6 zstd 12 entries
Nothing failed. util-linux is where it finally shouted, and even there
the rm was the first victim, not the cause.
pacman is the one that matters: libalpm.so.16 landed where pacman's own
binary cannot load it, and a target installed from that package has no
working package manager left to repair itself with.
arch-meson now states the libdir devtools has no need to state, and is
reinstalled on every run -- editing the copy here changed nothing while
/usr/local/bin held a stale one. Four packages call bare meson or cmake
and get their own hook. util-linux's old hook chased lib64, which never
existed here; it is deleted.
--- FR ---
meson et cmake demandent tous deux à l'HÔTE où vont les bibliothèques.
Sous Ubuntu la réponse est lib/s390x-linux-gnu : cinq paquets déjà dans
le dépôt livrent donc les leurs là où ld.so et pkgconf d'Arch ne
regarderont jamais. Mesuré :
expat 12 lz4 6 pacman 6 pkgconf 6 zstd 12 entrées
Rien n'a échoué. util-linux est l'endroit où cela a fini par crier, et
même là le rm était la première victime, pas la cause.
pacman est celui qui compte : libalpm.so.16 atterrissait là où le binaire
de pacman ne peut pas la charger, et une cible installée depuis ce paquet
n'a plus de gestionnaire de paquets pour se réparer.
arch-meson énonce désormais le libdir que devtools n'a pas besoin
d'énoncer, et se réinstalle à chaque exécution : éditer la copie du dépôt
ne changeait rien tant que /usr/local/bin en gardait une périmée. Quatre
paquets appellent meson ou cmake nu et reçoivent leur crochet. L'ancien
crochet util-linux poursuivait un lib64 qui n'a jamais existé ici : il
est supprimé.
Assisted-by: Claude Opus 5
Third attempt on this package, and the first one written after reading
the file instead of assuming its shape. The two before it failed for
the same reason:
1. Skipping ./bootstrap. The source is a git checkout, not a released
tarball, so that removed configure itself:
PKGBUILD: line 43: ./configure: No such file or directory
2. Editing `bootstrap`. The check is not there. It lives in
bootstrap.conf, inside a shell function, and its message is built
from a $url variable -- which is why grepping the literal text
found nothing, twice.
The check is two lines: a grep for the serial and a die. Both are
replaced by a no-op that keeps the enclosing function valid, verified
against the real file before being committed.
grep is the only package here that INSPECTS its host's m4 macros. This
is not an s390x incompatibility: pkg-config 0.29.2 ships that serial on
every distribution, x86 included.
The hook checks BOTH that the patch step was inserted and that
./bootstrap is still invoked, so mistake 1 cannot come back silently.
--- FR ---
Troisieme tentative sur ce paquet, et la premiere ecrite apres avoir lu
le fichier au lieu d en supposer la forme. Les deux precedentes ont
echoue pour la meme raison :
1. Sauter ./bootstrap. La source est un depot git, pas une archive de
version : cela supprimait configure lui-meme.
2. Modifier « bootstrap ». La verification n y est pas. Elle vit dans
bootstrap.conf, dans une fonction shell, et son message est
construit a partir d une variable $url -- d ou l echec, deux fois,
de la recherche du texte litteral.
La verification tient en deux lignes : un grep sur la serie et un die.
Les deux sont remplacees par une instruction vide qui laisse la
fonction valide, essai fait sur le vrai fichier avant de commiter.
grep est le seul paquet ici a EXAMINER les macros m4 de son hote. Ce
n est pas une incompatibilite s390x : pkg-config 0.29.2 livre cette
serie sur toutes les distributions, x86 compris.
Le crochet verifie A LA FOIS que l etape de correction est inseree et
que ./bootstrap est toujours appele, pour que l erreur 1 ne puisse pas
revenir en silence.
Assisted-by: Claude Opus 5
The previous version of this hook skipped ./bootstrap entirely, on the
assumption that the source was a released tarball and therefore already
bootstrapped. It is not -- it is a git checkout, so skipping bootstrap
removed configure itself:
PKGBUILD: line 43: ./configure: No such file or directory
That made things worse than the failure it was meant to fix, and it was
my assumption that was wrong, not the package.
What has to go is the check, not the bootstrap. grep is the only
package here that INSPECTS the version of the m4 macros its host
provides and refuses to proceed on Ubuntu's serial -- on any Ubuntu
host, x86 included. The check lives in the extracted source, so it is
removed from prepare().
The hook now verifies BOTH that the check is gone and that ./bootstrap
is still invoked, so this particular mistake cannot come back silently.
--- FR ---
La version precedente de ce crochet sautait ./bootstrap entierement, en
supposant que la source etait une archive de version, donc deja
amorcee. Elle ne l est pas -- c est un depot git, et sauter bootstrap
supprimait configure lui-meme :
PKGBUILD: line 43: ./configure: No such file or directory
Cela empirait l etat au lieu de le corriger, et c est mon hypothese qui
etait fausse, pas le paquet.
Ce qu il faut retirer, c est la verification, pas l amorcage. grep est
le seul paquet ici a EXAMINER la version des macros m4 de son hote et a
refuser la serie d Ubuntu -- sur n importe quel hote Ubuntu, x86
compris. La verification vit dans la source extraite : elle est donc
retiree depuis prepare().
Le crochet controle desormais A LA FOIS que la verification a disparu
et que ./bootstrap est toujours appele, pour que cette erreur precise
ne puisse pas revenir en silence.
Assisted-by: Claude Opus 5
grep is the only package here that INSPECTS the version of the m4
macros its build host provides, and refuses to proceed:
./bootstrap: do not use pkg.m4 serial 12
That is not an s390x incompatibility -- the same refusal happens on any
Ubuntu host, x86 included. The release tarball is already bootstrapped,
so re-running ./bootstrap regenerates what is already there and
skipping it costs nothing.
util-linux hits the lib64-versus-lib divergence already handled in
gcc.sh. Here it surfaces as
rm: cannot remove '.../usr/lib/lib*.la': No such file or directory
a glob that matched nothing, which rm reports as a missing file rather
than an empty expansion -- so the error names a path that was never
going to exist. Same remedy: merge the trees before package() touches
anything, leaving the upstream paths working unchanged.
That divergence has now appeared twice. If a third package hits it, it
belongs in the shared bootstrap rather than in per-package hooks.
--- FR ---
grep est le seul paquet ici a EXAMINER la version des macros m4 que lui
fournit son hote, et a refuser de poursuivre :
./bootstrap: do not use pkg.m4 serial 12
Ce n est pas une incompatibilite s390x -- le meme refus survient sur
n importe quel hote Ubuntu, x86 compris. L archive de version est deja
amorcee, donc relancer ./bootstrap regenere ce qui existe deja et le
sauter ne coute rien.
util-linux rencontre la divergence lib64 contre lib deja traitee dans
gcc.sh. Elle apparait ici sous la forme
rm: cannot remove '.../usr/lib/lib*.la': No such file or directory
un motif qui ne correspond a rien, que rm signale comme un fichier
manquant plutot que comme une expansion vide -- l erreur nomme donc un
chemin qui n allait jamais exister. Meme remede : fusionner les arbres
avant que package() ne touche a quoi que ce soit.
Cette divergence est apparue deux fois. Si un troisieme paquet la
rencontre, sa place est dans l amorcage partage et non dans des
crochets par paquet.
Assisted-by: Claude Opus 5
crypto/ec/ec_local.h:520:2: error:
"Can not enable ec_nistp_64_gcc_128 on big-endian systems"
Arch enables this elliptic-curve optimisation, which uses a 128-bit
integer representation that assumes little-endian byte order. s390x is
BIG-endian.
This is the first time in the whole port that endianness -- rather than
word size, instruction set or packaging layout -- decides anything. Ten
packages so far diverged on 32-bit multilib, missing front ends or path
conventions; this one diverges on how bytes are ordered in a word.
OpenSSL refuses at compile time rather than producing wrong results,
which is the right call and makes this one honest to diagnose. Dropping
the flag costs some NIST curve performance and nothing else: the curves
still work through the portable implementation.
--- FR ---
crypto/ec/ec_local.h:520:2: error:
"Can not enable ec_nistp_64_gcc_128 on big-endian systems"
Arch active cette optimisation de courbes elliptiques, qui repose sur
une representation entiere 128 bits supposant l ordre petit-boutiste.
s390x est GROS-boutiste.
C est la premiere fois dans tout le portage que l endianness -- et non
la taille de mot, le jeu d instructions ou la convention de chemins --
tranche quoi que ce soit. Dix paquets ont diverge jusqu ici sur le
multilib 32 bits, des frontaux absents ou des dispositions de
repertoires ; celui-ci diverge sur l ordre des octets dans un mot.
OpenSSL refuse a la compilation plutot que de produire des resultats
faux, ce qui est le bon choix et rend ce cas honnete a diagnostiquer.
Retirer l option coute un peu de performance sur les courbes NIST, et
rien d autre : elles fonctionnent par l implementation portable.
Assisted-by: Claude Opus 5
The PKGBUILD composes its target as "linux-$CARCH", giving
linux-s390x. That IS a valid OpenSSL target -- it is the 31-bit one.
The 64-bit target is linux64-s390x.
This one hid well. The log ends on
Configuring OpenSSL version 3.6.3 for target linux-s390x
and then fails, with the failure appearing to come from nowhere: the
target name is right there, it looks correct, and nothing says the
build is 31-bit on a 64-bit system. Four rounds of keyword grepping
found nothing, because the answer was not in the log at all -- it was
in the PKGBUILD, one line above the command that printed it.
The PKGBUILD already special-cases exactly this for riscv64, so s390x
joins that case rather than getting a mechanism of its own.
filesystem now builds: the gid 11 the host was missing was the whole
of it.
--- FR ---
Le PKGBUILD compose sa cible en « linux-$CARCH », ce qui donne
linux-s390x. C EST une cible OpenSSL valide -- celle du 31 bits. La
cible 64 bits s appelle linux64-s390x.
Celle-la se cachait bien. Le journal s acheve sur
Configuring OpenSSL version 3.6.3 for target linux-s390x
puis echoue, et l echec semble venir de nulle part : le nom de la cible
est la, il a l air juste, et rien ne dit qu on batit du 31 bits sur un
systeme 64 bits. Quatre tours de recherche par mots-cles n ont rien
trouve, parce que la reponse n etait pas dans le journal -- elle etait
dans le PKGBUILD, une ligne au-dessus de la commande qui l imprimait.
Le PKGBUILD traite deja exactement ce cas pour riscv64 ; s390x rejoint
donc cette branche plutot que d obtenir un mecanisme a lui.
filesystem se construit desormais : le gid 11 absent de l hote etait
tout le probleme.
Assisted-by: Claude Opus 5
mv: cannot stat 'usr/lib/libquadmath.a': No such file or directory
libquadmath implements __float128, which exists on x86 and ia64. On
s390x the directory is CONFIGURED -- it holds a Makefile, a config.log
and a config.status -- but no library is ever built. The half-created
directory is what makes this one confusing: it looks like a build that
failed rather than a target that has nothing to build.
Dropped from pkgname, from the _pick lines, and from the depends entry
in another sub-package. That last one matters: with --nodeps it is
harmless at build time and fatal at install time, which is exactly the
kind of defect that surfaces long after the build that introduced it.
package_libquadmath() is left in place. makepkg never calls a function
whose name is absent from pkgname, so removing it would be churn.
util-linux calls "python", which Ubuntu does not provide -- only
python3. python-is-python3 supplies the name.
--- FR ---
mv: cannot stat 'usr/lib/libquadmath.a': No such file or directory
libquadmath implemente __float128, qui existe sur x86 et ia64. Sur
s390x le repertoire est CONFIGURE -- il contient un Makefile, un
config.log et un config.status -- mais aucune bibliotheque n y est
jamais batie. C est ce repertoire a moitie cree qui rend le cas
trompeur : il a l air d une compilation ratee plutot que d une cible
qui n a rien a construire.
Retire de pkgname, des lignes _pick, et de la declaration depends d un
autre sous-paquet. Ce dernier point compte : avec --nodeps il est
inoffensif a la compilation et fatal a l installation, exactement le
genre de defaut qui se revele longtemps apres la compilation qui l a
introduit.
package_libquadmath() reste en place. makepkg n appelle jamais une
fonction dont le nom est absent de pkgname ; la retirer serait du
bruit.
util-linux appelle « python », qu Ubuntu ne fournit pas -- seulement
python3. python-is-python3 fournit le nom.
Assisted-by: Claude Opus 5
package_gcc() reached its very last step and stopped on one file:
mv: cannot stat 'usr/lib/libgfortran.spec': No such file or directory
The file exists, in usr/lib64/libgfortran.spec. lib64 is GCC's default
MULTILIB_OSDIRNAMES for 64-bit Z, while Arch puts everything in
usr/lib. So this is not one stray path: the whole package layout
differs, and every _pick naming usr/lib would miss the same way.
The trees are merged before any _pick runs, which leaves the upstream
package definitions working unchanged rather than rewriting each path
one at a time -- and keeps working if Arch adds a _pick later.
curl now builds, with HTTP/3 disabled and patchelf on the host.
--- FR ---
package_gcc() atteignait sa toute derniere etape et s arretait sur un
seul fichier :
mv: cannot stat 'usr/lib/libgfortran.spec': No such file or directory
Le fichier existe, dans usr/lib64/libgfortran.spec. lib64 est le
MULTILIB_OSDIRNAMES par defaut de GCC pour Z en 64 bits, quand Arch
place tout dans usr/lib. Ce n est donc pas un chemin isole : toute la
disposition du paquet differe, et chaque _pick nommant usr/lib
echouerait de la meme facon.
Les arbres sont fusionnes avant le premier _pick, ce qui laisse les
definitions amont fonctionner sans retouche plutot que de reecrire
chaque chemin un a un -- et continue de tenir si Arch ajoute un _pick
plus tard.
curl se construit desormais, HTTP/3 desactive et patchelf pose sur
l hote.
Assisted-by: Claude Opus 5
gcc failed on what looked like a missing header:
/usr/include/strings.h:23:10: fatal error:
.../gcc-build/prev-gcc/include/stddef.h: No such file or directory
The file was PRESENT when the tree was inspected afterwards. It is not
missing: it is generated by a rule that another rule consumes without
declaring the dependency, and with MAKEFLAGS=-j16 sixteen jobs win that
race often enough to fail. Read as an absent header, it sends you
hunting through include paths for nothing -- and past a set of host
symlinks that were, this time, innocent.
The bound goes into build() inside the PKGBUILD. My first attempt
exported MAKEFLAGS from the hook, which cannot work: hooks run in their
own bash process and never reach makepkg. gcc is the only package here
that bootstraps itself three times, so the limit is local to it.
util-linux wanted libmagic; curl wanted patchelf. Both installed.
--- FR ---
gcc echouait sur ce qui ressemblait a un en-tete manquant :
/usr/include/strings.h:23:10: fatal error:
.../gcc-build/prev-gcc/include/stddef.h: No such file or directory
Le fichier etait PRESENT a l inspection de l arbre apres coup. Il ne
manque pas : il est produit par une regle qu une autre consomme sans
declarer la dependance, et avec MAKEFLAGS=-j16 seize taches gagnent
cette course assez souvent pour echouer. Lu comme un en-tete absent, il
fait fouiller les chemins d inclusion pour rien -- et soupconner des
liens symboliques d hote qui, cette fois, etaient innocents.
La borne va dans build(), a l interieur du PKGBUILD. Ma premiere
tentative exportait MAKEFLAGS depuis le crochet, ce qui ne peut pas
fonctionner : les crochets tournent dans leur propre processus bash et
n atteignent jamais makepkg. gcc est le seul paquet ici a s amorcer
trois fois, la limite lui reste donc locale.
util-linux reclamait libmagic ; curl reclamait patchelf. Poses tous deux.
Assisted-by: Claude Opus 5