diff --git a/patches/pkgbuild/ca-certificates.sh b/patches/pkgbuild/ca-certificates.sh new file mode 100755 index 0000000..6d6caad --- /dev/null +++ b/patches/pkgbuild/ca-certificates.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ca-certificates: no man page for update-ca-trust. +# +# a2x: command not found +# +# a2x belongs to asciidoc, a Python toolchain whose only job here is turning +# update-ca-trust.8.txt into update-ca-trust.8. TWO lines have to go, not one: +# build() renders it and package() installs it. Removing only the render leaves +# +# install: cannot stat 'update-ca-trust.8' +# +# which is the same shape as libxml2's docs split -- a failure on the last line +# of package(), naming a path, after a build that worked. +set -euo pipefail +python3 - <<'ZZPY' +import io, re +lines = io.open("PKGBUILD", encoding="utf-8").read().split("\n") +a2x = [i for i, l in enumerate(lines) if re.match(r"^[ \t]*a2x\b", l)] +man = [i for i, l in enumerate(lines) if "update-ca-trust.8" in l and "install " in l] +assert len(a2x) == 1, "ca-certificates: expected one a2x call, got %d" % len(a2x) +assert len(man) == 1, "ca-certificates: expected one man install, got %d" % len(man) +lines[a2x[0]] = " # a2x removed: no asciidoc toolchain at either stage." +lines[man[0]] = " # man page not installed: nothing rendered it." +out = [l.replace(" asciidoc\n", "") for l in lines] +io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(out)) +ZZPY +grep -q "a2x removed" PKGBUILD && grep -q "nothing rendered it" PKGBUILD || { + echo "ca-certificates: one of the two lines was not replaced" >&2; exit 1; } +echo "ca-certificates: update-ca-trust man page dropped" diff --git a/patches/pkgbuild/cryptsetup.sh b/patches/pkgbuild/cryptsetup.sh new file mode 100755 index 0000000..a69d0fb --- /dev/null +++ b/patches/pkgbuild/cryptsetup.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# cryptsetup: no asciidoctor, so no rendered man pages. +# +# configure: error: Building man pages requires asciidoctor installed. +# +# asciidoctor is Ruby. Packaging Ruby to render cryptsetup's man pages is the +# largest of the three documentation closures this port declined, and the least +# justified: the error names the flag that turns it off. +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]*\./configure\b", l)] +assert len(hit) == 1, "cryptsetup: expected one ./configure, got %d" % len(hit) +i = hit[0] +indent = re.match(r"^[ \t]*", lines[i]).group(0) +assert lines[i].rstrip().endswith("\\"), "cryptsetup: ./configure does not continue" +lines.insert(i + 1, indent + " --disable-asciidoc \\") +out = [l.replace(" 'asciidoctor'", "") if "makedepends" in l else l for l in lines] +io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(out)) +ZZPY +grep -A1 -E "^[[:space:]]*\./configure" PKGBUILD | grep -q -- '--disable-asciidoc' || { + echo "cryptsetup: the flag is not on ./configure" >&2; exit 1; } +echo "cryptsetup: man pages disabled" diff --git a/patches/pkgbuild/fakeroot.sh b/patches/pkgbuild/fakeroot.sh new file mode 100755 index 0000000..a4ce965 --- /dev/null +++ b/patches/pkgbuild/fakeroot.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# fakeroot: no translated man pages. +# +# po4a: command not found +# +# build() ends on a po4a call that renders the man page into every language it +# has a catalogue for. po4a is Perl, and packaging it means packaging its module +# stack -- perl-yaml-tiny, perl-syntax-keyword-try, perl-term-readkey, +# perl-locale-gettext and more -- so that fakeroot's man page exists in Polish. +# +# fakeroot is not optional the way its man pages are: makepkg cannot build a +# package without it. Same arbitration as --auto-features auto in +# build-stage2.sh, and the same note for stage 3. +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]*po4a\b", l)] +assert len(hit) == 1, "fakeroot: expected one po4a call, got %d" % len(hit) +lines[hit[0]] = " # po4a call removed: no Perl module stack at either stage." +out = [] +for l in lines: + # makedepends too, or --nodeps is the only thing hiding the gap. + out.append(l.replace(" 'po4a'", "") if "makedepends" in l else l) +io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(out)) +ZZPY +grep -qE "^[ \t]*po4a " PKGBUILD && { echo "fakeroot: a po4a call survived" >&2; exit 1; } +grep -q "po4a call removed" PKGBUILD || { echo "fakeroot: nothing was removed" >&2; exit 1; } +echo "fakeroot: translated man pages dropped" diff --git a/patches/pkgbuild/gcc.sh b/patches/pkgbuild/gcc.sh index f2db2d5..49e85dd 100755 --- a/patches/pkgbuild/gcc.sh +++ b/patches/pkgbuild/gcc.sh @@ -401,3 +401,47 @@ PY grep -qF 'ln -sfv ../../../libgcc_s.so.1' PKGBUILD || { echo "gcc: libgcc_s.so link not repointed" >&2; exit 1; } echo "gcc: libgcc_s.so repointed to ../../../libgcc_s.so.1" + +# --- the baseline CPU of the compiler we SHIP --------------------------------- +# +# Arch's PKGBUILD names no s390x baseline, because Arch has no s390x. GCC's own +# fallback for this target is arch5 -- z900, from the year 2000 -- and that is +# what our gcc defaulted to while the host's Ubuntu gcc is configured +# --with-arch=z13 --with-tune=z16. The consequence was not a warning: +# +# contrib/crc32vx/crc32_vx.c:205:10: error: +# '__builtin_s390_vec_unpackl' requires '-mvx' +# +# zlib's configure had detected vector support and defined -DHAVE_S390X_VX, +# then compiled with a compiler told to assume a machine that has none. +# +# build-stage2.sh sets the same pair in the chroot's makepkg.conf, which governs +# how this distribution is COMPILED. This governs what the compiler we HAND OVER +# assumes when someone builds on the target with no flags at all. Doing only the +# first leaves a gcc that silently goes back to 2000. +# +# z13 because that is what the host distribution already requires: adopting it +# cannot stop anything from running that runs today. +python3 - <<'ZZPY' +import io, re +lines = io.open("PKGBUILD", encoding="utf-8").read().split("\n") +hit = [i for i, l in enumerate(lines) if "--enable-languages=" in l and "jit" not in l] +assert len(hit) == 1, "gcc: expected one main --enable-languages line, got %d" % len(hit) +i = hit[0] +indent = re.match(r"^[ \t]*", lines[i]).group(0) +assert lines[i].rstrip().endswith("\\"), "gcc: --enable-languages does not continue" +lines.insert(i + 1, indent + "--with-arch=z13 --with-tune=z16 \\") +io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(lines)) +ZZPY +grep -q -- '--with-arch=z13' PKGBUILD || { echo "gcc: baseline not set" >&2; exit 1; } +# On the configure line, not merely in the file. +# +# The first version of this check anchored on --enable-languages=ada and failed +# on a PKGBUILD that was correctly patched: a section ABOVE has already +# rewritten the language list, so `ada` is gone by the time this runs. The +# guard was testing its own stale assumption about the file rather than the +# edit -- the fourth time in this port that a check has verified something +# adjacent to what it meant. Anchor on what the python actually matched. +grep -A1 -E -- '--enable-languages=' PKGBUILD | grep -q -- '--with-arch=z13' || { + echo "gcc: --with-arch is in the file but not on the configure line" >&2; exit 1; } +echo "gcc: baseline z13, tune z16" diff --git a/scripts/build-stage2.sh b/scripts/build-stage2.sh index 553d178..832812c 100755 --- a/scripts/build-stage2.sh +++ b/scripts/build-stage2.sh @@ -62,6 +62,17 @@ CHROOT_PKGS=( # stage 2 tries -- stopped on `rsync: command not found`. The host had it # from apt, which is exactly why stage 1 never mentioned it. rsync + # The same class, named by the failures of the first full pass rather than + # guessed at. Each one is here because a package said so: + # + # gperf coreutils, diffutils, systemd, libseccomp + # wget sed, grep, findutils + # patchelf curl + # inetutils gnupg, for hostname + # libxslt shadow, for xsltproc + # swig audit + # help2man flex + gperf wget patchelf inetutils libxslt swig help2man # libxcrypt-compat, for a reason no declaration expresses. perl declares # `libxcrypt` and `libcrypt.so`, both satisfied by libxcrypt, which ships # libcrypt.so.2. But perl's BINARY was linked on the host against Ubuntu's @@ -207,16 +218,46 @@ configure_chroot() { sudo tee -a "$ROOT/etc/makepkg.conf" > /dev/null <<'EOC' # --- stage 2: the shipped values are Arch's x86_64 ones --- -CFLAGS="" -CXXFLAGS="" -LDFLAGS="" +# +# THE BASELINE CPU OF THIS PORT, which was being decided by accident. +# +# zlib stopped on +# +# contrib/crc32vx/crc32_vx.c:205:10: error: +# '__builtin_s390_vec_unpackl' requires '-mvx' +# +# after its own configure had detected vector support and defined +# -DHAVE_S390X_VX. Both halves were right, which is what made it worth +# measuring instead of patching: +# +# host gcc (Ubuntu) --with-arch=z13 --with-tune=z16 default -march=arch11 +# our gcc (nothing) default -march=arch5 +# +# arch5 is z900, from 2000. arch11 is z13, from 2015. Arch's PKGBUILD names no +# s390x baseline because Arch has no s390x, so our gcc fell back to the oldest +# machine the port could possibly run on -- and every package using a vector +# intrinsic failed, while zlib's configure went on detecting a CPU the compiler +# had been told to forget. +# +# z13 is not a guess: it is what Ubuntu s390x, the host distribution, already +# requires, so nothing that runs here today stops running. Every distribution +# picks one of these; this port had simply never said which, and silence chose +# the year 2000. +# +# TWO PLACES, because they answer different questions. Here is how this +# distribution is COMPILED. patches/pkgbuild/gcc.sh passes --with-arch to the +# compiler we SHIP, so a build done later on the target assumes the same +# machine. Setting only this one leaves a gcc that quietly reverts to arch5. +CFLAGS="-march=z13 -mtune=z16 -O2 -pipe -fno-plt -fexceptions" +CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS" +LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now" LTOFLAGS="" RUSTFLAGS="" DEBUG_CFLAGS="" DEBUG_CXXFLAGS="" EOC sudo grep -E '^(CARCH|CHOST|MAKEFLAGS|OPTIONS)=' "$ROOT/etc/makepkg.conf" | sed 's/^/ /' - printf ' compiler flags: emptied (stage 1 used none)\n' + printf ' baseline: -march=z13 -mtune=z16 (host Ubuntu uses the same)\n' # --auto-features auto, for this chroot only. # diff --git a/scripts/packages.sh b/scripts/packages.sh index df9190e..4ebb121 100644 --- a/scripts/packages.sh +++ b/scripts/packages.sh @@ -202,4 +202,28 @@ STAGE1_PACKAGES=( # because rsync links it. xxhash rsync + # 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) + # xsltproc shadow (libxslt ships it) + # 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 + libxslt + swig + help2man )