archlinux-s390x/scripts/packages.sh

386 lines
20 KiB
Bash
Raw Normal View History

[IMP] stage 2: resumable, guarded, driven by the shared list Stage 2 could rebuild one named package. It could not rebuild a hundred and thirty-three, for reasons that were all about the driver. The order is not re-derived: it is the closure stage 1 arrived at over four rounds of resolver output and then confirmed by 179 builds, so it moves to packages.sh and both stages read it. make_rootfs wipes the chroot every run, which is what makes it reproducible and what made stage 2 unresumable -- stage2.state outlived the packages it named. Its output is now put back. The stall guard is shared rather than copied: stage 2 needs it more, since a test suite is the likeliest thing in a build to wait forever. Build trees are removed after a package installs, never after it fails. --- FR --- L'étage 2 savait rebâtir un paquet nommé. Il ne savait pas en rebâtir cent trente-trois, pour des raisons qui tenaient toutes au pilote. L'ordre n'est pas réinventé : c'est la fermeture obtenue à l'étage 1 en quatre tours de sortie du résolveur, puis confirmée par 179 constructions. Il passe donc dans packages.sh, que les deux étages lisent. make_rootfs efface le chroot à chaque passage — ce qui le rend reproductible et rendait l'étage 2 irreprenable, stage2.state survivant aux paquets qu'il nommait. Sa production y est désormais réinstallée. La garde d'immobilité est partagée plutôt que recopiée : l'étage 2 en a plus besoin, une suite de tests étant ce qui attend le plus volontiers pour toujours. Les arbres de compilation sont effacés après installation, jamais après un échec. Assisted-by: Claude Opus 5
2026-08-20 01:16:49 -04:00
#!/usr/bin/env bash
# The package list, and the ORDER, shared by both stages.
#
# It lived in build-stage1.sh until stage 2 needed it. Stage 2 rebuilds the
# same packages inside the chroot, and the order it needs is not a new
# question: this one is the actual dependency closure, arrived at over four
# rounds of resolver output (35 unsatisfied, then 19, then 2, then none) and
# then confirmed by a hundred and ninety builds that each found their
# dependencies already present. Deriving a second order for stage 2 would be
# re-deriving a fact this file already holds -- and getting it subtly wrong
# would show up as a build failure attributed to the package rather than to
# the ordering.
#
# Sourced, never executed. Both stages read STAGE1_PACKAGES from here.
STAGE1_PACKAGES=(
# Foundation: headers, then the C library, then the compiler chain.
linux-api-headers glibc binutils gcc
# Compression and crypto, needed by libarchive and curl further down.
zlib bzip2 xz zstd lz4 openssl
# Terminal handling: bash links against readline, readline against ncurses.
ncurses readline
# The shell, and the coreutils prerequisites Arch declares.
attr acl gmp mpfr libcap bash coreutils
# Text and file tools the build systems themselves call.
sed grep gawk findutils diffutils file which patch
# Archivers, then the library pacman reads packages with.
tar gzip expat libarchive
# Build systems.
m4 autoconf automake libtool make pkgconf
# pacman's network and signature stack.
libnghttp2 libpsl curl libgpg-error libassuan gnupg gpgme
# System skeleton: without these a rootfs has no /etc/passwd, no zones,
# no /etc/services -- and nothing boots to a usable shell.
filesystem iana-etc tzdata licenses shadow util-linux
# Named by the chroot test, not guessed. Installing the repo into a
# rootfs and entering it turned "does it work?" into a precise list:
# - libcap needs pam; openssl needs brotli; libarchive needs libxml2
# - pacman itself asks for systemd, pacman-mirrorlist and
# libmakepkg-dropins
# Sixty-eight successful builds proved none of this. One chroot did.
#
# The chroot also named libselinux, and libselinux is NOT on this line,
# because that reading of it was wrong. Arch has no libselinux package at
# all -- the clone 404s. What the chroot saw was a HOST artefact: Ubuntu
# carries libselinux1-dev, coreutils probes for selinux/selinux.h
# unconditionally, and ours came out linked to a library the target will
# never contain. The answer is --without-selinux per package, which is
# what Arch's own build chroot gets for free by not having the header.
pam brotli libxml2 systemd pacman-mirrorlist libmakepkg-dropins
# The closure, named by pacman's own resolver rather than guessed.
#
# Everything above was added because a BUILD stopped. These were added
# because scripts/test-chroot.sh ran `pacman -Syp` with --nodeps OFF --
# the check the whole bootstrap skips -- and the resolver listed exactly
# what the repository still owes. Nothing here is speculative.
#
# It is the MINIMAL closure, and two measurements shaped it. Dropping the
# python-brotli sub-package took the list from 70 unresolved names to 47
# and removed `python` outright, with libffi, mpdecimal and gdbm behind
# it. Dropping systemd-ukify and systemd-tests removed five more python
# packages, and ukify cannot run on s390x at all. Both are recorded in
# TODO.md rather than left implicit.
#
# An audit of the remaining names against the ARTEFACTS found two that
# were declared and never linked: guile by make, and libisl.so by gcc.
# Both get their declaration removed, because it should describe the
# binary we shipped.
#
# Building isl instead was the first plan, and it is recorded here because
# the reason it failed is the kind that wastes an afternoon: the Arch
# packaging repo for isl was last touched in 2017 and its only source URL
# is isl.gforge.inria.fr, which died with INRIA's GForge. There is nothing
# to build. That flipped the decision -- not a change of mind, new
# evidence.
#
# These will pull their own dependencies. That is expected: the resolver
# will name the next round as precisely as it named this one.
audit ca-certificates cryptsetup dbus elfutils gettext gnutls hwdata
icu jansson kbd kmod krb5 libcap-ng libgcrypt libidn2 libksba
libmpc libnsl libseccomp libssh2 libtirpc libunistring libusb libxcrypt
nettle npth openldap pambase pcre2 perl pinentry sqlite tpm2-tss
# Closure, second round. The first thirty-five pulled these in, exactly as
# the comment above predicted, and the resolver named them just as
# precisely.
#
# THE MEASUREMENT THAT MATTERS HERE IS THE ONE THAT CHANGED ITS ANSWER.
# Four of these were going to be avoided by dropping a sub-package --
# sqlite-tcl, sqlite-analyzer, the openldap server, debuginfod -- on the
# reasoning that had removed python-brotli earlier. Measured instead of
# assumed, tcl, unixodbc and libmicrohttpd each cost ZERO new packages:
# the closure had filled in around them. Building them is cheaper than
# four hooks, and it does not leave sqlite shipping an sqltclsh that
# cannot start.
#
# python still costs three (libffi, mpdecimal, gdbm) and is still avoided
# -- but for the ABI reason, not the cost one: python-audit and
# python-capng are cp313 wheels and Arch ships 3.14. Their hooks say so.
#
db5.3 gdbm e2fsprogs gnulib-l10n json-c keyutils p11-kit libsasl
libsodium libtasn1 libverto lmdb popt lvm2 tcl unixodbc libmicrohttpd
# ca-certificates-mozilla, which is the only thing here that is not a
# library. It is the LIST OF ROOT CERTIFICATES -- ca-certificates itself
# is only the trust machinery around it, so without this the target has a
# trust store containing nothing, and every HTTPS verification fails.
# curl declares ca-certificates, and pacman fetches through curl.
#
# It has no packaging repo of its own: the clone 404s, which
# gitlab.archlinux.org reports by asking for a login -- the same
# misleading shape that made libselinux look like a network problem. nss
# produces it as a sub-package, so nss is what gets built, and nspr comes
# with it.
#
# Measured before committing to it rather than estimated: nspr costs
# nothing new, nss needs only nspr plus mercurial on the host, and
# hg.mozilla.org answers from this build host (HTTP 302 in 0.3s -- worth
# checking, since dev.gnupg.org does not answer at all and libassuan
# needed a source change because of it).
nspr nss
# Closure, third round, and it is two packages. Both were pulled in by
# what the second round added, and both cost nothing further: libffi by
# libp11-kit, libevent by libverto.
#
# They are worth a line because of what they unblocked. p11-kit builds
# into three packages, and libp11-kit's dependency on libffi was holding
# up the whole chain ca-certificates -> ca-certificates-utils -> p11-kit
# -> libp11-kit. The resolver reported it as "ca-certificates required by
# curl" -- four links away from the missing name, and nothing in that
# message points at libffi.
libffi libevent
# Closure, fourth round -- and it closed to NOTHING, which is the point
# worth recording. It asked for libaio and thin-provisioning-tools, both
# wanted by lvm2 alone. thin-provisioning-tools is Rust now, so that was a
# language runtime 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 lvm2 sub-package removed both
# entries and the Rust question with them -- see patches/pkgbuild/lvm2.sh.
#
# 35 packages, then 19, then 2, then 0. The closure has to be recomputed
# after each round rather than once: lvm2 DECLARED libaio all along, and
# the third round could not see it because lvm2 had not been built yet.
# What STAGE 2 needs in order to exist, which is a different question from
# what the repository needs to resolve.
#
# Stage 2 rebuilds everything INSIDE the stage-1 rootfs, so the tools that
# do the rebuilding have to be in that rootfs. The resolver never asked
# for these -- nothing in the repository depends on them -- so the closure
# rounds could not surface them. Enumerated instead from what makepkg and
# an autotools build actually invoke.
#
# fakeroot is the one that decides whether stage 2 can start at all:
# makepkg runs package() under it, and refuses to run as root. bison,
# flex, texinfo and groff are what the sources themselves call -- gcc,
# glibc and binutils all want makeinfo, and a great many configure scripts
# want bison.
#
# sudo is deliberately NOT here. makepkg needs it only for --syncdeps, and
# stage 2 passes --nodeps, so it would be a setuid binary in the chroot
# for no reason.
fakeroot bison flex texinfo groff
# git, and it is not optional: 51 of the 159 PKGBUILDs take their sources
# from a git+https URL, and makepkg re-validates that clone even with
# --noextract. Without git in the chroot, stage 2 can rebuild a third of
# the repository and no more.
#
# Its own three: perl-error, perl-mailtools (which brings perl-timedate)
# and zlib-ng. Measured, not guessed -- and 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.
perl-error perl-timedate perl-mailtools zlib-ng git
# meson and cmake, which is where python re-enters -- and the distinction
# matters, because dropping python earlier was not a mistake.
#
# At stage 1 the question was what the REPOSITORY must supply: python was
# wanted only by python-brotli and python-libseccomp, wheels that Arch's
# own python could not load anyway, so they went and python went with them.
# Here the question is what the BUILD ENVIRONMENT must contain, and meson
# is written in Python. Ten of the 159 PKGBUILDs call arch-meson; four call
# cmake. Different question, different answer.
#
# Measured: mpdecimal, python, ninja, python-tqdm and meson, then cmake
# with cppdap, jsoncpp, libuv, rhash and hicolor-icon-theme behind it.
# Nothing further.
mpdecimal python ninja python-tqdm meson
cppdap jsoncpp libuv rhash hicolor-icon-theme cmake
# And finally the package manager itself, built as an Arch package.
pacman
[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
# Tools the STAGE-2 CHROOT needs, which the host supplied for free.
#
# Stage 1 never noticed these: install_host_deps put them there with apt,
# and a build that finds its tool does not mention it. Inside the chroot
# there is no apt and no host, so every one of them has to exist as a
# package -- and the first thing stage 2 tried to rebuild stopped on
#
# /bin/sh: line 1: rsync: command not found
# make[1]: *** [.../Makefile:1463: headers_install] Error 127
#
# from linux-api-headers, the first entry in this list. xxhash is here
# because rsync links it.
xxhash
rsync
[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
# The rest of that same class, named by stage 2's first full pass rather
# than guessed. 77 packages rebuilt, 57 failed, and fourteen of the
# failures named the tool they wanted outright:
#
# gperf coreutils, diffutils, systemd, libseccomp
# wget sed, grep, findutils
# patchelf curl
# hostname gnupg (inetutils ships it)
[ADD] the seven tools stage 2 asked for by name Six built on the host. libxslt will not: its configure demands libxml2 2.15.1 and Ubuntu ships 2.14.5. Ours is 2.15.3 and exists only inside the stage-2 chroot, so that chroot is the only place libxslt can come from -- built BY stage 2 rather than installed into it, and hoisted so it precedes shadow, which died on `xsltproc is missing`. That is a shape worth naming: a package the host cannot build because the host is behind. Not contamination and not a closure gap -- the wrong machine. Three more tools were asked for and refused: po4a for fakeroot, a2x for ca-certificates, asciidoctor for cryptsetup. Perl, Python and Ruby respectively, each to render a man page. Hooks instead. --- FR --- Six se bâtissent sur l'hôte. Pas libxslt : son configure exige libxml2 2.15.1 et Ubuntu livre 2.14.5. Le nôtre est en 2.15.3 et n'existe que dans le chroot de l'étage 2 : ce chroot est donc le seul endroit d'où libxslt puisse venir — bâti PAR l'étage 2 plutôt qu'installé dedans, et hissé pour précéder shadow, mort sur `xsltproc is missing`. La forme mérite un nom : un paquet que l'hôte ne peut pas bâtir parce que l'hôte est en retard. Ni contamination ni trou de fermeture — la mauvaise machine. Trois autres outils réclamés et refusés : po4a pour fakeroot, a2x pour ca-certificates, asciidoctor pour cryptsetup. Perl, Python et Ruby respectivement, chacun pour rendre une page de manuel. Des hooks à la place. Assisted-by: Claude Opus 5
2026-08-21 00:29:40 -04:00
# xsltproc shadow (libxslt ships it -- see below)
[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
# swig audit
# help2man flex
#
# All small and self-contained. Three more tools were asked for and are NOT
# here -- po4a, asciidoc's a2x, and asciidoctor -- because each brings a
# language runtime (Perl module stack, Python, Ruby) to render
# documentation. Those three packages get a hook instead, the same
# arbitration as --auto-features auto.
gperf
wget
patchelf
inetutils
swig
help2man
# help2man's own closure. Stage 1 builds with --nodeps, so help2man built
# cleanly and was then UNINSTALLABLE -- populate stopped the whole of stage-2
# pass two on
#
# unable to satisfy dependency 'perl-locale-gettext' required by help2man
#
# which is the routine consequence of --nodeps and the reason RESOLVE exists
# in test-chroot.sh: a build succeeding says nothing about whether the
# repository is complete.
perl-locale-gettext
[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
# Python packaging, which three stage-2 builds stopped on:
#
# /usr/bin/python: No module named build
#
# brotli, libseccomp and meson build their wheels with `python -m build`,
# and python-tqdm installs one. On the host these came from apt; in the
# chroot they have to be packages. Ordered by their own dependencies:
# flit-core bootstraps itself, then the two libraries build needs.
[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
# Of these seven, only python-flit-core builds on the host. The other six
# compute their install paths from the running python, so the host bakes
# Debian's dist-packages into them -- three failed on a `rm` that found
# nothing, and three succeeded and shipped 180 unreachable module paths.
# They are built by stage 2 instead; a stage-1 run is expected to report
# them as failed, exactly like libxslt.
[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
python-flit-core
python-packaging
python-pyproject-hooks
python-build
python-installer
python-setuptools
python-wheel
# scdoc: kmod's meson stopped on `Program 'scdoc' not found`. A man-page
# generator, but a tiny self-contained C one -- nothing like the language
# runtimes behind doxygen or asciidoctor, so it is cheaper to build than to
# hook around.
scdoc
[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
# nlohmann-json: a real closure gap, not a documentation cut. BOTH cmake and
# cppdap stop on
#
# Could NOT find nlohmann_json (missing: nlohmann_json_DIR)
#
# It is a header-only C++ library -- one of the cheapest packages in this
# list -- and cmake is not optional here: the whole cmake/cppdap/jsoncpp/
# libuv group behind it is what several other packages build with.
nlohmann-json
[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
# python-setuptools-scm: python-tqdm's build stops on
#
# setuptools-scm[toml]>=3.4
#
# which is a requirements line, not an error message -- pip printing what it
# could not find. Built by stage 2 with the rest of the Python set, for the
# same reason: its package() would take Debian's dist-packages from the
# host's python.
python-setuptools-scm
# systemd generates part of its source with jinja2 templates:
#
# meson.build:1620:15: ERROR: python3 is missing modules: jinja2
#
# Not documentation -- the build cannot proceed without it. python-markupsafe
# comes with it, as jinja's only dependency.
python-markupsafe
python-jinja
[FIX] the second half of two of my own hooks libevent: mv: cannot stat '<pkgdir>/usr/share/doc': No such file or directory pam: rm: cannot remove '.../Linux-PAM/*.pdf': No such file or directory Both are hooks I wrote in this session, and both stopped a build in exactly the way this port has documented eight times: the documentation build was disabled and its install was left in place. Turning EVENT__DOXYGEN off does not stop package() moving usr/share/doc into the libevent-doc split; -Ddocs=disabled does not stop pam deleting PDFs it no longer produces. fakeroot was the first one I made myself. This makes three, so the rule is worth stating instead of rediscovering: after disabling documentation anywhere, search package() for share/doc, man, and the split arrays before believing the hook is finished. pam's rm becomes tolerant rather than deleted -- on a machine with the DocBook stack the PDFs are real, and the comment above the line says why they must go: they are not reproducible. --- FR --- libevent: mv: cannot stat '<pkgdir>/usr/share/doc': No such file or directory pam: rm: cannot remove '.../Linux-PAM/*.pdf': No such file or directory Deux hooks que j'ai écrits dans cette session, et deux arrêts de construction de la façon exacte que ce portage a documentée huit fois : la construction de la documentation désactivée, son installation laissée en place. Éteindre EVENT__DOXYGEN n'empêche pas package() de déplacer usr/share/doc vers le sous-paquet libevent-doc ; -Ddocs=disabled n'empêche pas pam de supprimer des PDF qu'il ne produit plus. fakeroot fut le premier de ma main. Cela en fait trois : la règle mérite d'être énoncée plutôt que redécouverte — après avoir désactivé une documentation, chercher dans package() share/doc, man, et les tableaux de sous-paquets avant de croire le hook terminé. Le rm de pam devient tolérant plutôt que supprimé : sur une machine dotée de la pile DocBook les PDF existent, et le commentaire au-dessus dit pourquoi ils doivent partir — ils ne sont pas reproductibles. Assisted-by: Claude Opus 5
2026-08-23 19:09:10 -04:00
# Three more the chroot asked for by name, each a build tool:
#
# python-pkgconfig brotli: ERROR Missing dependencies: pkgconfig
# -- the python MODULE, not pkg-config the program,
# which has been there since the lib64 fix.
# cython libseccomp: ERROR Backend subprocess exited when
# trying to invoke get_requires_for_build_wheel
# -- its python bindings are Cython.
# autoconf-archive tpm2-tss: configure.ac:139: error: undefined or
# overquoted macro: AC_MSG_WARN
# -- an AX_* macro is missing, so autoconf misreads the
# line and blames one it does know.
python-pkgconfig
cython
autoconf-archive
2026-08-23 20:19:45 -04:00
# publicsuffix-list: DATA, not a tool. libpsl stops on
#
# make: *** No rule to make target
# '/usr/share/publicsuffix/effective_tld_names.dat', needed by ...
#
# It compiles the Public Suffix List into a lookup table, so the list itself
# is an input to the build. First entry in this port whose absence is neither
# a program nor a library.
publicsuffix-list
[FIX] --nodeps once skips versions, not dependencies Two install commands passed one --nodeps and looked like they were skipping dependencies. pacman documents the difference: -d skips dependency VERSION checks, -dd skips them entirely. So cython could not be installed -- warning: cannot resolve python-pygments, a dependency of cython :: unable to satisfy dependency python-numpy required by cython -- and the numbers matter. cython is wanted here only as a BUILD tool, for libseccomp Python binding, while its declared RUNTIME dependencies are numpy and pygments, and numpy brings BLAS and LAPACK. A single -d nearly bought a numerical stack to compile one .pyx file. The message named numpy and numpy was not the subject. The subject was a missing letter d. python-poetry-core joins the list: the fourth Python build backend needed here after flit_core, setuptools and hatchling. --- FR --- Deux commandes d installation passaient un seul --nodeps et semblaient sauter les dependances. pacman documente la difference : -d saute les controles de VERSION, -dd les saute entierement. cython ne pouvait donc pas etre installe -- warning: cannot resolve python-pygments, a dependency of cython :: unable to satisfy dependency python-numpy required by cython -- et les chiffres comptent. cython n est voulu ici que comme OUTIL de construction, pour la liaison Python de libseccomp, alors que ses dependances d EXECUTION declarees sont numpy et pygments, et numpy tire BLAS et LAPACK. Un seul -d a failli faire compiler une pile numerique pour un fichier .pyx. Le message nommait numpy, et numpy n etait pas le sujet. Le sujet etait un d manquant. python-poetry-core rejoint la liste : quatrieme moteur de construction Python necessaire ici, apres flit_core, setuptools et hatchling. Assisted-by: Claude Opus 5
2026-08-23 20:47:32 -04:00
# python-poetry-core: the fourth Python build backend this port has needed.
# python-pkgconfig stops on
#
# ERROR Backend 'poetry.core.masonry.api' is not available.
#
# flit_core, setuptools, hatchling and now poetry-core -- each package picks
# its own, and each one has to exist before that package can be built.
python-poetry-core
# python-vcs-versioning: setuptools-scm was split, and its own build now
# imports the half that left:
#
# from vcs_versioning import Configuration
# ModuleNotFoundError: No module named 'vcs_versioning'
#
# The traceback runs through setuptools' build_meta, so the visible error is
# "Backend subprocess exited when trying to invoke build_wheel" -- a backend
# complaint about a package that split upstream.
python-vcs-versioning
[FIX] binutils records a usr/lib64 path, and cmake deletes html it did not make pacman refused the rebuilt binutils: binutils: <root>/usr/lib64 exists in filesystem (owned by filesystem) binutils: <root>/usr/lib64/libiberty.a exists in filesystem --libdir=/usr/lib was not enough. libiberty installs into $(libdir)$(MULTIOSSUBDIR), and gcc reports ../lib64 for -print-multi-os-directory on s390x. In the installed system that resolves through the symlink filesystem now provides, so the file lands in /usr/lib -- but pkgdir has no symlink, so make creates a real pkg/usr/lib64/ and makepkg records the literal path. The two fixes are not alternatives: the symlink is what keeps meson and cmake choosing lib, and this moves the one file that still writes through the multi-os subdirectory. cmake is the eleventh instance of removing a documentation build and leaving its cleanup: with Sphinx off there is no html, and the PKGBUILD deletes _sources from it. rm -rf rather than deleted -- on a machine with Sphinx it is real. The binutils hook also assumed package_binutils(). binutils is not a split package; its own assertion caught that. --- FR --- pacman a refusé le binutils reconstruit : binutils: <root>/usr/lib64 exists in filesystem (owned by filesystem) binutils: <root>/usr/lib64/libiberty.a exists in filesystem --libdir=/usr/lib ne suffisait pas. libiberty s'installe dans $(libdir)$(MULTIOSSUBDIR), et gcc annonce ../lib64 pour -print-multi-os-directory sur s390x. Dans le système installé cela se résout par le lien que filesystem fournit désormais, donc le fichier atterrit dans /usr/lib — mais pkgdir n'a pas de lien : make crée un vrai pkg/usr/lib64/ et makepkg enregistre le chemin littéral. Les deux correctifs ne sont pas des alternatives : le lien est ce qui fait choisir lib à meson et cmake, et celui-ci déplace le seul fichier qui écrive encore par le sous-répertoire multi-os. cmake est la onzième occurrence du retrait d'une documentation sans son nettoyage : sans Sphinx il n'y a pas de html, et le PKGBUILD en supprime _sources. rm -rf plutôt que supprimé — sur une machine dotée de Sphinx, il est réel. Le hook binutils supposait aussi package_binutils(). binutils n'est pas un paquet scindé ; sa propre assertion l'a arrêté. Assisted-by: Claude Opus 5
2026-08-23 22:05:26 -04:00
# python-fastjsonschema: poetry-core validates pyproject.toml against a JSON
# schema, so it needs a schema validator to build anything -- including
# itself. ModuleNotFoundError: No module named 'fastjsonschema'.
python-fastjsonschema
[ADD] gyp for nss, and jsoncpp's doxygen output nss will not configure without gyp: Building NSS requires an installation of gyp: https://gyp.gsrc.io Google's build-file generator, which nss uses to produce its ninja files. It is a real Arch package and a Python program, so it joins the Python set. jsoncpp is the fourteenth instance of this shape and the sixth of my own making. Removing the doxybuild.py call stopped the API html being generated; package() still copied the directory it would have produced, and the name carries pkgver so the path is not greppable without knowing the version. The rule is mechanical enough now to state as a procedure rather than a lesson: after removing a documentation build, grep package() for the OUTPUT directory name, not for the tool. The tool appears in build(); the path appears in package(), and it is the path that fails. --- FR --- nss ne se configure pas sans gyp : Building NSS requires an installation of gyp: https://gyp.gsrc.io Le générateur de fichiers de construction de Google, dont nss se sert pour produire ses fichiers ninja. C'est un vrai paquet Arch et un programme Python : il rejoint l'ensemble Python. jsoncpp est la quatorzième occurrence de cette forme, et la sixième de ma main. Retirer l'appel à doxybuild.py a arrêté la génération du html d'API ; package() copiait toujours le répertoire qu'il aurait produit, et son nom porte pkgver — le chemin n'est donc pas trouvable par grep sans connaître la version. La règle est assez mécanique pour être énoncée en procédure plutôt qu'en leçon : après avoir retiré une construction de documentation, chercher dans package() le nom du répertoire de SORTIE, pas celui de l'outil. L'outil est dans build() ; le chemin est dans package(), et c'est le chemin qui échoue. Assisted-by: Claude Opus 5
2026-08-24 00:03:26 -04:00
# gyp: nss will not configure without it --
#
# Building NSS requires an installation of gyp: https://gyp.gsrc.io
#
# Google's build-file generator, which nss uses to produce its ninja files.
# A Python program, so it goes with the rest of the Python set.
gyp
[ADD] llvm and clang, with Sphinx off, for Rust Rust is not optional. ERPLibre's poetry.lock requires cryptography 46.0.5 with optional = false, plus jiter, orjson, pydantic-core and rpds-py -- all of which build Rust from source where no wheel exists, and none exists for s390x. Without Rust, `pip install cryptography` fails and ERPLibre does not start. The bootstrap cycle is not the obstacle it looks like: rust-1.90.0 ships an official s390x-unknown-linux-gnu tarball, verified with HTTP 200, and the host already carries rustc 1.85.1. What costs is llvm and clang. Measured before choosing, the way glib2 and iproute2 were: beyond what this port already has, llvm and clang want libedit, python-psutil, python-sphinx and python-myst-parser. The last two are documentation only, and behind them sit docutils, babel, pygments, snowballstemmer, imagesize, alabaster, the sphinxcontrib family, markdown-it-py and mdit-py-plugins -- some fifteen packages to render HTML for a compiler whose manual nothing here reads. -DLLVM_ENABLE_SPHINX=OFF removes all of it. Their package() ends on `rm -r .../html/{_sources,.buildinfo}`, which Sphinx creates. Seventeenth appearance of that shape, and the FIRST found before the build rather than after -- the procedure written in jsoncpp's hook, applied forwards. python-psutil is a stage-2 package: built on the host it shipped 41 dist-packages paths, and the ARTEFACT check caught it. --- FR --- Rust n'est pas optionnel. Le poetry.lock d'ERPLibre exige cryptography 46.0.5 en optional = false, plus jiter, orjson, pydantic-core et rpds-py, qui tous compilent du Rust depuis les sources là où aucune roue n'existe — et il n'en existe pas pour s390x. Sans Rust, `pip install cryptography` échoue et ERPLibre ne démarre pas. Le cycle d'amorçage n'est pas l'obstacle qu'il paraît : rust-1.90.0 publie une archive officielle s390x-unknown-linux-gnu, vérifiée en HTTP 200, et l'hôte porte déjà rustc 1.85.1. Ce qui coûte, c'est llvm et clang. Mesuré avant de choisir, comme glib2 et iproute2 : au-delà de ce que ce portage a déjà, llvm et clang veulent libedit, python-psutil, python-sphinx et python-myst-parser. Les deux derniers ne servent qu'à la documentation, et derrière eux viennent docutils, babel, pygments, snowballstemmer, imagesize, alabaster, la famille sphinxcontrib, markdown-it-py et mdit-py-plugins — une quinzaine de paquets pour produire du HTML sur un compilateur dont personne ici ne lit le manuel. -DLLVM_ENABLE_SPHINX=OFF supprime tout cela. Leur package() finit sur `rm -r .../html/{_sources,.buildinfo}`, que Sphinx crée. Dix-septième apparition de cette forme, et la PREMIÈRE trouvée avant la construction plutôt qu'après — la procédure inscrite dans le hook de jsoncpp, appliquée à l'endroit. python-psutil est un paquet d'étage 2 : bâti sur l'hôte, il livrait 41 chemins dist-packages, et le test ARTEFACT l'a attrapé. Assisted-by: Claude Opus 5
2026-08-24 01:57:19 -04:00
# --- Rust, and what it needs ---------------------------------------------
#
# NOT optional, and that was measured rather than assumed. ERPLibre's
# poetry.lock requires cryptography 46.0.5 with optional = false, plus jiter,
# orjson, pydantic-core and rpds-py -- all of which build Rust from source
# where no wheel exists, and none exists for s390x. Without Rust,
# `pip install cryptography` fails and ERPLibre does not start.
#
# The bootstrap cycle is not the obstacle it looks like: rust-1.90.0 ships an
# official s390x-unknown-linux-gnu tarball (verified, HTTP 200) and the host
# already carries rustc 1.85.1. What costs is llvm and clang, which Arch's
# rust lists as makedepends.
#
# libedit and python-psutil are all llvm and clang need beyond what is
# already here -- Sphinx is disabled by their hooks, which removes some
# fifteen documentation packages from the bill.
libedit
# python-psutil is a stage-2 package: built on the host it shipped 41
# dist-packages paths, like every Python package whose install path comes
# from the running interpreter. The ARTEFACT check caught it.
python-psutil
llvm
clang
[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
# libaio: a real closure gap. lvm2 stops on
#
# device/bcache.c:30:10: fatal error: libaio.h: No such file or directory
#
# A small C library for asynchronous I/O, and one this port had already met
# from the other side: Ubuntu renamed its runtime to libaio.so.1t64 for
# time64, which was noted as a divergence long before anything needed the
# headers.
libaio
[ADD] the seven tools stage 2 asked for by name Six built on the host. libxslt will not: its configure demands libxml2 2.15.1 and Ubuntu ships 2.14.5. Ours is 2.15.3 and exists only inside the stage-2 chroot, so that chroot is the only place libxslt can come from -- built BY stage 2 rather than installed into it, and hoisted so it precedes shadow, which died on `xsltproc is missing`. That is a shape worth naming: a package the host cannot build because the host is behind. Not contamination and not a closure gap -- the wrong machine. Three more tools were asked for and refused: po4a for fakeroot, a2x for ca-certificates, asciidoctor for cryptsetup. Perl, Python and Ruby respectively, each to render a man page. Hooks instead. --- FR --- Six se bâtissent sur l'hôte. Pas libxslt : son configure exige libxml2 2.15.1 et Ubuntu livre 2.14.5. Le nôtre est en 2.15.3 et n'existe que dans le chroot de l'étage 2 : ce chroot est donc le seul endroit d'où libxslt puisse venir — bâti PAR l'étage 2 plutôt qu'installé dedans, et hissé pour précéder shadow, mort sur `xsltproc is missing`. La forme mérite un nom : un paquet que l'hôte ne peut pas bâtir parce que l'hôte est en retard. Ni contamination ni trou de fermeture — la mauvaise machine. Trois autres outils réclamés et refusés : po4a pour fakeroot, a2x pour ca-certificates, asciidoctor pour cryptsetup. Perl, Python et Ruby respectivement, chacun pour rendre une page de manuel. Des hooks à la place. Assisted-by: Claude Opus 5
2026-08-21 00:29:40 -04:00
# libxslt stays in the list because it is part of the distribution, but
# STAGE 1 CANNOT BUILD IT:
#
# configure: error: Version 2.14.5 found. You need at least libxml2
# 2.15.1 for this version of libxslt
#
# 2.14.5 is Ubuntu's. Ours is 2.15.3 and exists only inside the stage-2
# chroot, so that is the only place libxslt can come from -- it is in
# STAGE2_FIRST, and a stage-1 run is expected to report it as failed.
libxslt
[IMP] stage 2: resumable, guarded, driven by the shared list Stage 2 could rebuild one named package. It could not rebuild a hundred and thirty-three, for reasons that were all about the driver. The order is not re-derived: it is the closure stage 1 arrived at over four rounds of resolver output and then confirmed by 179 builds, so it moves to packages.sh and both stages read it. make_rootfs wipes the chroot every run, which is what makes it reproducible and what made stage 2 unresumable -- stage2.state outlived the packages it named. Its output is now put back. The stall guard is shared rather than copied: stage 2 needs it more, since a test suite is the likeliest thing in a build to wait forever. Build trees are removed after a package installs, never after it fails. --- FR --- L'étage 2 savait rebâtir un paquet nommé. Il ne savait pas en rebâtir cent trente-trois, pour des raisons qui tenaient toutes au pilote. L'ordre n'est pas réinventé : c'est la fermeture obtenue à l'étage 1 en quatre tours de sortie du résolveur, puis confirmée par 179 constructions. Il passe donc dans packages.sh, que les deux étages lisent. make_rootfs efface le chroot à chaque passage — ce qui le rend reproductible et rendait l'étage 2 irreprenable, stage2.state survivant aux paquets qu'il nommait. Sa production y est désormais réinstallée. La garde d'immobilité est partagée plutôt que recopiée : l'étage 2 en a plus besoin, une suite de tests étant ce qui attend le plus volontiers pour toujours. Les arbres de compilation sont effacés après installation, jamais après un échec. Assisted-by: Claude Opus 5
2026-08-20 01:16:49 -04:00
)