Disabling libgccjit took four separate cuts, and this is the fourth. Removing the second configure pass, the pkgname entry and the _pick lines still left package_gcc() calling make -C gcc DESTDIR="$pkgdir" jit.install-common jit.install-info which fails on a library that was never built: install: cannot install libgccjit.so.0.0.1 The lesson repeats: in an Arch PKGBUILD a component is referenced in several independent places -- the pkgname array, a build block, _pick lines in package(), and explicit make targets. Removing it means finding all four, and grepping for the component name after each cut is the only way to know. shadow and util-linux both stop on a missing libpam. Same family as every host makedepend before them: invisible until a build names it, because --nodeps forbids pacman from checking. --- FR --- Desactiver libgccjit aura demande quatre coupes distinctes, et voici la quatrieme. Retirer la seconde passe de configuration, l entree de pkgname et les lignes _pick laissait encore package_gcc() appeler make -C gcc DESTDIR="$pkgdir" jit.install-common jit.install-info qui echoue sur une bibliotheque jamais batie : install: cannot install libgccjit.so.0.0.1 La lecon se repete : dans un PKGBUILD d Arch, un composant est reference en plusieurs endroits independants -- le tableau pkgname, un bloc de compilation, des lignes _pick dans package(), et des cibles make explicites. Le retirer suppose de trouver les quatre, et chercher son nom apres chaque coupe est le seul moyen de le savoir. shadow et util-linux s arretent tous deux sur un libpam absent. Meme famille que tous les makedepends d hote precedents : invisibles jusqu a ce qu une compilation les nomme, puisque --nodeps interdit a pacman de verifier. Assisted-by: Claude Opus 5
173 lines
7.6 KiB
Bash
Executable file
173 lines
7.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# gcc: three x86 assumptions, all fatal on s390x.
|
|
#
|
|
# 1. Front ends written in themselves.
|
|
#
|
|
# configure: error: GNAT is required to build ada
|
|
# configure: error: GDC is required to build d
|
|
#
|
|
# Ada and D need an existing compiler of the same language; Modula-2 and
|
|
# COBOL have the same shape. Nothing in a core bootstrap, and nothing in
|
|
# ERPLibre, is written in any of them.
|
|
#
|
|
# 2. Multilib, which on Z means the 31-bit ABI:
|
|
#
|
|
# configure: error: Support for -m31 is deprecated and will be removed.
|
|
# Specify --enable-obsolete to build it anyway.
|
|
#
|
|
# On x86_64 multilib means i686 and Arch wants it. Here it means the
|
|
# 31-bit ESA/390 ABI that GCC is actively removing. Disabled rather than
|
|
# resurrected as obsolete.
|
|
#
|
|
# 3. The lib32 split package and every _pick that feeds it.
|
|
#
|
|
# The front-end reduction is a STAGE 1 CONCESSION: once the port is
|
|
# self-hosting, its own gcc can bootstrap Ada and D. The multilib and lib32
|
|
# removals are permanent -- they are architectural.
|
|
set -euo pipefail
|
|
|
|
# Only the MAIN build. The PKGBUILD configures gcc twice: once for the
|
|
# compiler, once for libgccjit with --enable-languages=jit. Rewriting
|
|
# every occurrence clobbered the second one, so the jit tree built a
|
|
# compiler instead of a library and package() died on
|
|
# cp: cannot stat 'gcc/libgccjit.so*': No such file or directory
|
|
# after forty minutes of compiling. Match the language list, never 'jit'.
|
|
sed -i '/--enable-languages=jit/!s/^\(\s*--enable-languages=\).*\\$/\1c,c++,fortran,lto,objc,obj-c++ \\/' PKGBUILD
|
|
if grep -qE 'enable-languages=[^ ]*(ada|,d,|m2|cobol)' PKGBUILD; then
|
|
echo "gcc: a self-hosted front end is still enabled" >&2; exit 1
|
|
fi
|
|
|
|
if grep -q -- '--enable-multilib' PKGBUILD; then
|
|
sed -i 's/--enable-multilib/--disable-multilib/' PKGBUILD
|
|
else
|
|
sed -i 's/^\(\s*\)--enable-languages=\(.*\)$/\1--disable-multilib \\\n\1--enable-languages=\2/' PKGBUILD
|
|
fi
|
|
grep -q -- '--disable-multilib' PKGBUILD || { echo "gcc: multilib not disabled" >&2; exit 1; }
|
|
|
|
# The pkgname array lists one sub-package per front end. makepkg calls
|
|
# package_<name>() for every entry, so those whose language is now off would
|
|
# package an empty tree. Names absent from the array are never called, so
|
|
# pruning it is enough -- the functions themselves can stay.
|
|
python3 - <<'PY'
|
|
import io, re
|
|
drop = {
|
|
"gcc-ada", "gcc-d", "gcc-gcobol", "gcc-go", "gcc-m2", "gcc-rust",
|
|
"libgm2", "libgo", "libgphobos", "libgcobol",
|
|
"lib32-gcc-libs",
|
|
# Hardware-assisted ASan exists on x86_64 and aarch64 only.
|
|
"libhwasan",
|
|
}
|
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
|
m = re.search(r"^pkgname=\(\n(.*?)^\)$", s, re.S | re.M)
|
|
assert m, "pkgname array not found"
|
|
kept = [ln for ln in m.group(1).splitlines() if ln.strip() not in drop]
|
|
s = s[:m.start(1)] + "\n".join(kept) + "\n" + s[m.end(1):]
|
|
s = re.sub(r"\npackage_lib32-gcc-libs\(\)\s*\{.*?\n\}\n", "\n", s, flags=re.S)
|
|
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
|
|
print("gcc: sub-packages kept -> %d" % len(kept))
|
|
PY
|
|
|
|
# Two lingering references outside the array: a makedepends entry on a
|
|
# package that does not exist for this architecture, and a run of
|
|
# `_pick lib32-gcc-libs usr/lib32/...` splitting out files multilib would
|
|
# have produced. With multilib off, usr/lib32 is empty.
|
|
sed -i '/^\s*lib32-gcc-libs\s*$/d' PKGBUILD
|
|
sed -i '/_pick lib32-gcc-libs/d' PKGBUILD
|
|
sed -i '/lib32-gcc-libs: for generating code/d' PKGBUILD
|
|
|
|
# package_gcc() still manipulates the 32-bit tree in several places, and
|
|
# every one of them fails once multilib is off, because usr/lib32 never
|
|
# exists:
|
|
#
|
|
# 'usr/lib/gcc/s390x-ibm-linux-gnu/16/libatomic.so' -> '../../../libatomic.so'
|
|
# ln: No such file or directory
|
|
#
|
|
# The link that is reported is the one that SUCCEEDED; the failure is the
|
|
# usr/lib32 line right after it, in the same loop. Reading the error alone
|
|
# sends you hunting for a missing libatomic that is in fact present.
|
|
sed -i '/usr\/lib32/d; /_libdir\/32/d' PKGBUILD
|
|
|
|
# The same loop links the D runtimes, which do not exist now that the D
|
|
# front end is off.
|
|
sed -i 's/^\(\s*for _so in \).*; do$/\1libatomic.so libstdc++.so; do/' PKGBUILD
|
|
|
|
# package_gcc() also _picks files out for every sub-package, including the
|
|
# front ends we disabled. _pick is a mv, so it fails on what was never built:
|
|
#
|
|
# mv: cannot stat 'usr/bin/gnat': No such file or directory
|
|
#
|
|
# Dropping the entries from pkgname was not enough -- the _pick lines live in
|
|
# package_gcc() and run regardless of which sub-packages are requested.
|
|
for _lang in gcc-ada gcc-d gcc-go gcc-m2 gcc-rust gcc-gcobol \
|
|
libgm2 libgo libgphobos libgcobol libhwasan; do
|
|
sed -i "/_pick ${_lang} /d" PKGBUILD
|
|
done
|
|
if grep -qE '_pick (gcc-ada|gcc-d|gcc-go|gcc-m2|gcc-rust|gcc-gcobol) ' PKGBUILD; then
|
|
echo "gcc: _pick lines remain for a disabled front end" >&2; exit 1
|
|
fi
|
|
|
|
if grep -q 'usr/lib32' PKGBUILD; then
|
|
echo "gcc: usr/lib32 still manipulated" >&2; exit 1
|
|
fi
|
|
if grep -qE 'for _so in .*(gdruntime|gphobos)' PKGBUILD; then
|
|
echo "gcc: D runtimes still in the symlink loop" >&2; exit 1
|
|
fi
|
|
grep -m1 'for _so in' PKGBUILD | sed 's/^\s*//'
|
|
|
|
# Verify what matters: the array makepkg iterates. Grepping the whole file
|
|
# for the bare name declared a false failure once already, on libtool and
|
|
# then here -- the string survives in comments and in unused functions.
|
|
if sed -n '/^pkgname=(/,/^)/p' PKGBUILD | grep -q 'lib32'; then
|
|
echo "gcc: lib32 still in pkgname array" >&2; exit 1
|
|
fi
|
|
grep -m1 -- '--enable-languages' PKGBUILD
|
|
|
|
# libgccjit: OPTIONAL, and off by default.
|
|
#
|
|
# Arch configures and compiles the entire gcc source tree a SECOND time just
|
|
# for libgccjit -- it needs --enable-host-shared, which would slow the main
|
|
# compiler down if applied to it. That second pass is roughly half of gcc's
|
|
# build time, and on this hardware that is twenty minutes per attempt.
|
|
#
|
|
# Nothing in the bootstrap needs it, and neither does ERPLibre. It is
|
|
# skipped by default and re-enabled with:
|
|
#
|
|
# EL_GCC_JIT=1 bash scripts/build-stage1.sh
|
|
#
|
|
# When enabled, nothing below runs and the PKGBUILD keeps its upstream
|
|
# behaviour, including the --enable-languages=jit line the main-build sed
|
|
# deliberately leaves alone.
|
|
if [ "${EL_GCC_JIT:-0}" != "1" ]; then
|
|
python3 - <<'PY'
|
|
import io, re
|
|
s = io.open("PKGBUILD", encoding="utf-8").read()
|
|
# The second configure pass, from its comment to the copy of the .so.
|
|
s = re.sub(
|
|
r"\n # Build libgccjit separately.*?\n cp -a gcc/libgccjit\.so\* \.\./gcc-build/gcc/\n",
|
|
"\n", s, flags=re.S)
|
|
# Its package function, the _pick lines that feed it, and its pkgname entry.
|
|
s = re.sub(r"\npackage_libgccjit\(\)\s*\{.*?\n\}\n", "\n", s, flags=re.S)
|
|
s = "\n".join(l for l in s.split("\n")
|
|
if "_pick libgccjit" not in l
|
|
and l.strip() != "libgccjit"
|
|
and "mkdir -p \"$srcdir\"/libgccjit-build" not in l)
|
|
io.open("PKGBUILD", "w", encoding="utf-8").write(s)
|
|
PY
|
|
# package_gcc() also installs the jit artefacts explicitly:
|
|
# make -C gcc DESTDIR="$pkgdir" jit.install-common jit.install-info
|
|
# Removing the build block and the pkgname entry was not enough --
|
|
# this line runs in the MAIN package function and fails on a library
|
|
# that was never built:
|
|
# install: cannot install libgccjit.so.0.0.1
|
|
sed -i '/jit\.install-common/d' PKGBUILD
|
|
if grep -q 'libgccjit-build' PKGBUILD; then
|
|
echo "gcc: libgccjit build block remains" >&2; exit 1
|
|
fi
|
|
if sed -n '/^pkgname=(/,/^)/p' PKGBUILD | grep -q 'libgccjit'; then
|
|
echo "gcc: libgccjit still in pkgname array" >&2; exit 1
|
|
fi
|
|
echo "gcc: libgccjit skipped (set EL_GCC_JIT=1 to build it)"
|
|
else
|
|
echo "gcc: libgccjit ENABLED (second full build of the tree)"
|
|
fi
|
|
echo "gcc: front ends reduced, multilib off, lib32 removed"
|