[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
|
|
|
#!/usr/bin/env bash
|
[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
|
|
|
# expat: two defaults decided by the build HOST rather than by the PKGBUILD.
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
# 1. The library directory.
|
[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
|
|
|
#
|
|
|
|
|
# The PKGBUILD calls cmake directly -- NOT arch-cmake -- so the devtools
|
|
|
|
|
# stand-in that already passes -DCMAKE_INSTALL_LIBDIR=lib never runs. The
|
|
|
|
|
# option array only pins the prefix.
|
|
|
|
|
#
|
|
|
|
|
# expat's CMakeLists include(GNUInstallDirs), and GNUInstallDirs picks its
|
|
|
|
|
# default LIBDIR by sniffing the HOST: it sees /etc/debian_version, finds no
|
|
|
|
|
# /etc/arch-release, and sets lib/<multiarch> = lib/s390x-linux-gnu. Because
|
|
|
|
|
# CMAKE_INSTALL_LIBDIR was never given, that default wins and is cached.
|
|
|
|
|
#
|
|
|
|
|
# The build then exits 0 and the package installs cleanly. It is the ARTEFACT
|
|
|
|
|
# that is wrong -- everything LIBDIR-derived lands off Arch's search paths:
|
|
|
|
|
#
|
|
|
|
|
# usr/lib/s390x-linux-gnu/libexpat.so.1.12.3 ld.so reads /usr/lib only
|
|
|
|
|
# usr/lib/s390x-linux-gnu/pkgconfig/expat.pc pkgconf reads /usr/lib only
|
|
|
|
|
# usr/lib/s390x-linux-gnu/cmake/expat-2.8.3/ find_package(EXPAT) misses
|
|
|
|
|
#
|
|
|
|
|
# and usr/lib itself holds nothing but that subdirectory. expat is a
|
|
|
|
|
# dependency of cmake, python, gdb and fontconfig, so this does not fail
|
|
|
|
|
# loudly here -- it fails later, in whatever links against -lexpat.
|
|
|
|
|
#
|
[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
|
|
|
# Passing it on the command line makes it a cache entry BEFORE GNUInstallDirs
|
|
|
|
|
# runs, and GNUInstallDirs only fills in defaults for variables still unset.
|
[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
|
|
|
python3 - <<'PY'
|
|
|
|
|
import io
|
|
|
|
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
|
|
|
|
assert "CMAKE_INSTALL_LIBDIR" not in s, "expat: libdir already set, hook ran twice"
|
|
|
|
|
anchor = " -D CMAKE_INSTALL_PREFIX=/usr\n"
|
|
|
|
|
n = s.count(anchor)
|
|
|
|
|
assert n == 1, "expat: expected 1 cmake option block, found %d" % n
|
|
|
|
|
s = s.replace(anchor, anchor + " -D CMAKE_INSTALL_LIBDIR=lib\n", 1)
|
|
|
|
|
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
|
|
|
|
|
PY
|
|
|
|
|
[ "$(grep -c 'CMAKE_INSTALL_LIBDIR=lib' PKGBUILD)" = 1 ] || {
|
|
|
|
|
echo "expat: libdir not pinned exactly once" >&2; exit 1; }
|
|
|
|
|
echo "expat: CMAKE_INSTALL_LIBDIR=lib (bare cmake bypasses arch-cmake)"
|
[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
|
|
|
|
|
|
|
|
# 2. EXPAT_BUILD_DOCS: pin it OFF, because its default reads the host's PATH.
|
|
|
|
|
#
|
|
|
|
|
# THE TRAP: this option has no fixed default. CMakeLists.txt line 74 does
|
|
|
|
|
#
|
|
|
|
|
# find_program(DOCBOOK_TO_MAN NAMES docbook2x-man db2x_docbook2man \
|
|
|
|
|
# docbook2man docbook-to-man)
|
|
|
|
|
#
|
|
|
|
|
# and turns docs ON if ANY of those four is found. Nothing in the PKGBUILD
|
|
|
|
|
# asks for docs -- makedepends is (cmake git). So whether expat builds a man
|
|
|
|
|
# page is decided by whatever apt happens to have dragged onto the VM.
|
|
|
|
|
#
|
|
|
|
|
# Not hypothetical, and the timeline is the whole lesson. expat built clean on
|
|
|
|
|
# 2026-08-15 21:25 and its package carries no usr/share/man at all. At
|
|
|
|
|
# 2026-08-16 00:23:31 apt installed docbook-utils -- nobody asked for it; it
|
|
|
|
|
# arrived as an automatic dependency of asciidoc, which install_host_deps
|
|
|
|
|
# needs for pacman. docbook-utils owns /usr/bin/docbook2man, the THIRD name in
|
|
|
|
|
# that list. From that moment find_program succeeded and a target that had
|
|
|
|
|
# never run in this port switched itself on. expat was simply not rebuilt for
|
|
|
|
|
# another twenty-nine hours, so the breakage waited.
|
|
|
|
|
#
|
|
|
|
|
# THE ERROR NAMES THE WRONG CULPRIT, twice over:
|
|
|
|
|
#
|
|
|
|
|
# mv: cannot stat 'XMLWF.1': No such file or directory
|
|
|
|
|
#
|
|
|
|
|
# Nothing is wrong with the mv, and XMLWF.1 is the correct name --
|
|
|
|
|
# doc/xmlwf.xml declares <refentrytitle>XMLWF</refentrytitle>, and every
|
|
|
|
|
# docbook man backend derives the filename from it. The real failure is one
|
|
|
|
|
# command earlier and silent: docbook-utils' docbook2man is a two-line shell
|
|
|
|
|
# script, `jw -f docbook -b man "$@"`, i.e. the SGML pipeline. doc/xmlwf.xml
|
|
|
|
|
# is DocBook XML 4.2, whose ISO entity sets use `&#xNNNN;` hex character
|
|
|
|
|
# references that SGML forbids. onsgmls emits `"X2288" is not a function name`
|
|
|
|
|
# two hundred times, gives up -- and jw still EXITS 0, having written only
|
|
|
|
|
# manpage.refs and manpage.links. Those two hundred lines sit ABOVE the
|
|
|
|
|
# failure in the log and read like harmless validation noise.
|
|
|
|
|
#
|
|
|
|
|
# Upstream knows this tool is unusable and rejects it BY NAME in the autotools
|
|
|
|
|
# path: configure.ac:454 greps `${DOCBOOK_TO_MAN} --help` for "sgmlbase" and
|
|
|
|
|
# aborts with "was found to work with SGML rather than XML". Our
|
|
|
|
|
# /usr/bin/docbook2man matches that grep. The CMake path has no such guard.
|
|
|
|
|
#
|
|
|
|
|
# WHY OFF RATHER THAN INSTALLING docbook2x: because OFF is what Arch ships.
|
|
|
|
|
# Arch's core expat 2.8.3 has 29 files and no usr/share/man, which proves
|
|
|
|
|
# Arch's builder has none of those four programs -- any one would have flipped
|
|
|
|
|
# the default. Pinning OFF reproduces Arch exactly; installing docbook2x would
|
|
|
|
|
# make s390x diverge from x86_64 and add one more host tool that silently
|
|
|
|
|
# decides what gets built.
|
|
|
|
|
python3 - <<'PY'
|
|
|
|
|
import io
|
|
|
|
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
|
|
|
|
assert "EXPAT_BUILD_DOCS" not in s, "expat: docs already pinned, hook ran twice"
|
|
|
|
|
anchor = " -D CMAKE_INSTALL_LIBDIR=lib\n"
|
|
|
|
|
n = s.count(anchor)
|
|
|
|
|
assert n == 1, "expat: expected 1 libdir line, found %d" % n
|
|
|
|
|
s = s.replace(anchor, anchor + " -D EXPAT_BUILD_DOCS=OFF\n", 1)
|
|
|
|
|
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
|
|
|
|
|
PY
|
|
|
|
|
[ "$(grep -c 'EXPAT_BUILD_DOCS=OFF' PKGBUILD)" = 1 ] || {
|
|
|
|
|
echo "expat: docs not pinned exactly once" >&2; exit 1; }
|
|
|
|
|
echo "expat: EXPAT_BUILD_DOCS=OFF (default follows host PATH, not the PKGBUILD)"
|