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
84 lines
3.8 KiB
Bash
Executable file
84 lines
3.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# dbus: three documentation generators, made mandatory by arch-meson.
|
|
#
|
|
# The build stopped three times in a row, on a different tool each time:
|
|
#
|
|
# ERROR: Program 'ducktype' not found or not executable
|
|
# ERROR: Program 'yelp-build' not found or not executable
|
|
# ERROR: Program 'qhelpgenerator qhelpgenerator-qt5' not found
|
|
#
|
|
# Each looked like its own missing host package, and the first two were duly
|
|
# installed. THE TRAP is that chasing them one at a time is the wrong shape:
|
|
# the third needs Qt, so the chain does not terminate anywhere reasonable, and
|
|
# none of the three was ever really required.
|
|
#
|
|
# meson.build asks for them like this:
|
|
#
|
|
# doxygen = find_program('doxygen', required: get_option('doxygen_docs'))
|
|
# ducktype = find_program('ducktype', required: get_option('ducktype_docs'))
|
|
# yelpbuild = find_program('yelp-build', required: get_option('ducktype_docs'))
|
|
# qhelpgen = find_program('qhelpgenerator', ..., required: get_option('qt_help'))
|
|
#
|
|
# and all three options are features declared with no value -- 'auto'.
|
|
# arch-meson passes --auto-features enabled, which promotes every one of them
|
|
# to a hard requirement. On Arch that is harmless: the doc tools are in the
|
|
# build chroot. Here it turned optional documentation into three consecutive
|
|
# build failures. Same mechanism as util-linux's translated man pages and
|
|
# expat's docbook converter; dbus is just the clearest instance, because it
|
|
# repeated three times in one afternoon.
|
|
#
|
|
# xml_docs is deliberately LEFT ALONE: it generates the man pages through
|
|
# xsltproc, which is installed, and man pages are worth having.
|
|
#
|
|
# The dbus-docs sub-package goes with the options. Its `_pick docs
|
|
# usr/share/doc` is a mv, so with nothing generated it would fail the way
|
|
# every other _pick on an absent path in this port has failed -- after a
|
|
# successful compile, at the last step, naming a directory rather than a
|
|
# reason. Deferred, not architectural: TODO.md records the way back.
|
|
set -euo pipefail
|
|
python3 - <<'PY'
|
|
import io, re
|
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
|
|
|
# (a) pin the three features off, beside the options already being pinned
|
|
anchor = " -D apparmor=disabled\n"
|
|
assert s.count(anchor) == 1, "dbus: meson_options array not in the expected form"
|
|
s = s.replace(anchor,
|
|
anchor +
|
|
" -D doxygen_docs=disabled\n"
|
|
" -D ducktype_docs=disabled\n"
|
|
" -D qt_help=disabled\n", 1)
|
|
|
|
# (b) the sub-package that would have nothing to package
|
|
m = re.search(r"pkgname=\((.*?)\)\n", s, re.S)
|
|
assert m, "dbus: pkgname array not found"
|
|
names = [n for n in re.findall(r"[A-Za-z0-9._+-]+", m.group(1))]
|
|
assert "dbus-docs" in names, "dbus: dbus-docs not in pkgname"
|
|
kept = [n for n in names if n != "dbus-docs"]
|
|
s = s[:m.start()] + "pkgname=(\n" + "".join(" %s\n" % n for n in kept) + ")\n" + s[m.end():]
|
|
|
|
# (c) and the _pick that feeds it
|
|
old = ' _pick docs "$pkgdir"/usr/share/doc\n'
|
|
assert s.count(old) == 1, "dbus: docs _pick not in the expected form"
|
|
s = s.replace(old, "", 1)
|
|
|
|
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
|
|
PY
|
|
for o in doxygen_docs ducktype_docs qt_help; do
|
|
grep -qF -- "-D $o=disabled" PKGBUILD || {
|
|
echo "dbus: $o not pinned off" >&2; exit 1; }
|
|
done
|
|
grep -qF '_pick docs' PKGBUILD && {
|
|
echo "dbus: docs _pick survived and would fail on an absent path" >&2; exit 1; }
|
|
python3 - <<'PY'
|
|
import io, re, sys
|
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
|
m = re.search(r"pkgname=\((.*?)\)\n", s, re.S)
|
|
if not m:
|
|
sys.exit("dbus: pkgname array unreadable after patching")
|
|
names = re.findall(r"[A-Za-z0-9._+-]+", m.group(1))
|
|
if "dbus-docs" in names:
|
|
sys.exit("dbus: dbus-docs still declared in pkgname")
|
|
print("dbus: pkgname -> %s" % " ".join(names))
|
|
PY
|
|
echo "dbus: doc generators pinned off (--auto-features made three of them fatal)"
|