diff --git a/local/scripts/build-redbear.sh b/local/scripts/build-redbear.sh index 5435c2ae33..c76acee5a9 100755 --- a/local/scripts/build-redbear.sh +++ b/local/scripts/build-redbear.sh @@ -9,7 +9,7 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # REDBEAR_VERSION (which tracks the OS release derived from the git branch). # Starts at 1.0 and is bumped AUTOMATICALLY on every change by the pre-commit # git hook (local/scripts/bump-build-version.sh); do not edit the minor by hand. -BUILD_REDBEAR_VERSION="1.7" +BUILD_REDBEAR_VERSION="1.8" # ── Colorized output ────────────────────────────────── # Enabled only on a TTY with NO_COLOR unset, so redirected build logs and CI @@ -772,6 +772,46 @@ if [ "$NO_CACHE" != "1" ]; then done + # Vendored-recipe source staleness (the Qt/KDE 6.11.0->6.11.1 / 6.10->6.28 + # class). Many recipes under local/recipes vendor their upstream tree in git + # at /source/ AND declare a [source] tar=. Cookbook keys its build + # cache on the source.tar hash (source_identifier), but the ACTUAL build + # input is the vendored source/ tree. When a version bump propagates into + # source/ WITHOUT changing source.tar (e.g. source.tar was already the new + # version, or a manual source/ edit), cookbook sees an unchanged + # source_identifier and reuses a STALE stage — the desktop then builds the + # old version (qtshadertools wanted Qt 6.11.1 but got a cached 6.11.0 qtbase). + # + # Fix: fingerprint each vendored source/ by its git tree hash (content-based, + # mtime-independent) plus a working-tree-dirty flag, and rm that recipe's + # target/ when it changes. First observation for a recipe only SEEDS the + # fingerprint (no invalidation) so this never triggers a spurious full + # rebuild; thereafter any source/ change forces exactly that recipe to + # re-cook. Mirrors verify-external-source-versions.sh at the cache layer. + while IFS= read -r _rt; do + _rdir="$(dirname "$_rt")" + _sdir="$_rdir/source" + [ -d "$_sdir" ] || continue + _tgt="$_rdir/target/x86_64-unknown-redox" + [ -f "$_tgt/stage.pkgar" ] || continue # nothing cooked yet -> nothing stale + _relsrc="${_sdir#"$PROJECT_ROOT"/}" + _tree="$(git -C "$PROJECT_ROOT" rev-parse "HEAD:$_relsrc" 2>/dev/null || echo "")" + [ -n "$_tree" ] || continue # source/ not git-tracked -> skip + _dirty="" + git -C "$PROJECT_ROOT" diff --quiet HEAD -- "$_relsrc" 2>/dev/null || _dirty="-dirty" + [ -n "$(git -C "$PROJECT_ROOT" ls-files --others --exclude-standard -- "$_relsrc" 2>/dev/null)" ] && _dirty="-dirty" + _cur="${_tree}${_dirty}" + _fp="$_tgt/.redbear-source-tree" + _last="$(cat "$_fp" 2>/dev/null || echo "")" + if [ -z "$_last" ]; then + printf '%s\n' "$_cur" > "$_fp" # seed only, trust the existing build + elif [ "$_cur" != "$_last" ]; then + echo "${C_INFO}>>>${C_RESET} Stale vendored source: $(basename "$_rdir") (source/ changed since last cook) — invalidating target/" + rm -rf "$_rdir/target" + STALE_DETECTED=1 + fi + done < <(find "$PROJECT_ROOT/local/recipes" -name recipe.toml -not -path '*/wip/*' 2>/dev/null) + # (The blanket "wipe every recipe's build/sysroot when a runtime fork changed" # step used to live here. It was the bug: it recompiled the entire dynamically # -linked desktop — Qt, KF6, mesa, sddm — on any relibc/base/syscall change,