diff --git a/patches/pkgbuild/git.sh b/patches/pkgbuild/git.sh index b6ad819..185588a 100755 --- a/patches/pkgbuild/git.sh +++ b/patches/pkgbuild/git.sh @@ -24,6 +24,17 @@ # choice will have to be made then: build Rust, or drop the flag. Recorded now # rather than discovered twice. set -euo pipefail +# STAGE 1 ONLY -- this section, not this file. +# +# It used to be expressed by naming this hook in STAGE2_SKIP_HOOKS, which skips +# the whole FILE. Then a section was appended that both stages need, and it +# silently never ran: the package kept failing in stage 2 on the very thing the +# new section fixes, and the log said "hook skipped (stage-1 only)" about a hook +# that was now two thirds relevant. +# +# The scope belongs next to the reason, so each section decides for itself. +if [ "${EL_STAGE:-1}" = 1 ]; then + python3 - <<'PY' import io s = io.open("PKGBUILD", encoding="utf-8").read() @@ -45,6 +56,9 @@ grep -q "'zlib-ng'" PKGBUILD && { grep -qF "'grep' 'shadow' 'zlib')" PKGBUILD || { echo "git: zlib not substituted in depends" >&2; exit 1; } echo "git: plain zlib (no zlib-ng headers on the host); STAGE-1 ONLY" +else + echo "git: zlib-ng available in the chroot; keeping Arch's choice" +fi # --- no man pages ------------------------------------------------------------- # diff --git a/patches/pkgbuild/libarchive.sh b/patches/pkgbuild/libarchive.sh index ecb0529..8290974 100755 --- a/patches/pkgbuild/libarchive.sh +++ b/patches/pkgbuild/libarchive.sh @@ -37,6 +37,15 @@ # leaves the package uninstallable for a reason the diff appears to fix -- the # fifth place, and the one that has cost the most time in this port. set -euo pipefail + +# STAGE 1 ONLY, the whole file. Expressed here rather than in a list kept by the +# driver: a list of file names cannot say WHY, and when a hook later grows a +# section that both stages need, the list silently skips that too. That happened +# to git and meson. +if [ "${EL_STAGE:-1}" != 1 ]; then + echo "libarchive: nothing to do at stage 2 -- our libxml2 and icu agree in the chroot" + exit 0 +fi python3 - <<'ZZPY' import io, re s = io.open("PKGBUILD", encoding="utf-8").read() diff --git a/patches/pkgbuild/libgcrypt.sh b/patches/pkgbuild/libgcrypt.sh index 6e94427..7af1ab6 100755 --- a/patches/pkgbuild/libgcrypt.sh +++ b/patches/pkgbuild/libgcrypt.sh @@ -53,6 +53,15 @@ # MAKEFLAGS bound inside build() rather than at hook level. set -euo pipefail +# STAGE 1 ONLY, the whole file. Expressed here rather than in a list kept by the +# driver: a list of file names cannot say WHY, and when a hook later grows a +# section that both stages need, the list silently skips that too. That happened +# to git and meson. +if [ "${EL_STAGE:-1}" != 1 ]; then + echo "libgcrypt: nothing to do at stage 2 -- our libgpg-error is installed in the chroot" + exit 0 +fi + WORK="${WORK:-$HOME/work/arch-s390x}" PREFIX="$WORK/stage1-prefix" diff --git a/patches/pkgbuild/meson.sh b/patches/pkgbuild/meson.sh index 49a759d..01c6511 100755 --- a/patches/pkgbuild/meson.sh +++ b/patches/pkgbuild/meson.sh @@ -40,6 +40,17 @@ # will actually import this. Deriving it from the interpreter running the build # is the intuitive thing and the wrong one. set -euo pipefail +# STAGE 1 ONLY -- this section, not this file. +# +# It used to be expressed by naming this hook in STAGE2_SKIP_HOOKS, which skips +# the whole FILE. Then a section was appended that both stages need, and it +# silently never ran: the package kept failing in stage 2 on the very thing the +# new section fixes, and the log said "hook skipped (stage-1 only)" about a hook +# that was now two thirds relevant. +# +# The scope belongs next to the reason, so each section decides for itself. +if [ "${EL_STAGE:-1}" = 1 ]; then + python3 - <<'ZZPY' import io s = io.open("PKGBUILD", encoding="utf-8").read() @@ -89,6 +100,9 @@ ZZPY grep -q 'posix_local scheme installs' PKGBUILD || { echo "meson: the relocation was not inserted" >&2; exit 1; } echo "meson: wheel relocated out of /usr/local; STAGE-1 ONLY" +else + echo "meson: chroot python has no posix_local scheme; no relocation needed" +fi # --- no reference manual ------------------------------------------------------ # diff --git a/scripts/bootstrap-pacman.sh b/scripts/bootstrap-pacman.sh index 3d369b3..3f35e0e 100755 --- a/scripts/bootstrap-pacman.sh +++ b/scripts/bootstrap-pacman.sh @@ -403,7 +403,11 @@ build_package() { local hook="$PATCH_DIR/$name.sh" if [ -f "$hook" ]; then git checkout -- PKGBUILD 2>/dev/null || true - bash "$hook" || return 1 + # EL_STAGE tells the hook which stage is asking. Some hooks -- git, + # meson, libgcrypt, libarchive -- exist partly or wholly to work around + # something about the HOST, and that part must not run in the chroot + # where the problem does not exist. + EL_STAGE=1 bash "$hook" || return 1 fi rm -f ./*.pkg.tar.* # Explicit `|| return 1`. Relying on `set -e` here does NOT work: callers diff --git a/scripts/build-stage2.sh b/scripts/build-stage2.sh index 8b45040..21ba418 100755 --- a/scripts/build-stage2.sh +++ b/scripts/build-stage2.sh @@ -687,7 +687,7 @@ NOTE # backstop. # # libxml2 -- because the xar cycle reformed INSIDE stage 2. libarchive is in -# STAGE2_SKIP_HOOKS, so stage 2 rebuilt it as Arch does, with xar, linking the +# a hook that runs at stage 1 only, so stage 2 rebuilt it as Arch does, with # libxml2 that happened to be installed at that moment: the stage-1 one, which # wants the host's libicuuc.so.76. bsdtar then could not start, and bsdtar is # what makepkg uses to extract sources and write packages -- so 39 of 39 @@ -781,8 +781,6 @@ CHROOT_STAGE2_PKGS=( python-setuptools-scm ) -STAGE2_SKIP_HOOKS=(libgcrypt git meson libarchive) - # Packages whose sources must be extracted on the HOST, because the chroot # cannot extract anything until they are rebuilt. # @@ -825,12 +823,6 @@ host_extract() { return 1 } -skip_hook() { - local n="$1" h - for h in "${STAGE2_SKIP_HOOKS[@]}"; do [ "$n" = "$h" ] && return 0; done - return 1 -} - # stage2_build -- rebuild one package inside the chroot and install it. # # The hook is applied on the HOST, not in the chroot: hooks are seds over the @@ -843,10 +835,18 @@ stage2_build() { ( cd "$dir" && git checkout -- PKGBUILD 2>/dev/null ) || true if [ -f "$PATCH_DIR/$name.sh" ]; then - if skip_hook "$name"; then - echo " hook skipped (stage-1 only)" - else - ( cd "$dir" && bash "$PATCH_DIR/$name.sh" ) || { + # EL_STAGE=2, and no skip list any more. + # + # There WAS a list -- naming hooks to ignore here. It skipped the + # whole FILE, and that broke silently the moment a listed hook grew a + # section both stages need: git and meson each kept failing in stage + # 2 on exactly what their new sections fix, while the log said + # "hook skipped (stage-1 only)" about a hook that was by then two + # thirds relevant. + # + # A list of file names cannot say why. The hooks read EL_STAGE and + # decide per section, with the reason written beside the guard. + ( cd "$dir" && EL_STAGE=2 bash "$PATCH_DIR/$name.sh" ) || { echo " hook failed" >&2; return 1; } # A hook can leave a PKGBUILD that no longer parses, and makepkg # reports that far from its cause: @@ -863,7 +863,6 @@ stage2_build() { # calls a valid file broken without it. ( cd "$dir" && bash -O extglob -n PKGBUILD ) || { echo " hook left an unparseable PKGBUILD" >&2; return 1; } - fi fi ( cd "$dir" && rm -f ./*.pkg.tar.* ) || true