Commit graph

53 commits

Author SHA1 Message Date
ff65121058 [FIX] systemd without AppArmor, gpgme without its test harness, groff without a logo
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
2026-08-22 22:02:56 -04:00
2fd675ce6b [FIX] libaio, and two packages that installed man pages nobody wrote
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
2026-08-22 22:00:00 -04:00
ca355190c0 [FIX] binutils' extra targets were x86_64's, and gcc only wanted man pages
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
2026-08-22 21:52:39 -04:00
f67796d04c [FIX] sqlite, libpsl and util-linux
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
2026-08-22 07:33:10 -04:00
4eca3612f9 [ADD] nlohmann-json, and three more packages without their docs
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
2026-08-22 02:32:55 -04:00
e5c6835234 [FIX] libxcrypt: a compiler newer than the release expects
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
2026-08-22 00:08:00 -04:00
adb6c4f21d [FIX] four more packages that build without their documentation
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
2026-08-22 00:07:14 -04:00
07486af2fa [FIX] systemd without BPF, pacman without asciidoc
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
2026-08-21 21:25:20 -04:00
9936d8f873 [FIX] binutils: delete the option, do not comment it out
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
2026-08-21 16:53:49 -04:00
09aa24c46a [FIX] three packages shipped 180 unreachable module paths
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
2026-08-21 16:49:37 -04:00
c3916d3982 [ADD] Python packaging, through Arch's own bootstrap path
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
2026-08-21 16:37:55 -04:00
f2aff788ec [FIX] the chroot could not resolve a name, and wget could not fix itself
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
2026-08-21 16:29:10 -04:00
a42e43bcf1 [FIX] binutils: no PGO+LTO build, so gold links
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
2026-08-21 04:16:20 -04:00
613fb66ee0 [FIX] filesystem: give s390x the lib64 compatibility symlinks
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
2026-08-21 00:54:14 -04:00
f380f3fd66 [FIX] one stray .a file broke every pkg-config lookup
libxslt reported

  configure: error: Package requirements (python-3.14) were not met:
  Package 'python-3.14' not found

with python 3.14.7 installed and /usr/lib/pkgconfig/python-3.14.pc present. The
chain, none of whose links resembles the others:

  binutils installs libiberty.a into /usr/lib64, because s390x's default
  MULTILIB_OSDIRNAME is lib64, creating that path as a REAL directory. meson
  chooses its default libdir by inspecting the system, and 64-bit plus a real
  /usr/lib64 means lib64 -- a symlink does not count, which is why Arch never
  sees this and arch-meson passes no --libdir at all. pkgconf is a meson
  package, so it installed there and COMPILED IN /usr/lib64/pkgconfig as its
  search path. Every .pc in the distribution is in /usr/lib/pkgconfig.

Fixed at all three levels: binutils pinned to --libdir=/usr/lib, the chroot's
arch-meson wrapper pins --libdir lib as a backstop, and the ARTEFACT check --
which said "no Debian multiarch libdir anywhere", truthfully and uselessly --
now also counts paths under usr/lib64.

--- FR ---

libxslt annonçait

  configure: error: Package requirements (python-3.14) were not met:
  Package 'python-3.14' not found

avec python 3.14.7 installé et /usr/lib/pkgconfig/python-3.14.pc bien présent.
La chaîne, dont aucun maillon ne ressemble aux autres :

  binutils dépose libiberty.a dans /usr/lib64, le MULTILIB_OSDIRNAME par défaut
  de s390x, et crée donc ce chemin comme VRAI répertoire. meson choisit son
  libdir par défaut en inspectant le système : 64 bits plus un vrai /usr/lib64
  donne lib64 — un lien ne compte pas, d'où le fait qu'Arch ne voit jamais cela
  et qu'arch-meson ne passe aucun --libdir. pkgconf étant un paquet meson, il
  s'y est installé et a COMPILÉ /usr/lib64/pkgconfig comme chemin de recherche.
  Or tous les .pc de la distribution sont dans /usr/lib/pkgconfig.

Corrigé aux trois niveaux : binutils épinglé à --libdir=/usr/lib, l'enveloppe
arch-meson du chroot épingle --libdir lib en filet, et le test ARTEFACT — qui
répondait « aucun libdir multiarch Debian », véridiquement et inutilement —
compte désormais aussi les chemins sous usr/lib64.

Assisted-by: Claude Opus 5
2026-08-21 00:47:09 -04:00
ef143aac67 [FIX] s390x: say which machine this port targets
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
2026-08-21 00:23:26 -04:00
eafa3355aa [FIX] stage 2: the build tools the host was providing silently
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
2026-08-20 01:34:41 -04:00
f6199bdb16 [FIX] stage 2: produce its first package
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
2026-08-20 01:12:14 -04:00
4d8856b82d [FIX] stage 2: x86_64 compiler flags, and a .pc naming nothing
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
2026-08-19 20:19:37 -04:00
adc508d8f6 [FIX] python packages: /usr/local, once, for all of them
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
2026-08-19 20:19:37 -04:00
c78c263312 [ADD] the build systems stage 2 rebuilds with
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
2026-08-19 19:53:46 -04:00
d5b8158e55 [ADD] stage 2: the rebuild loop, and git to feed it
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
2026-08-19 08:56:41 -04:00
22b101dc47 [FIX] gcc: two defects only a chroot could find
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
2026-08-19 08:30:49 -04:00
6f44fdb572 [FIX] lvm2: only device-mapper, and the closure closes
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
2026-08-19 06:40:50 -04:00
82a231e5f9 [ADD] test-chroot: read the binaries, not the declarations
The resolver reported satisfied. The rootfs installed 102 packages. bash,
coreutils, tar, sed and find all ran inside the chroot, on s390x, against
glibc 2.44. Every check passed.

Then a fourth check, reading ELF headers instead of metadata, found seventeen
libraries that some shipped binary asks for and no shipped package provides.
Most are the ordinary stage-1 artefact -- the host's soname where Arch's
differs, libgpgme.so.11 against our .45 -- and stage 2 dissolves those by
rebuilding inside the chroot.

One was not. kbd's loadkeys needed libxkbcommon.so.0 while kbd declared
glibc, gzip and pam. An UNDER-DECLARED dependency: invisible to pacman's
resolver and to this port's own closure computation, because both read
declarations. And the cause was mine -- libxkbcommon-dev went into
install_host_deps for systemd, and kbd, built later, probed for it and linked
it. Arch declares it nowhere, so its chroot fails the same probe;
--disable-xkb converges rather than diverges.

Also here: the test now uses its own package cache. The shared one held a
coreutils from before its selinux fix, at the same pkgver-pkgrel, and pacman
called it corrupted.

--- FR ---

Le résolveur se déclarait satisfait. Le rootfs installait 102 paquets. bash,
coreutils, tar, sed et find tournaient tous dans le chroot, sur s390x, contre
la glibc 2.44. Toutes les vérifications passaient.

Puis une quatrième, lisant les en-têtes ELF au lieu des métadonnées, a trouvé
dix-sept bibliothèques qu'un binaire livré réclame et qu'aucun paquet livré ne
fournit. La plupart sont l'artefact ordinaire de l'étage 1 — le soname de
l'hôte là où celui d'Arch diffère, libgpgme.so.11 contre notre .45 — et
l'étage 2 les dissout en reconstruisant dans le chroot.

Une ne l'était pas. Le loadkeys de kbd réclamait libxkbcommon.so.0 quand kbd
déclarait glibc, gzip et pam. Une dépendance SOUS-DÉCLARÉE : invisible au
résolveur de pacman comme au calcul de fermeture de ce portage, puisque tous
deux lisent des déclarations. Et la cause était mienne — libxkbcommon-dev est
entré dans install_host_deps pour systemd, et kbd, bâti plus tard, l'a sondé
et lié. Arch ne le déclare nulle part, son chroot échoue donc à la même
sonde ; --disable-xkb converge au lieu de diverger.

Aussi ici : le test utilise désormais son propre cache de paquets. Le cache
partagé gardait un coreutils d'avant son correctif selinux, au même
pkgver-pkgrel, et pacman le déclarait corrompu.

Assisted-by: Claude Opus 5
2026-08-19 06:24:11 -04:00
cb13d98b2b [FIX] four hooks the closure's second round needed
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
2026-08-19 06:24:11 -04:00
62233fc747 [ADD] libgcrypt: stage 1 consumes its own libgpg-error
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
2026-08-19 05:28:32 -04:00
09ef26798a [FIX] the build host answered questions the target should
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
2026-08-19 05:28:32 -04:00
3c926f10a9 [FIX] declared, never linked: guile, libisl.so, leancrypto
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
2026-08-19 05:28:32 -04:00
2a1997e06d [REM] sub-packages: four that cost more closure than they carry
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
2026-08-19 05:28:32 -04:00
bda5fe67c5 [FIX] gcc: a dropped component is removed in a fifth place
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
2026-08-17 02:37:46 -04:00
9a696af012 [FIX] host defaults: apt was deciding what got built
--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
2026-08-17 02:37:46 -04:00
dcaa55b19a [ADD] host deps: the tools six packages needed and nobody declared
--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
2026-08-17 01:33:41 -04:00
04ee9be5cc [FIX] selinux: the chroot named a host artefact, not a dependency
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
2026-08-17 01:33:41 -04:00
ddbf91108f [FIX] libdir: the Debian host hid the libraries from Arch
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
2026-08-17 01:33:41 -04:00
f7053490d0 [FIX] grep: the m4 check lives in bootstrap.conf, not bootstrap
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
2026-08-17 00:00:48 -04:00
9ec47f76ff [FIX] grep: neutralise the m4 check, do not skip bootstrap
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
2026-08-16 23:30:49 -04:00
231514904a [FIX] grep: skip its host-vetting bootstrap; util-linux: lib64 again
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
2026-08-16 23:26:54 -04:00
36d726f0a1 [FIX] openssl: s390x is big-endian, drop the little-endian EC path
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
2026-08-16 22:53:33 -04:00
9bc7dbce3e [FIX] openssl: s390x needs the 64-bit Configure target
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
2026-08-16 22:50:01 -04:00
dc0f38987e [FIX] gcc: libquadmath does not exist on s390x; python alias for util-linux
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
2026-08-16 19:52:55 -04:00
bcc6d63bed [FIX] gcc: s390x installs to lib64, Arch expects lib
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
2026-08-16 16:59:53 -04:00
115ea48fb4 [FIX] gcc: bound bootstrap parallelism; libmagic and patchelf on the host
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
2026-08-16 07:13:33 -04:00
00c3909df5 [ADD] TODO.md: track every divergence from upstream Arch
A port that does not track what it gave up drifts silently, and the gap
is found years later by whoever needs the missing feature. Every
deliberate difference is now written down, with the hook that
implements it and what it would take to close it.

The document separates two kinds, because the difference matters.
DEFERRED entries were dropped to get the bootstrap moving -- nothing
about s390x prevents them, they cost build time or a host dependency,
and they should come back. ARCHITECTURAL entries drop something that is
x86-specific by nature; there is nothing to restore, and they are
listed so nobody spends an afternoon rediscovering why.

A third section covers what is neither: environment facts, like
dev.gnupg.org being unreachable from this host, which close themselves
elsewhere.

curl joins the deferred list. Arch builds HTTP/3 through nghttp3 and
ngtcp2; Ubuntu packages neither, and building both to reach HTTP/3 is a
detour when pacman and ERPLibre talk to plain HTTPS mirrors. The
dependency declarations and the soname map go with the configure flags:
left in place, the package would claim to need libraries it no longer
links.

--- FR ---

Un portage qui ne trace pas ce qu il a abandonne derive en silence, et
l ecart se decouvre des annees plus tard par celui a qui la
fonctionnalite manque. Chaque difference deliberee est desormais
consignee, avec le crochet qui la met en oeuvre et ce qu il faudrait
pour la refermer.

Le document separe deux natures, parce que la distinction compte. Les
entrees DIFFEREES ont ete abandonnees pour faire avancer l amorcage --
rien dans s390x ne s y oppose, elles coutent du temps de compilation ou
une dependance d hote, et elles doivent revenir. Les entrees
ARCHITECTURALES retirent ce qui est par nature propre a x86 ; il n y a
rien a restaurer, et elles figurent la pour que personne ne passe un
apres-midi a redecouvrir pourquoi.

Une troisieme section couvre ce qui n est ni l un ni l autre : des
faits d environnement, comme dev.gnupg.org injoignable depuis cet hote,
qui se refermeront ailleurs.

curl rejoint la liste des differes. Arch batit HTTP/3 par nghttp3 et
ngtcp2 ; Ubuntu n empaquete ni l un ni l autre, et les batir tous deux
pour atteindre HTTP/3 est un detour quand pacman et ERPLibre parlent a
des miroirs HTTPS ordinaires. Les declarations de dependance et la
table de sonames partent avec les options de configuration : laissees
en place, le paquet pretendrait dependre de bibliotheques qu il ne lie
plus.

Assisted-by: Claude Opus 5
2026-08-16 05:47:47 -04:00
a67bd94f8b [FIX] gcc: 32-bit paths hidden in brace expansions; more host libraries
Two more shapes of the same multilib assumption, and the second is a
trap worth naming.

Some _pick lines write the 32-bit path in full:

  mv: cannot stat 'usr/lib/gcc/s390x-ibm-linux-gnu/16/32/finclude/'

Others write BOTH paths in one line with a brace expansion --
$_libdir/{,32/}finclude/ expands to the normal path and the 32-bit one.
Deleting such a line would silently lose the path that DOES exist, so
only the alternative is removed: {,32/} and {,32} become nothing.

That distinction matters. A blanket "delete every line mentioning 32"
would have dropped gcc-fortran's finclude, libcaf and libgfortran.spec
from the package, and the loss would only have surfaced later, in
something that failed to link.

Host libraries again: libcryptsetup for util-linux, libgcrypt, libksba
and npth for gnupg, libpam for shadow.

--- FR ---

Deux formes de plus de la meme hypothese multilib, et la seconde est un
piege qui merite d etre nomme.

Certaines lignes _pick ecrivent le chemin 32 bits en entier :

  mv: cannot stat 'usr/lib/gcc/s390x-ibm-linux-gnu/16/32/finclude/'

D autres ecrivent les DEUX chemins d un coup par expansion d accolades
-- $_libdir/{,32/}finclude/ produit le chemin normal et celui en 32
bits. Supprimer une telle ligne perdrait en silence le chemin qui
EXISTE, donc seule l alternative disparait : {,32/} et {,32} deviennent
rien.

La distinction compte. Un « supprimer toute ligne mentionnant 32 »
aurait retire finclude, libcaf et libgfortran.spec du paquet
gcc-fortran, et la perte ne serait apparue que plus tard, dans quelque
chose qui refuse de se lier.

Bibliotheques d hote, encore : libcryptsetup pour util-linux, libgcrypt,
libksba et npth pour gnupg, libpam pour shadow.

Assisted-by: Claude Opus 5
2026-08-16 05:19:20 -04:00
fd18e61dd9 [FIX] gcc: remove the explicit jit install; libpam for shadow and util-linux
Disabling libgccjit took four separate cuts, and this is the fourth.
Removing the second configure pass, the pkgname entry and the _pick
lines still left package_gcc() calling

  make -C gcc DESTDIR="$pkgdir" jit.install-common jit.install-info

which fails on a library that was never built:

  install: cannot install libgccjit.so.0.0.1

The lesson repeats: in an Arch PKGBUILD a component is referenced in
several independent places -- the pkgname array, a build block, _pick
lines in package(), and explicit make targets. Removing it means
finding all four, and grepping for the component name after each cut is
the only way to know.

shadow and util-linux both stop on a missing libpam. Same family as
every host makedepend before them: invisible until a build names it,
because --nodeps forbids pacman from checking.

--- FR ---

Desactiver libgccjit aura demande quatre coupes distinctes, et voici la
quatrieme. Retirer la seconde passe de configuration, l entree de
pkgname et les lignes _pick laissait encore package_gcc() appeler

  make -C gcc DESTDIR="$pkgdir" jit.install-common jit.install-info

qui echoue sur une bibliotheque jamais batie :

  install: cannot install libgccjit.so.0.0.1

La lecon se repete : dans un PKGBUILD d Arch, un composant est
reference en plusieurs endroits independants -- le tableau pkgname, un
bloc de compilation, des lignes _pick dans package(), et des cibles
make explicites. Le retirer suppose de trouver les quatre, et chercher
son nom apres chaque coupe est le seul moyen de le savoir.

shadow et util-linux s arretent tous deux sur un libpam absent. Meme
famille que tous les makedepends d hote precedents : invisibles jusqu a
ce qu une compilation les nomme, puisque --nodeps interdit a pacman de
verifier.

Assisted-by: Claude Opus 5
2026-08-16 03:57:46 -04:00
d72673a3db [FIX] clean the source tree between attempts; strip gcc _pick lines
Four packages -- grep, gnupg, pacman and curl -- were failing on my own
driver, not on the port. makepkg -f rebuilds but does not wipe $srcdir,
so a re-run re-entered the previous attempt's tree:

  patch: ... already exists!  Skipping patch.
  1 out of 1 hunk ignored
  mkdir: build-curl-compat: File exists

makepkg -C now cleans first. Worth stating plainly: those four looked
like port problems for two full rounds, and were not.

gcc: dropping sub-packages from pkgname was not enough. package_gcc()
_picks files out for every front end regardless of what was requested,
and _pick is a mv, so it fails on what was never built:

  mv: cannot stat 'usr/bin/gnat': No such file or directory

The _pick lines for the disabled front ends are removed too.

shadow needed libaudit-dev on the host -- one more makedepend that
--nodeps hides until a build stops on it.

--- FR ---

Quatre paquets -- grep, gnupg, pacman et curl -- echouaient a cause de
mon propre pilote, pas du portage. makepkg -f reconstruit mais ne vide
pas $srcdir, si bien qu une reprise revenait dans l arbre de la
tentative precedente :

  patch: ... already exists!  Skipping patch.
  1 out of 1 hunk ignored
  mkdir: build-curl-compat: File exists

makepkg -C nettoie desormais d abord. A dire clairement : ces quatre-la
ont eu l air de problemes de portage pendant deux tours entiers, et ne
l etaient pas.

gcc : retirer les sous-paquets de pkgname ne suffisait pas.
package_gcc() extrait des fichiers pour chaque frontal quoi qu on ait
demande, et _pick est un mv, donc il echoue sur ce qui n a jamais ete
bati :

  mv: cannot stat 'usr/bin/gnat': No such file or directory

Les lignes _pick des frontaux desactives sont retirees aussi.

shadow reclamait libaudit-dev sur l hote -- un makedepend de plus que
--nodeps masque jusqu a ce qu une compilation s y arrete.

Assisted-by: Claude Opus 5
2026-08-16 02:23:01 -04:00
6eb83c91c3 [ADD] gcc: make libgccjit optional, strip the remaining lib32 work
Arch configures and compiles the whole gcc tree a SECOND time just for
libgccjit, because it needs --enable-host-shared and applying that to
the main compiler would slow it down. That pass is about half of gcc's
build time -- twenty minutes per attempt on this hardware -- and
nothing in the bootstrap or in ERPLibre uses it.

It is now skipped by default and restored with:

    EL_GCC_JIT=1 bash scripts/build-stage1.sh

Verified both ways: off leaves zero libgccjit references in the
PKGBUILD, on leaves the ten upstream ones untouched, including the
--enable-languages=jit line the main-build sed deliberately avoids.

package_gcc() still manipulated the 32-bit tree in several places, and
each fails once multilib is off because usr/lib32 never exists:

  'usr/lib/gcc/s390x-ibm-linux-gnu/16/libatomic.so' -> '../../../libatomic.so'
  ln: No such file or directory

The link named in that error is the one that SUCCEEDED; the failure is
the usr/lib32 line right after it in the same loop. Read alone, it
sends you hunting for a missing libatomic that is in fact present. The
same loop also linked the D runtimes, gone with the D front end.

--- FR ---

Arch configure et compile l arbre gcc entier une SECONDE fois pour le
seul libgccjit, qui reclame --enable-host-shared -- appliquer cette
option au compilateur principal le ralentirait. Cette passe represente
environ la moitie du temps de compilation de gcc, soit vingt minutes
par tentative sur cette machine, et rien dans l amorcage ni dans
ERPLibre ne s en sert.

Elle est desormais ecartee par defaut et se retablit par :

    EL_GCC_JIT=1 bash scripts/build-stage1.sh

Verifie dans les deux sens : desactive, il ne reste aucune reference a
libgccjit dans le PKGBUILD ; active, les dix references amont restent
intactes, y compris la ligne --enable-languages=jit que le sed du
build principal evite deliberement.

package_gcc() manipulait encore l arbre 32 bits en plusieurs endroits,
et chacun echoue une fois le multilib retire, puisque usr/lib32
n existe jamais :

  'usr/lib/gcc/s390x-ibm-linux-gnu/16/libatomic.so' -> '../../../libatomic.so'
  ln: No such file or directory

Le lien nomme dans cette erreur est celui qui a REUSSI ; l echec est la
ligne usr/lib32 juste apres, dans la meme boucle. Lue seule, elle fait
chercher un libatomic manquant qui est pourtant bien la. La meme boucle
liait aussi les runtimes D, partis avec le frontal D.

Assisted-by: Claude Opus 5
2026-08-16 01:54:13 -04:00
63be2a7990 [FIX] gcc: do not rewrite the libgccjit language list
The PKGBUILD configures gcc twice: once for the compiler, once for
libgccjit with --enable-languages=jit. The hook rewrote every
occurrence, so the second tree built a compiler instead of a library
and package() died on

  cp: cannot stat 'gcc/libgccjit.so*': No such file or directory

after forty minutes of compiling -- the worst kind of failure, at the
very end, from a patch that looked right.

The sed now skips any line containing jit. A patch that rewrites "every
occurrence" of anything in a PKGBUILD should be suspected by default:
these files configure the same source tree several times, for different
outputs.

--- FR ---

Le PKGBUILD configure gcc deux fois : une fois pour le compilateur, une
fois pour libgccjit avec --enable-languages=jit. Le crochet reecrivait
toutes les occurrences, si bien que le second arbre batissait un
compilateur au lieu d une bibliotheque, et package() mourait sur

  cp: cannot stat 'gcc/libgccjit.so*': No such file or directory

apres quarante minutes de compilation -- le pire genre d echec, tout a
la fin, venu d un correctif qui semblait juste.

Le sed ecarte desormais toute ligne contenant jit. Un correctif qui
reecrit « toutes les occurrences » de quoi que ce soit dans un PKGBUILD
doit etre suspecte d office : ces fichiers configurent plusieurs fois le
meme arbre source, pour des sorties differentes.

Assisted-by: Claude Opus 5
2026-08-16 01:18:45 -04:00
a61890d83a [FIX] canonical CHOST, and a reachable libassuan source
CHOST was the Debian-style triplet. gcc -dumpmachine reports
s390x-linux-gnu on this host, but config.sub canonicalises that to
s390x-ibm-linux-gnu and GCC builds its tree under the canonical name.

Arch PKGBUILDs assume the canonical form -- theirs is
x86_64-pc-linux-gnu, vendor field present -- so gcc's own PKGBUILD
looked for $CHOST/libstdc++-v3/doc and found nothing:

  make: *** s390x-linux-gnu/libstdc++-v3/doc: No such file or directory

while the build had created s390x-ibm-linux-gnu/libstdc++-v3/doc. This
is a port-wide setting, not a gcc quirk: every PKGBUILD that derives a
path from CHOST was pointing one directory sideways.

libassuan fetches from dev.gnupg.org, which is unreachable from this
build host -- measured HTTP 000, while github.com/gpg/libassuan.git and
gnupg.org/ftp both answer. That is a network fact, not a port problem,
so only the transport changes: the pinned tag is untouched and what
gets built is what Arch specifies.

Host dependencies again: doxygen for xz, libunistring for libpsl,
systemd-dev for util-linux. Every one of them was invisible until a
build stopped on it, because --nodeps means pacman never checks
makedepends.

--- FR ---

CHOST portait le triplet de style Debian. Sur cet hote, gcc
-dumpmachine rend s390x-linux-gnu, mais config.sub le canonise en
s390x-ibm-linux-gnu, et GCC batit son arbre sous le nom canonique.

Les PKGBUILD d Arch supposent la forme canonique -- la leur est
x86_64-pc-linux-gnu, champ constructeur present -- si bien que le
PKGBUILD de gcc cherchait $CHOST/libstdc++-v3/doc sans rien trouver :

  make: *** s390x-linux-gnu/libstdc++-v3/doc: No such file or directory

alors que la compilation avait cree s390x-ibm-linux-gnu/libstdc++-v3/doc.
C est un reglage de portage, pas une bizarrerie de gcc : tout PKGBUILD
derivant un chemin de CHOST visait un repertoire a cote.

libassuan se telecharge depuis dev.gnupg.org, injoignable depuis cet
hote -- mesure : HTTP 000, quand github.com/gpg/libassuan.git et
gnupg.org/ftp repondent tous deux. C est un fait de reseau, pas un
probleme de portage : seul le transport change, l etiquette epinglee
reste intacte et ce qui se batit est ce qu Arch specifie.

Dependances d hote, encore : doxygen pour xz, libunistring pour libpsl,
systemd-dev pour util-linux. Chacune est restee invisible jusqu a ce
qu une compilation s y arrete, parce que --nodeps interdit a pacman de
verifier les makedepends.

Assisted-by: Claude Opus 5
2026-08-16 00:45:50 -04:00