diff --git a/build/build-jasp.sh b/build/build-jasp.sh index 415ddc4..91ab7aa 100755 --- a/build/build-jasp.sh +++ b/build/build-jasp.sh @@ -251,7 +251,23 @@ for lock in root.glob("*/renv.lock"): print(f"patched {patched} lockfiles") PY -Rscript buildAllDefaultJaspModules.R +# renv restores packages concurrently and its ordering is not always +# dependency-correct: a module can be lazy-loaded while a package it needs is +# still being built, e.g. "forecast" failing with "there is no package called +# 'vctrs'" six log lines before vctrs finishes compiling. That aborts the whole +# sapply() loop, so a single race costs every remaining module. +# +# Retrying is the cheap fix: renv skips what is already installed, so each pass +# starts from more complete state and converges. Passes are capped so a genuine +# failure cannot loop forever. +EXPECTED_MODULES=22 +for attempt in 1 2 3; do + log "module build pass ${attempt}/3" + Rscript buildAllDefaultJaspModules.R || true + built="$(find "$MODULE_BUNDLES" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l)" + log "pass ${attempt} finished: ${built}/${EXPECTED_MODULES} bundles" + [[ "$built" -ge "$EXPECTED_MODULES" ]] && break +done if [[ ! -d "$MODULE_LIBRARY/jaspModuleTools" ]]; then echo "error: jaspModuleTools was not installed — install_github failed" >&2 @@ -260,11 +276,14 @@ if [[ ! -d "$MODULE_LIBRARY/jaspModuleTools" ]]; then exit 1 fi +# Guard on the expected count, not merely "non-empty". An earlier run shipped a +# package containing 2 of 22 modules because a non-empty check passed. bundle_count="$(find "$MODULE_BUNDLES" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l)" -if [[ "$bundle_count" -eq 0 ]]; then - echo "error: the module build produced no bundles in ${MODULE_BUNDLES}" >&2 +if [[ "$bundle_count" -lt "$EXPECTED_MODULES" ]]; then + echo "error: only ${bundle_count}/${EXPECTED_MODULES} module bundles were built" >&2 echo " system2() in buildAllDefaultJaspModules.R hides the real error;" >&2 - echo " re-run buildModuleBundlesLocally.R by hand to see it" >&2 + echo " search the log above for 'failed to install'" >&2 + find "$MODULE_BUNDLES" -mindepth 1 -maxdepth 1 -printf ' have: %f\n' 2>/dev/null >&2 exit 1 fi log "module build produced ${bundle_count} bundles" diff --git a/build/bundle-libs.sh b/build/bundle-libs.sh index beb65d7..03aaa1c 100755 --- a/build/bundle-libs.sh +++ b/build/bundle-libs.sh @@ -73,6 +73,11 @@ while [[ "$copied_any" -eq 1 ]]; do # userland we want to capture. while read -r soname path; do [[ -n "$path" && -f "$path" ]] || continue + # ldd reports some entries with an absolute path in the first column — + # the dynamic loader shows up as "/lib64/ld-linux-x86-64.so.2 => ...". + # Without this the denylist misses it and the copy below tries to create + # $LIBDIR/lib64/ld-linux-x86-64.so.2 in a directory that does not exist. + soname="${soname##*/}" is_system_lib "$soname" && continue [[ -f "$LIBDIR/$soname" ]] && continue # Never bundle something that already lives inside our own tree.