archlinux-s390x/patches/pkgbuild/sqlite.sh

135 lines
6.4 KiB
Bash
Raw Permalink Normal View History

[FIX] the build host answered questions the target should Five packages, one shape: a default computed from this machine rather than from Arch, and arch-meson's --auto-features enabled turning what was optional into a requirement. dbus taught the method. It stopped three times in a row on a different documentation tool -- ducktype, then yelp-build, then qhelpgenerator. The first two were installed. The third needs Qt, so the chain had no end. All three are `auto` features promoted to mandatory; pinned off, they cost nothing. A single missing library is a host dependency. A queue of them is a feature that should be disabled. pinentry wanted Qt6 for a passphrase prompt; tty and curses remain. krb5 asked for a system ss library Ubuntu ships no headers for, and said "cannot run test program" instead of saying so. sqlite found tcl, then installed into share/tcltk because Ubuntu's tclConfig.sh says so and Arch's says lib. gettext linked the host's libselinux, silently -- the sixth package to do it, and the first the audit caught rather than a build. --- FR --- Cinq paquets, une seule forme : une valeur par défaut calculée depuis cette machine plutôt que depuis Arch, et le --auto-features enabled d'arch-meson qui transforme l'optionnel en exigence. dbus a enseigné la méthode. Il s'est arrêté trois fois de suite sur un outil de documentation différent — ducktype, puis yelp-build, puis qhelpgenerator. Les deux premiers ont été installés. Le troisième exige Qt : la chaîne ne terminait nulle part. Les trois sont des features `auto` promues en obligations ; épinglées à disabled, elles ne coûtent rien. Une bibliothèque manquante est une dépendance hôte. Une file d'attente en est une fonctionnalité à désactiver. pinentry réclamait Qt6 pour une invite de mot de passe ; tty et curses suffisent. krb5 demandait une bibliothèque ss système dont Ubuntu ne livre aucun en-tête, et annonçait « cannot run test program » plutôt que de le dire. sqlite trouvait tcl, puis installait dans share/tcltk parce que le tclConfig.sh d'Ubuntu le dit là où celui d'Arch dit lib. gettext liait le libselinux de l'hôte, en silence — sixième paquet à le faire, et le premier que l'audit a pris plutôt qu'une compilation. Assisted-by: Claude Opus 5
2026-08-19 05:28:32 -04:00
#!/usr/bin/env bash
# sqlite: the tcl extension installs where Ubuntu's tclConfig.sh says, not
# where Arch's does.
#
# mv: cannot stat '<pkgdir>/usr/lib/tcl8.6/sqlite*': No such file or directory
#
# THE TRAP is that tcl was found. The log says so, plainly:
#
# Checking for tclsh8.6.../usr/bin/tclsh8.6
# Using tclConfig.sh: /usr/lib/s390x-linux-gnu/tclConfig.sh
#
# so "install tcl-dev" looks like it worked, and the failure looks like a
# separate problem. It is the same problem one layer down: tclConfig.sh
# carries TCL_PACKAGE_PATH, and Ubuntu's says share/tcltk while Arch's says
# lib. Measured in the pkgdir:
#
# usr/share/tcltk/tcl8.6/sqlite3.53.4/libsqlite3.53.4.so
#
# and usr/lib/tcl8.6 does not exist at all. This is the multiarch libdir theme
# again -- a path the BUILD HOST decides -- but one layer out from the library
# directory itself, which is why --libdir does not reach it.
#
# The tree is relocated to Arch's path before package_sqlite() splits it out,
# so the upstream mv keeps working unchanged. Same shape as the lib64 merge in
# gcc.sh: move the tree, do not rewrite every path that names it.
set -euo pipefail
python3 - <<'PY'
import io
s = io.open("PKGBUILD", encoding="utf-8").read()
anchor = " # split out tcl extension\n"
assert s.count(anchor) == 1, "sqlite: expected one tcl split block"
fix = """ # Ubuntu's tclConfig.sh puts the tcl package tree under share/tcltk;
# Arch's puts it under lib. Move it before the split below reads it.
if [ -d "$pkgdir"/usr/share/tcltk/tcl8.6 ]; then
mkdir -p "$pkgdir"/usr/lib
mv "$pkgdir"/usr/share/tcltk/tcl8.6 "$pkgdir"/usr/lib/tcl8.6
rmdir --ignore-fail-on-non-empty "$pkgdir"/usr/share/tcltk
fi
"""
s = s.replace(anchor, fix + anchor, 1)
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
PY
grep -q "tclConfig.sh puts the tcl package tree" PKGBUILD || {
echo "sqlite: tcl relocation not inserted" >&2; exit 1; }
echo "sqlite: tcl extension relocated from share/tcltk to lib (host TCL_PACKAGE_PATH)"
[FIX] sqlite, libpsl and util-linux sqlite is the deferred item this port had written down long ago -- "libtcl8.6 versus our tcl 9.0" -- arriving as a missing directory: mv: cannot stat '<pkgdir>/usr/lib/tcl8.6/sqlite*': No such file or directory The version is read from the tree rather than written in, because the tcl package decides it and hardcoding 9.0 puts the same trap back one release later. The first attempt guarded with a blanket `grep tcl8.6` and condemned correct code: the existing section of that hook names tcl8.6 on purpose, because it is about the HOST's tcl. It also substituted $_tcldir into that older section, before the variable was defined. The guard caught both. util-linux is the seventh package to fail on a path at the end of package() after a compile that worked. libpsl's error names its own fix. --- FR --- sqlite est l'élément différé que ce portage avait noté depuis longtemps — « libtcl8.6 contre notre tcl 9.0 » — arrivant sous la forme d'un répertoire absent : mv: cannot stat '<pkgdir>/usr/lib/tcl8.6/sqlite*': No such file or directory La version est lue dans l'arbre plutôt qu'écrite en dur, parce que c'est le paquet tcl qui la décide et qu'inscrire 9.0 remettrait le même piège une version plus tard. La première tentative gardait par un `grep tcl8.6` global et condamnait du code juste : la section existante de ce hook nomme tcl8.6 exprès, car elle traite du tcl de l'HÔTE. Elle avait aussi injecté $_tcldir dans cette section antérieure, avant que la variable soit définie. Le garde a attrapé les deux. util-linux est le septième paquet à échouer sur un chemin en fin de package() après une compilation réussie. L'erreur de libpsl nomme son propre correctif. Assisted-by: Claude Opus 5
2026-08-22 07:33:10 -04:00
# --- and in the chroot, our tcl is not 8.6 -----------------------------------
#
# mv: cannot stat '<pkgdir>/usr/lib/tcl8.6/sqlite*': No such file or directory
#
# The section above solves the HOST's problem: Ubuntu's tclConfig.sh says
# share/tcltk, so the tree is relocated to usr/lib/tcl8.6 where the upstream mv
# expects it. Inside the stage-2 chroot neither half of that applies -- Arch's
# tclConfig.sh already says lib, and our tcl is 9.0, so sqlite installs into
# usr/lib/tcl9.0 and the upstream mv finds nothing. The relocation above becomes
# a no-op there, correctly, because it is guarded by [ -d ].
#
# This is the deferred item this port had already written down -- "libtcl8.6
# versus our tcl 9.0" -- arriving as a missing directory rather than as a version
# mismatch.
#
# The version is READ from the tree, not written in. Hardcoding 9.0 would put the
# same trap back one release later, and the tcl package is what decides it.
python3 - <<'ZZPY'
import io
s = io.open("PKGBUILD", encoding="utf-8").read()
old = 'mv "$pkgdir"/usr/lib/tcl8.6/sqlite* "$srcdir"/tcl'
assert s.count(old) == 1, "sqlite: the upstream tcl move is not in the expected form"
new = ('_tcldir=$(cd "$pkgdir"/usr/lib && echo tcl[0-9]*)\n'
' [ -d "$pkgdir/usr/lib/$_tcldir" ] || { echo "sqlite: no tcl dir under usr/lib" >&2; exit 1; }\n'
' mv "$pkgdir"/usr/lib/"$_tcldir"/sqlite* "$srcdir"/tcl')
s = s.replace(old, new, 1)
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
ZZPY
# Only the upstream mv had to change. The relocation above still names tcl8.6 on
# purpose -- it is about the HOST's tcl -- so a blanket grep for tcl8.6 would
# condemn correct code, and did on the first attempt.
grep -qE '^[[:space:]]*mv .*usr/lib/tcl8\.6/sqlite' PKGBUILD && {
echo "sqlite: the hardcoded upstream move survived" >&2; exit 1; }
grep -q '_tcldir=' PKGBUILD || { echo "sqlite: the tcl dir is not discovered" >&2; exit 1; }
echo "sqlite: upstream tcl move reads the version from the tree"
[FIX] sqlite: tcl 9 keeps its library inside the binary The hook's guard reported "no tcl dir under usr/lib". What sqlite had created instead was a directory literally named `zipfs:` <pkgdir>/sqlite/zipfs:/lib/tcl/tcl_library/ The generated Makefile explains itself: # TCLLIBDIR = where to install the tcl plugin. If this is empty, it TCLLIBDIR = //zipfs:/lib/tcl/tcl_library/sqlite3.53.4 sqlite asks tcl where its library lives and installs the plugin beside it. In tcl 8.6 that was a real directory. tcl 9 ships its library INSIDE the executable, in a zipfs mount, so the answer is a path only tcl can open -- and sqlite used it as a filesystem path, creating a directory whose name contains a colon. This is the deferred "libtcl8.6 versus our tcl 9.0" item in its final form: not a version number to update but a change in what tcl considers a path. TCLLIBDIR now points at a real directory, versioned from tclsh. --- FR --- Le garde du hook signalait « no tcl dir under usr/lib ». Ce que sqlite avait créé était un répertoire littéralement nommé `zipfs:` <pkgdir>/sqlite/zipfs:/lib/tcl/tcl_library/ Le Makefile généré s'explique lui-même : # TCLLIBDIR = where to install the tcl plugin. If this is empty, it TCLLIBDIR = //zipfs:/lib/tcl/tcl_library/sqlite3.53.4 sqlite demande à tcl où vit sa bibliothèque et installe le greffon à côté. En tcl 8.6 c'était un vrai répertoire. tcl 9 livre sa bibliothèque DANS l'exécutable, en montage zipfs : la réponse est un chemin que seul tcl sait ouvrir, et sqlite l'a traité comme un chemin de fichiers, créant un répertoire dont le nom contient deux points. C'est l'élément différé « libtcl8.6 contre notre tcl 9.0 » dans sa forme finale : non pas un numéro de version à mettre à jour, mais un changement de ce que tcl appelle un chemin. TCLLIBDIR vise désormais un vrai répertoire, sa version lue depuis tclsh. Assisted-by: Claude Opus 5
2026-08-23 21:18:44 -04:00
# --- tcl 9 keeps its library inside the binary -------------------------------
#
# The section above discovers whatever tcl directory exists under usr/lib. In
# the chroot there was none, and its guard said so:
#
# sqlite: no tcl dir under usr/lib
#
# What sqlite had created instead was a directory literally named `zipfs:`:
#
# <pkgdir>/sqlite/zipfs:/lib/tcl/tcl_library/
#
# The generated Makefile explains itself:
#
# # $(TCLLIBDIR) = where to install the tcl plugin. If this is empty, it
# TCLLIBDIR = //zipfs:/lib/tcl/tcl_library/sqlite3.53.4
#
# sqlite asks tcl where its library lives and installs the plugin beside it. In
# tcl 8.6 that was a real directory. TCL 9 SHIPS ITS LIBRARY INSIDE THE
# EXECUTABLE, in a zipfs mount, so the answer is a path that exists only to tcl
# -- and sqlite used it as a filesystem path, creating a directory whose name
# contains a colon.
#
# This is the deferred "libtcl8.6 versus our tcl 9.0" item in its final form: not
# a version number to update but a change in what tcl considers a path.
#
# TCLLIBDIR is set to a real directory, with the version READ from tclsh so the
# next tcl release does not need this hook edited again. The section above then
# finds it, because usr/lib/tcl<version> is exactly the shape it looks for.
set -euo pipefail
python3 - <<'ZZPY'
import io, re
lines = io.open("PKGBUILD", encoding="utf-8").read().split("\n")
hit = [i for i, l in enumerate(lines) if re.match(r"^[ \t]*make\b.*\bsqltclsh\b", l)]
if not hit:
hit = [i for i, l in enumerate(lines) if re.match(r"^[ \t]*make[ \t]*$", l)]
assert hit, "sqlite: no make line found in build()"
i = hit[0]
ind = re.match(r"^[ \t]*", lines[i]).group(0)
lines[i:i] = [
ind + "# tcl 9 answers with a zipfs path that only tcl can open, and sqlite",
ind + "# would install its plugin into a directory named `zipfs:`. Give it a",
ind + "# real one, versioned from tclsh rather than written in here.",
ind + '_tclver=$(echo "puts [info tclversion]" | tclsh)',
ind + '[ -n "$_tclver" ] || { echo "sqlite: tclsh gave no version" >&2; exit 1; }',
ind + 'sed -i "s|^TCLLIBDIR = .*|TCLLIBDIR = /usr/lib/tcl${_tclver}/sqlite${pkgver}|" Makefile',
ind + 'grep -q "^TCLLIBDIR = /usr/lib/tcl" Makefile || { echo "sqlite: TCLLIBDIR not redirected" >&2; exit 1; }',
]
io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(lines))
ZZPY
grep -q "TCLLIBDIR = /usr/lib/tcl" PKGBUILD || {
echo "sqlite: the TCLLIBDIR redirection was not inserted" >&2; exit 1; }
echo "sqlite: tcl plugin directed to a real directory (tcl 9 uses zipfs)"