[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
This commit is contained in:
parent
92c5850e53
commit
c78c263312
4 changed files with 161 additions and 1 deletions
45
patches/pkgbuild/cmake.sh
Executable file
45
patches/pkgbuild/cmake.sh
Executable file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# cmake: --qt-gui, on a machine with no display and no Qt.
|
||||||
|
#
|
||||||
|
# CMake Error at Source/QtDialog/CMakeLists.txt:33 (message):
|
||||||
|
# Error when bootstrapping CMake:
|
||||||
|
#
|
||||||
|
# cmake-gui is a Qt application. Arch lists qt6-base in makedepends and builds
|
||||||
|
# it; this port has no Qt and will not grow one to give a bootstrap a dialog
|
||||||
|
# box. Same reasoning as pinentry's Qt front end, and the cost is the same
|
||||||
|
# thing: a graphical program nothing here can display.
|
||||||
|
#
|
||||||
|
# WHY cmake IS IN STAGE 1 AT ALL, since it is worth being clear that this is
|
||||||
|
# not scope creep: four PKGBUILDs call cmake directly, and stage 2 rebuilds
|
||||||
|
# every package inside a chroot that has to contain the build systems. cmake
|
||||||
|
# is a tool the REBUILD needs, not a dependency of anything in the repository
|
||||||
|
# -- which is why the dependency resolver never asked for it.
|
||||||
|
#
|
||||||
|
# --sphinx-man and --sphinx-html stay: sphinx-build is installed, and the man
|
||||||
|
# pages are worth having.
|
||||||
|
#
|
||||||
|
# The makedepends entry goes with the flag. Nothing checks it under --nodeps,
|
||||||
|
# but a package declaring a build dependency it does not use is the same
|
||||||
|
# untruth as gcc-libs declaring libhwasan -- and leaving it would tell the
|
||||||
|
# next reader that Qt was needed here.
|
||||||
|
set -euo pipefail
|
||||||
|
python3 - <<'ZZPY'
|
||||||
|
import io
|
||||||
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
||||||
|
|
||||||
|
old = " --qt-gui \\\n"
|
||||||
|
assert s.count(old) == 1, "cmake: expected exactly one --qt-gui"
|
||||||
|
s = s.replace(old, "", 1)
|
||||||
|
|
||||||
|
old = " qt6-base)"
|
||||||
|
assert s.count(old) == 1, "cmake: makedepends tail not in the expected form"
|
||||||
|
s = s.replace(old, " )", 1)
|
||||||
|
|
||||||
|
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
|
||||||
|
ZZPY
|
||||||
|
grep -q -- '--qt-gui' PKGBUILD && { echo "cmake: --qt-gui survived" >&2; exit 1; }
|
||||||
|
sed -n '/^makedepends=(/,/)/p' PKGBUILD | grep -q 'qt6-base' && {
|
||||||
|
echo "cmake: qt6-base still in makedepends" >&2; exit 1; }
|
||||||
|
grep -q -- '--sphinx-man' PKGBUILD || {
|
||||||
|
echo "cmake: man pages lost with the GUI" >&2; exit 1; }
|
||||||
|
echo "cmake: --qt-gui dropped (no Qt, no display)"
|
||||||
78
patches/pkgbuild/python.sh
Executable file
78
patches/pkgbuild/python.sh
Executable file
|
|
@ -0,0 +1,78 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# python: an unbounded loop that hunts for a free X display number.
|
||||||
|
#
|
||||||
|
# build() ends with:
|
||||||
|
#
|
||||||
|
# export servernum=99
|
||||||
|
# while ! xvfb-run -a -n "$servernum" /bin/true 2>/dev/null; do
|
||||||
|
# servernum=$((servernum+1))
|
||||||
|
# done
|
||||||
|
# LC_CTYPE=en_US.UTF-8 xvfb-run -s "-screen 0 1920x1080x16 ..." -a \
|
||||||
|
# -n "$servernum" make EXTRA_CFLAGS="$CFLAGS"
|
||||||
|
#
|
||||||
|
# xvfb-run is not installed here. It fails with 127, `!` inverts that to true,
|
||||||
|
# servernum increments, and the loop tries again. FOREVER. There is no exit
|
||||||
|
# condition for "the command does not exist" -- the loop can only end by
|
||||||
|
# finding a display, and it never will.
|
||||||
|
#
|
||||||
|
# THE TRAP IS THE `2>/dev/null`. It swallows the one line that would have
|
||||||
|
# explained everything. Measured before it was killed: ten hours of wall
|
||||||
|
# clock, four million PIDs consumed, and a build log frozen at
|
||||||
|
# `configure: creating Makefile` -- not one byte of output in ten hours. strace
|
||||||
|
# showed clone/wait4 pairs returning status 127 and no execve at all, because
|
||||||
|
# bash gives up before exec when a command is not on PATH.
|
||||||
|
#
|
||||||
|
# It also defeated every heuristic I had for "is the build progressing":
|
||||||
|
# the process was alive, burning 40% CPU, with a plausible cwd of
|
||||||
|
# .../pkg/python/src/Python-3.14.7. A stalled LOG next to a running makepkg is
|
||||||
|
# the signal that finds this; a process list is not.
|
||||||
|
#
|
||||||
|
# WHY REMOVE RATHER THAN INSTALL xvfb. Arch wraps the build in a virtual
|
||||||
|
# display so that steps which touch tkinter or IDLE have one. A headless
|
||||||
|
# `make` does not need it -- and stage 2 rebuilds this inside a chroot that
|
||||||
|
# will have no xvfb either, so installing it on the host would fix one stage
|
||||||
|
# and leave the other spinning for ten hours. The wrapper goes, in both.
|
||||||
|
#
|
||||||
|
# THE SAME LOOP IS IN check(), and that one matters more, not less. Stage 1
|
||||||
|
# passes --nocheck so it never ran -- but stage 2 drops --nocheck on purpose,
|
||||||
|
# because that is where a test suite finally means something. It would have
|
||||||
|
# spun there for ten hours too, on a build nobody was watching. Both copies
|
||||||
|
# go, and the guard counts them rather than trusting one substitution.
|
||||||
|
#
|
||||||
|
# xorg-server-xvfb leaves makedepends with them: it is a package this port
|
||||||
|
# does not build, so declaring it would be one more entry asking for
|
||||||
|
# something that will never exist -- the class of gcc-libs/libhwasan.
|
||||||
|
set -euo pipefail
|
||||||
|
python3 - <<'PYX'
|
||||||
|
import io, re
|
||||||
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
||||||
|
|
||||||
|
# (a) BOTH loops -- build() and check() -- comment line included.
|
||||||
|
pat = (r"\n *# Obtain next free server number[^\n]*\n"
|
||||||
|
r" *export servernum=99\n"
|
||||||
|
r" *while ! xvfb-run[^\n]*\n")
|
||||||
|
n = len(re.findall(pat, s))
|
||||||
|
assert n == 2, "python: expected 2 xvfb servernum loops, found %d" % n
|
||||||
|
s = re.sub(pat, "\n", s)
|
||||||
|
|
||||||
|
# (b) every xvfb-run wrapper, whatever it wraps.
|
||||||
|
pat2 = r'xvfb-run (?:-s "[^"]*" )?-a -n "\$servernum" '
|
||||||
|
m = len(re.findall(pat2, s))
|
||||||
|
assert m >= 1, "python: no xvfb-run wrapper found"
|
||||||
|
s = re.sub(pat2, "", s)
|
||||||
|
|
||||||
|
# (c) the makedepend on a package this port does not build.
|
||||||
|
old = "'gdb' 'xorg-server-xvfb' 'ttf-font'"
|
||||||
|
assert s.count(old) == 1, "python: makedepends not in the expected form"
|
||||||
|
s = s.replace(old, "'gdb' 'ttf-font'", 1)
|
||||||
|
|
||||||
|
assert "xvfb" not in s, "python: an xvfb reference survived"
|
||||||
|
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
|
||||||
|
print("python: %d xvfb wrapper(s) and 2 loops removed" % m)
|
||||||
|
PYX
|
||||||
|
grep -q 'xvfb' PKGBUILD && { echo "python: xvfb still referenced" >&2; exit 1; }
|
||||||
|
grep -qF 'LC_CTYPE=en_US.UTF-8 make EXTRA_CFLAGS="$CFLAGS"' PKGBUILD || {
|
||||||
|
echo "python: the build make line was not rebuilt correctly" >&2; exit 1; }
|
||||||
|
grep -q 'servernum' PKGBUILD && {
|
||||||
|
echo "python: a servernum reference survived" >&2; exit 1; }
|
||||||
|
echo "python: xvfb-run wrapper and its unbounded servernum loop removed"
|
||||||
|
|
@ -119,6 +119,36 @@ install_host_deps() {
|
||||||
# stage 1 only because STAGE 2 needs it: 51 of the 159 PKGBUILDs take their
|
# stage 1 only because STAGE 2 needs it: 51 of the 159 PKGBUILDs take their
|
||||||
# sources from git+https, and makepkg validates that clone even under
|
# sources from git+https, and makepkg validates that clone even under
|
||||||
# --noextract. Nothing in the repository depends on git.
|
# --noextract. Nothing in the repository depends on git.
|
||||||
|
#
|
||||||
|
# libmpdec-dev is python's, and it is not optional: Python 3.13 removed the
|
||||||
|
# vendored libmpdec, so --with-system-libmpdec is the only way to build and
|
||||||
|
# it needs the system headers. Without them the failure is
|
||||||
|
#
|
||||||
|
# No rule to make target 'Modules/_decimal/libmpdec/basearith.h'
|
||||||
|
#
|
||||||
|
# nine hundred lines into a PGO build -- a missing header reported as a
|
||||||
|
# missing make rule for a file that used to be vendored.
|
||||||
|
#
|
||||||
|
# The last line is the meson/cmake round, and every entry is a tool those
|
||||||
|
# two need to describe themselves: setuptools-scm and yaml for meson's own
|
||||||
|
# build, sphinx for libuv's docs, rhash and nlohmann-json for cmake and
|
||||||
|
# cppdap. Note what they are NOT: none is a dependency of the software
|
||||||
|
# being ported. They are the cost of the build system, which is why the
|
||||||
|
# dependency resolver never mentioned one of them.
|
||||||
|
#
|
||||||
|
# strictyaml, not yaml: meson's docs/meson.build asks for the module by
|
||||||
|
# name and PyYAML does not answer to it. `python3-yaml` was installed
|
||||||
|
# first, the error did not move, and only makedepends said which one --
|
||||||
|
# `python-strictyaml`. Reading the PKGBUILD would have been quicker than
|
||||||
|
# reading the error.
|
||||||
|
#
|
||||||
|
# cmake asked for four of these one at a time -- rhash, then jsoncpp, then
|
||||||
|
# cppdap -- because its bootstrap prefers a system copy of everything it
|
||||||
|
# bundles. That is a queue, and the rule says a queue is a feature to
|
||||||
|
# disable. It is not applied here for once, and deliberately: each one
|
||||||
|
# exists as an Ubuntu -dev package, so the queue terminates. The rule is
|
||||||
|
# about queues with no end, like dbus asking for a third documentation
|
||||||
|
# tool that needed Qt.
|
||||||
sudo apt-get -o DPkg::Lock::Timeout=600 install -y -qq \
|
sudo apt-get -o DPkg::Lock::Timeout=600 install -y -qq \
|
||||||
meson ninja-build pkg-config gettext \
|
meson ninja-build pkg-config gettext \
|
||||||
libarchive-dev libcurl4-openssl-dev libgpgme-dev libssl-dev \
|
libarchive-dev libcurl4-openssl-dev libgpgme-dev libssl-dev \
|
||||||
|
|
@ -145,7 +175,10 @@ install_host_deps() {
|
||||||
autoconf-archive ducktype \
|
autoconf-archive ducktype \
|
||||||
yelp-tools liblmdb-dev libcmocka-dev libverto-dev uthash-dev \
|
yelp-tools liblmdb-dev libcmocka-dev libverto-dev uthash-dev \
|
||||||
libtasn1-bin libevent-dev libaio-dev mercurial libnspr4-dev \
|
libtasn1-bin libevent-dev libaio-dev mercurial libnspr4-dev \
|
||||||
libglib2.0-dev libsecret-1-dev
|
libglib2.0-dev libsecret-1-dev libmpdec-dev \
|
||||||
|
python3-setuptools-scm python3-yaml python3-sphinx \
|
||||||
|
librhash-dev nlohmann-json3-dev python3-strictyaml libjsoncpp-dev \
|
||||||
|
libcppdap-dev
|
||||||
install_host_shims
|
install_host_shims
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,10 @@ CHROOT_PKGS=(
|
||||||
# git: 51 PKGBUILDs use git sources, and makepkg validates the clone even
|
# git: 51 PKGBUILDs use git sources, and makepkg validates the clone even
|
||||||
# under --noextract.
|
# under --noextract.
|
||||||
git
|
git
|
||||||
|
# meson and cmake, with the python they are written in. Ten PKGBUILDs
|
||||||
|
# call arch-meson and four call cmake, so without these stage 2 could
|
||||||
|
# rebuild most of the repository and then stop.
|
||||||
|
python meson ninja cmake
|
||||||
)
|
)
|
||||||
|
|
||||||
log() { printf '\n== %s ==\n' "$*"; }
|
log() { printf '\n== %s ==\n' "$*"; }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue