build: scope ABI-staleness invalidation to the config being built

The relibc-consumer ABI sweep looped over the whole shared repo/*.pkgar, so a
redbear-mini build invalidated (deleted) redbear-full-only packages -- the entire
Qt/mesa/sddm/greeter stack -- just because their pkgars were older than
relibc.pkgar. Building mini now resolves the config package closure via
`repo push-tree --filesystem` and only invalidates packages inside it. Build
mini, touch mini; full artifacts are never collateral. No env flag needed for
the common case.
This commit is contained in:
2026-07-25 07:14:09 +09:00
parent 4822c85e5c
commit 087cae5d35
10 changed files with 11302 additions and 2 deletions
+30
View File
@@ -739,8 +739,36 @@ if [ "$NO_CACHE" != "1" ]; then
*) return 1 ;;
esac
}
# ── Config-scoped ABI invalidation ──────────────────────────────────
# repo/ is shared across configs, so a `redbear-mini` build must NOT nuke
# packages that only `redbear-full` builds (Qt, mesa, sddm, ...) just because
# their pkgars sit in the repo older than relibc.pkgar. Resolve the closure
# of the config being built and only ever invalidate packages inside it.
# No env flag needed — you named the config, so we know it's mini not full.
declare -A _config_pkg_set
_config_scoped=0
_cfg_file="$PROJECT_ROOT/config/$CONFIG.toml"
if [ -f "$_cfg_file" ]; then
while read -r _p; do
[ -n "$_p" ] && _config_pkg_set["$_p"]=1
done < <(timeout 120 "$PROJECT_ROOT/target/release/repo" push-tree \
--filesystem="$_cfg_file" 2>/dev/null \
| sed -E 's/^[^A-Za-z0-9_]+//' | awk '{print $1}' | grep -E '^[A-Za-z0-9]')
[ "${#_config_pkg_set[@]}" -gt 0 ] && _config_scoped=1
fi
if [ "$_config_scoped" = "1" ]; then
echo ">>> ABI-staleness scoped to $CONFIG (${#_config_pkg_set[@]} pkgs); other configs' repo packages untouched."
else
echo ">>> NOTE: could not resolve $CONFIG package closure; ABI sweep is repo-wide (fallback)."
fi
_pkg_in_config() {
# true unless we have a config closure and pkg is outside it
[ "$_config_scoped" != "1" ] && return 0
[ -n "${_config_pkg_set[$1]:-}" ]
}
invalidate_consumer() {
local pkg="$1"
_pkg_in_config "$pkg" || return 0
rm -f "$REPO_DIR/$pkg".*
find "$PROJECT_ROOT/recipes" "$PROJECT_ROOT/local/recipes" \
-path "*/$pkg/target" -type d -exec rm -rf {} + 2>/dev/null || true
@@ -762,6 +790,7 @@ if [ "$NO_CACHE" != "1" ]; then
for _pkgar in "$REPO_DIR"/*.pkgar; do
[ -f "$_pkgar" ] || continue
_pkg="$(basename "$_pkgar" .pkgar)"
_pkg_in_config "$_pkg" || continue
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)."
@@ -775,6 +804,7 @@ if [ "$NO_CACHE" != "1" ]; then
[ -f "$_pkgar" ] || continue
_pkg="$(basename "$_pkgar" .pkgar)"
[ "$_pkg" = "relibc" ] && continue
_pkg_in_config "$_pkg" || 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