diff --git a/patches/pkgbuild/gcc.sh b/patches/pkgbuild/gcc.sh index d5e4dc2..6b30c64 100755 --- a/patches/pkgbuild/gcc.sh +++ b/patches/pkgbuild/gcc.sh @@ -1,24 +1,79 @@ #!/usr/bin/env bash -# gcc: keep only the front ends that bootstrap without an existing compiler -# of the same language. +# gcc: three x86 assumptions, all fatal on s390x. # -# configure: error: GNAT is required to build ada -# configure: error: GDC is required to build d +# 1. Front ends written in themselves. # -# Ada and D are written in themselves: building their front ends needs an -# existing Ada or D compiler of a compatible vintage. Ubuntu ships gnat, but -# not one GCC 15 accepts, and D has no bootstrap compiler here at all. -# Modula-2 and COBOL have the same shape of problem. +# configure: error: GNAT is required to build ada +# configure: error: GDC is required to build d # -# Nothing in a core bootstrap -- and nothing in ERPLibre -- is written in any -# of them. C, C++, Fortran, LTO and the Objective-C front ends cover -# everything the rest of this port compiles. +# 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. # -# STAGE 1 CONCESSION, not a permanent one. Once the port is self-hosting its -# own gcc can bootstrap the others, and this hook should be revisited. +# 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 + sed -i '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_() 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 + +# 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 -grep -qE 'enable-languages=[^ ]*(ada|,d,|m2|cobol)' PKGBUILD && { - echo "gcc: a self-hosted front end is still enabled" >&2; exit 1; } -echo "gcc: front ends reduced to those that bootstrap from C" +echo "gcc: front ends reduced, multilib off, lib32 removed" diff --git a/patches/pkgbuild/glibc.sh b/patches/pkgbuild/glibc.sh index 51c5e63..d66fc2b 100755 --- a/patches/pkgbuild/glibc.sh +++ b/patches/pkgbuild/glibc.sh @@ -1,18 +1,44 @@ #!/usr/bin/env bash -# glibc: SFrame does not exist on s390x. +# glibc: two x86-only assumptions, both fatal on s390x. # -# Arch's PKGBUILD passes --enable-sframe, added when x86_64 gained SFrame -# stack tracing. glibc's own configure rejects it outright on this -# architecture: +# 1. SFrame. # -# configure: error: the architecture doesn't support SFrame +# Arch passes --enable-sframe, added when x86_64 gained SFrame stack +# tracing. glibc's configure rejects it outright here: # -# This is not a build-environment problem and no host package fixes it: the -# feature is genuinely absent from s390x. Dropping the flag is what a port -# does -- and it must be dropped surgically, leaving every other configure -# option untouched, so that a future Arch change to this PKGBUILD is not -# silently discarded. +# configure: error: the architecture doesn't support SFrame +# +# No host package fixes this: the feature is genuinely absent from s390x. +# +# 2. lib32-glibc. +# +# glibc is a split package whose second half is the 32-bit multilib +# build. The main glibc package builds and packages perfectly -- measured, +# the whole compile succeeds -- and then makepkg aborts in +# package_lib32-glibc() with "No rule to make target 'install'", because +# the 32-bit tree was never configured. +# +# lib32 is i686-on-x86_64. On s390x there is no 32-bit userspace to build +# against, and the deprecated 31-bit ABI is not it either. +# +# Both are removed rather than repaired: what is being removed is +# architecture-specific by nature. set -euo pipefail + sed -i '/--enable-sframe/d' PKGBUILD grep -q -- '--enable-sframe' PKGBUILD && { echo "glibc: sframe flag still present" >&2; exit 1; } -echo "glibc: --enable-sframe removed (unsupported on s390x)" + +# Drop the lib32 half: package list, its build steps and its package function. +sed -i 's/^pkgname=(glibc lib32-glibc\(.*\))$/pkgname=(glibc\1)/' PKGBUILD +sed -i '/lib32-gcc-libs/d' PKGBUILD +python3 - <<'PY' +import io, re +s = io.open("PKGBUILD", encoding="utf-8").read() +# The package function, and the build block guarded by the 32-bit tree. +s = re.sub(r"\npackage_lib32-glibc\(\)\s*\{.*?\n\}\n", "\n", s, flags=re.S) +io.open("PKGBUILD", "w", encoding="utf-8").write(s) +PY +grep -q 'package_lib32-glibc' PKGBUILD && { echo "glibc: lib32 package function remains" >&2; exit 1; } +grep -qE '^pkgname=\(glibc( |\))' PKGBUILD || { echo "glibc: pkgname not reduced" >&2; exit 1; } +grep -m1 '^pkgname=' PKGBUILD +echo "glibc: --enable-sframe removed, lib32 split package removed" diff --git a/scripts/devtools/arch-cmake b/scripts/devtools/arch-cmake new file mode 100755 index 0000000..383a2fb --- /dev/null +++ b/scripts/devtools/arch-cmake @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# Minimal stand-in for devtools' arch-cmake, same reasoning as arch-meson. +exec cmake \ + -DCMAKE_BUILD_TYPE=None \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DCMAKE_INSTALL_LIBEXECDIR=lib \ + -DCMAKE_INSTALL_SBINDIR=bin \ + -DBUILD_SHARED_LIBS=ON \ + -Wno-dev \ + "$@" diff --git a/scripts/devtools/arch-meson b/scripts/devtools/arch-meson new file mode 100755 index 0000000..1de327d --- /dev/null +++ b/scripts/devtools/arch-meson @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Minimal stand-in for devtools' arch-meson. +# +# A number of Arch PKGBUILDs call arch-meson rather than meson directly. It +# ships in the `devtools` package, which is itself an Arch package -- so +# during a bootstrap it does not exist yet, and every PKGBUILD that uses it +# stops on "arch-meson: command not found". +# +# This reproduces the options devtools passes, which are what the PKGBUILDs +# assume: /usr prefix, plain buildtype so makepkg's CFLAGS are honoured +# verbatim, and no network access for subprojects. +exec meson setup \ + --prefix /usr \ + --libexecdir lib \ + --sbindir bin \ + --buildtype plain \ + --auto-features enabled \ + --wrap-mode nodownload \ + -D b_pie=true \ + -D python.bytecompile=1 \ + "$@"