Compile modules one at a time, and let V8 fetch its own libv8

Upstream's buildModuleBundlesLocally.R sapply()s over the modules, so the first
failure silently abandons every module after it. The resumed build stopped at
26/36 this way: jaspPower failed on V8, and the nine modules behind it were
never attempted in any of the four passes. build/build-modules.R compiles each
module under tryCatch, reports what failed and carries on, and also skips
reinstalling devtools and jaspModuleTools on every call.

V8 needs libv8, which Arch does not package; DOWNLOAD_STATIC_LIBV8=1 makes its
configure download upstream's static build.

Claude-Session: https://claude.ai/code/session_01GGe7kUhooMFuzY6GaDb2w9
This commit is contained in:
agw
2026-09-30 20:35:00 +02:00
parent 35756d2afb
commit 274f22493b
2 changed files with 48 additions and 13 deletions
+14 -13
View File
@@ -196,12 +196,11 @@ log "compiling JASP (-j$JOBS)"
ninja -C "$BUILD_DIR" -j"$JOBS"
# The R modules are the long pole: several hundred R packages compiled from
# source. buildAllDefaultJaspModules.R shells out to buildModuleBundlesLocally.R
# via system2(), which does NOT check exit status — so every failure below is
# silent and the script still exits 0. The guards after it are what actually
# catch a broken module build.
# source. build/build-modules.R reports a failed module and carries on rather
# than exiting non-zero, so the guards after it are what actually catch a
# broken module build.
#
# GITHUB_PAT is required, not optional: buildModuleBundlesLocally.R does
# GITHUB_PAT is required, not optional: jaspModuleTools is installed with
# install_github('jasp-stats/jaspModuleTools'), and anonymous GitHub API rate
# limits make that fail. When it fails, no bundles are produced at all and the
# build otherwise looks successful.
@@ -217,12 +216,10 @@ log "building R modules — this is the slow part"
mkdir -p "$BUILD_DIR"/Modules/{binary_pkgs,manifests,module_libs,Tools}
cd "$SRC_DIR/Tools"
# buildModuleBundlesLocally.R calls devtools::install_github(), which since
# devtools 2.5.0 is deprecated and delegates to the `remotes` package — but
# remotes is no longer a hard dependency of devtools, so the call dies with
# "The package \"remotes\" is required." Pre-seed it into the same library the
# script uses, since that script does .libPaths(new=userLibrary) and would not
# see remotes anywhere else.
# jaspModuleTools is installed from GitHub with `remotes`, which devtools >= 2.5
# no longer pulls in ("The package \"remotes\" is required."). Pre-seed it into
# the library build-modules.R uses, since that does .libPaths(new=userLibrary)
# and would not see remotes anywhere else.
MODULE_LIBRARY="$SRC_DIR/Tools/ModuleBundleBuildDir/LibraryR"
MODULE_BUNDLES="$SRC_DIR/Modules/local"
@@ -329,6 +326,10 @@ purge_stale_renv_cache() {
}
purge_stale_renv_cache
# The R package V8 (jaspPower, via gt and juicyjuice) needs libv8, which Arch
# does not package; this makes its configure fetch upstream's static build.
export DOWNLOAD_STATIC_LIBV8=1
# ccache for R package compiles too: cheap insurance for when renv reinstalls a
# package whose compiler inputs did not actually change.
export PATH="/usr/lib/ccache/bin:$PATH"
@@ -340,7 +341,7 @@ log "clearing stale R install locks"
rm -rf "${MODULE_LIBRARY}"/00LOCK-* 2>/dev/null || true
# The interrupted install can also leave the library without devtools, which
# buildModuleBundlesLocally.R calls unconditionally. Reinstall whatever is
# the jaspModuleTools install relies on. Reinstall whatever is
# missing rather than assuming a clean slate.
Rscript -e "
lib <- '${MODULE_LIBRARY}'
@@ -415,7 +416,7 @@ for attempt in 1 2 3; do
done
[[ ${#MODULE_PATHS[@]} -eq 0 ]] && break
log "module build pass ${attempt}/3: ${#MODULE_PATHS[@]} modules left"
./buildModuleBundlesLocally.R "${MODULE_PATHS[@]}" || true
Rscript /work/build/build-modules.R "${MODULE_PATHS[@]}" || true
built=0
for module in "${ALL_MODULES[@]}"; do
[[ -f "${MODULE_BUNDLES}/${module}.JASPModule" ]] && built=$((built + 1))
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env Rscript
# Stand-in for Tools/buildModuleBundlesLocally.R. Upstream's script sapply()s
# over the modules, so the first failure aborts every module after it, and it
# reinstalls devtools and jaspModuleTools on every call. This compiles each
# module on its own, reports failures and carries on.
options(repos = 'https://cran.r-project.org', jaspRemoteCellarRedownload = FALSE)
workdir <- './ModuleBundleBuildDir'
userLibrary <- file.path(workdir, 'LibraryR')
dir.create(userLibrary, recursive = TRUE, showWarnings = FALSE)
.libPaths(new = userLibrary)
if (!requireNamespace('jaspModuleTools', quietly = TRUE)) {
for (pkg in c('remotes', 'devtools'))
if (!requireNamespace(pkg, quietly = TRUE)) install.packages(pkg, lib = userLibrary)
remotes::install_github('jasp-stats/jaspModuleTools', lib = userLibrary)
}
here <- getwd()
failed <- character()
for (mod in commandArgs(trailingOnly = TRUE)) {
message('==> compiling ', basename(mod))
ok <- tryCatch({
jaspModuleTools::compile(mod, workdir = file.path(workdir, 'build_dir'),
resultdir = '../Modules/local', bundleAll = TRUE)
TRUE
}, error = function(e) {
message('==> FAILED ', basename(mod), ': ', conditionMessage(e))
FALSE
})
setwd(here) # compile() may leave us elsewhere when it errors
if (!ok) failed <- c(failed, basename(mod))
}
if (length(failed)) message('==> modules that failed: ', paste(failed, collapse = ' '))