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
134 lines
6.4 KiB
Bash
Executable file
134 lines
6.4 KiB
Bash
Executable file
#!/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)"
|
|
|
|
# --- 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"
|
|
|
|
# --- 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)"
|