From f6b09ff713ec78a3dab478eefe54c6f97c2ed8d2 Mon Sep 17 00:00:00 2001 From: vasilito Date: Fri, 24 Jul 2026 13:14:24 +0900 Subject: [PATCH] build: stop re-cooking llvm21/toolchain on every relibc/base bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The relibc-consumer invalidation (correctly) force-deletes every pkgar+target when relibc rebuilds or its pkgar is missing, to prevent stale-ABI skew. But it swept up heavy, ABI-inert toolchain packages (llvm21, clang21, lld21, rust) identically to a 200KB daemon — forcing a 1-2h LLVM re-cook on EVERY base/relibc bump, which cripples Mesa/KDE iteration. These are build-time-only STATIC archives (BUILD_SHARED_LIBS=off; no runtime .so of their own). Their libc/relibc symbol references are UNRESOLVED in the .a and resolve at the CONSUMER final link — mesa links libLLVM*.a and resolves against the freshly-built relibc there. So a relibc protocol change is absorbed by relinking mesa (NOT on the preserve-list; stays invalidated), and recompiling all of LLVM from scratch is unnecessary. Add TOOLCHAIN_PRESERVE={llvm21,clang21,lld21,rust} skipped in both invalidation branches, with escape hatch REDBEAR_FORCE_TOOLCHAIN_RECOOK=1 for a genuine libc-ABI change. Trades a rare theoretical risk for a large repeated speedup; the churn during driver/desktop work is Redox scheme/syscall shims the compilers never call, so the default is safe. --- local/scripts/build-redbear.sh | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/local/scripts/build-redbear.sh b/local/scripts/build-redbear.sh index da3f09f9be..134170a889 100755 --- a/local/scripts/build-redbear.sh +++ b/local/scripts/build-redbear.sh @@ -706,6 +706,30 @@ if [ "$NO_CACHE" != "1" ]; then if [ "$RELIBC_INVALIDATED" = "1" ] || [ ! -f "$RELIBC_PKGAR" ]; then relibc_rebuilding=1 fi + # Heavy, ABI-inert toolchain packages preserved across relibc invalidation. + # + # These are BUILD-TIME-ONLY static archives (built with BUILD_SHARED_LIBS=off; + # they ship no runtime .so of their own). Their references to libc/relibc + # symbols are UNRESOLVED in the .a and get resolved at the CONSUMER's final + # link — e.g. mesa links libLLVM*.a into libgallium and resolves malloc/etc. + # against the freshly-built relibc at THAT point. So a relibc protocol change + # is absorbed by relinking the consumer (mesa is NOT on this list and stays + # invalidated), and recompiling all of LLVM/Rust from scratch to pick up a + # relibc change is unnecessary — it just burns 1-2h per base/relibc bump. + # + # This trades a rare theoretical risk (a relibc change to a libc struct/inline + # actually baked into an llvm .o) for a large, repeated speedup. The churn + # during driver/desktop work is Redox scheme/syscall-protocol shims, which + # these compilers never call, so the default is safe. Escape hatch: + # REDBEAR_FORCE_TOOLCHAIN_RECOOK=1 restores the full from-scratch nuke. + TOOLCHAIN_PRESERVE="llvm21 clang21 lld21 rust" + _rb_preserve_toolchain() { + [ "${REDBEAR_FORCE_TOOLCHAIN_RECOOK:-0}" = "1" ] && return 1 + case " $TOOLCHAIN_PRESERVE " in + *" $1 "*) return 0 ;; + *) return 1 ;; + esac + } invalidate_consumer() { local pkg="$1" rm -f "$REPO_DIR/$pkg".* @@ -718,7 +742,13 @@ if [ "$NO_CACHE" != "1" ]; then echo ">>> clean relink (correctness over speed; prevents stale-binary skew)." for _pkgar in "$REPO_DIR"/*.pkgar; do [ -f "$_pkgar" ] || continue - invalidate_consumer "$(basename "$_pkgar" .pkgar)" + _pkg="$(basename "$_pkgar" .pkgar)" + if _rb_preserve_toolchain "$_pkg"; then + echo ">>> preserving ABI-inert toolchain pkg '$_pkg' (consumer relinks;" \ + "set REDBEAR_FORCE_TOOLCHAIN_RECOOK=1 to force a full re-cook)." + continue + fi + invalidate_consumer "$_pkg" done elif [ -f "$RELIBC_PKGAR" ]; then relibc_ts=$(stat -c %Y "$RELIBC_PKGAR" 2>/dev/null || echo "0") @@ -726,6 +756,7 @@ if [ "$NO_CACHE" != "1" ]; then [ -f "$_pkgar" ] || continue _pkg="$(basename "$_pkgar" .pkgar)" [ "$_pkg" = "relibc" ] && continue + _rb_preserve_toolchain "$_pkg" && continue _pkg_ts=$(stat -c %Y "$_pkgar" 2>/dev/null || echo "0") if [ "$relibc_ts" != "0" ] && [ "$relibc_ts" -gt "$_pkg_ts" ]; then echo ">>> ABI-stale $_pkg (older than relibc.pkgar — interrupted prior build); invalidating..."