diff --git a/.github/workflows/install_github.yml b/.github/workflows/install_github.yml index 3fc45b9..b09a251 100644 --- a/.github/workflows/install_github.yml +++ b/.github/workflows/install_github.yml @@ -88,9 +88,23 @@ jobs: - name: install_github (with tag) if: github.ref_type == 'tag' shell: bash - run: Rscript -e "library(devtools); install_github('libKriging/rlibkriging@${{ github.ref_name }}'); if (!library('rlibkriging', character.only=TRUE, logical.return=TRUE)) quit(status=1, save='no')" + run: | + for attempt in 1 2 3; do + echo "install_github attempt ${attempt}/3" + Rscript -e "library(devtools); install_github('libKriging/rlibkriging@${{ github.ref_name }}'); if (!library('rlibkriging', character.only=TRUE, logical.return=TRUE)) quit(status=1, save='no')" && exit 0 + echo "install_github attempt ${attempt} failed (e.g. transient pak subprocess error); retrying in 20s..." + sleep 20 + done + echo "install_github failed after 3 attempts"; exit 1 - name: install_github (without tag) if: github.ref_type != 'tag' shell: bash - run: Rscript -e "library(devtools); install_github('libKriging/rlibkriging'); if (!library('rlibkriging', character.only=TRUE, logical.return=TRUE)) quit(status=1, save='no')" + run: | + for attempt in 1 2 3; do + echo "install_github attempt ${attempt}/3" + Rscript -e "library(devtools); install_github('libKriging/rlibkriging'); if (!library('rlibkriging', character.only=TRUE, logical.return=TRUE)) quit(status=1, save='no')" && exit 0 + echo "install_github attempt ${attempt} failed (e.g. transient pak subprocess error); retrying in 20s..." + sleep 20 + done + echo "install_github failed after 3 attempts"; exit 1 diff --git a/.github/workflows/submit-on-cran.yml b/.github/workflows/submit-on-cran.yml index af327d7..8f06260 100644 --- a/.github/workflows/submit-on-cran.yml +++ b/.github/workflows/submit-on-cran.yml @@ -39,6 +39,14 @@ jobs: with: cmake-version: '3.24.x' + # Assemble the R package from the libKriging submodule (generate R/, docs, + # tests; strip non-package files). Without this, `R CMD build .` packages + # an incomplete tree (missing R code/docs/tests -> many spurious WARNINGs). + # Mirrors the pre-compile step in check-standard.yaml. + - name: pre-compile step + shell: bash + run: ./tools/setup.sh + - name: R CMD build shell: bash env: diff --git a/tools/build.sh b/tools/build.sh index 2ee7e04..7651188 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -75,6 +75,37 @@ if [ "$_R_CHECK_CRAN_INCOMING_" != "FALSE" ]; then EXTRA_CMAKE_OPTIONS="-DRCPP_INCLUDE_PATH=${RCPP_INCLUDE_PATH} -DR_INCLUDE_PATH=${R_INCLUDE_PATH} ${EXTRA_CMAKE_OPTIONS}" fi +# macOS: align the static-lib build's deployment target with the one R links +# against. cmake otherwise defaults CMAKE_OSX_DEPLOYMENT_TARGET to the host OS +# (e.g. 26.4), so the static libs are "built for newer macOS than being linked" +# (e.g. 26.0); ld warns and R CMD check reports +# "checking whether package can be installed ... WARNING". +if [ "$(uname -s)" = "Darwin" ]; then + MACOS_TARGET="${MACOSX_DEPLOYMENT_TARGET:-}" + if [ -z "$MACOS_TARGET" ]; then + MACOS_TARGET=$(printf '%s %s' "${CFLAGS:-}" "${CXXFLAGS:-}" | tr ' ' '\n' | sed -n 's/^-mmacosx-version-min=//p' | head -1) + fi + if [ -z "$MACOS_TARGET" ]; then + MACOS_TARGET=$(${R_HOME}/bin/Rscript -e 'cat(Sys.getenv("MACOSX_DEPLOYMENT_TARGET"))' 2>/dev/null || true) + fi + if [ -z "$MACOS_TARGET" ]; then + # Most reliable: ask R's own C compiler what min macOS version it targets. + # The macro value is major*10000 + minor*100 + patch (e.g. 260000 -> 26.0). + _min=$(printf '' | ${CC:-cc} ${CFLAGS:-} -dM -E - 2>/dev/null \ + | awk '/__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__/ {print $3; exit}') + if [ -n "$_min" ]; then + MACOS_TARGET="$(( _min / 10000 )).$(( (_min / 100) % 100 ))" + fi + fi + if [ -n "$MACOS_TARGET" ]; then + export MACOSX_DEPLOYMENT_TARGET="$MACOS_TARGET" + EXTRA_CMAKE_OPTIONS="-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOS_TARGET} ${EXTRA_CMAKE_OPTIONS:-}" + echo "build: macOS deployment target aligned with R -> ${MACOS_TARGET}" + else + echo "build: could not determine R macOS deployment target; leaving cmake default" + fi +fi + BUILD_TEST=false \ MODE=Release \ EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS:-} -DCMAKE_INSTALL_LIBDIR=lib -DBUILD_SHARED_LIBS=${MAKE_SHARED_LIBS} -DSTATIC_LIB=${STATIC_LIB} -DEXTRA_SYSTEM_LIBRARY_PATH=${EXTRA_SYSTEM_LIBRARY_PATH}" \ diff --git a/tools/install_packages.R b/tools/install_packages.R index 48f0d6c..b27deef 100644 --- a/tools/install_packages.R +++ b/tools/install_packages.R @@ -10,15 +10,26 @@ if (Sys.info()["sysname"] == "Darwin") { options(pkgType = "both") # Try binary first, then source } -for (lib in packages) { +# Retry wrapper: package repositories (and pak/pkgdepends subprocesses) can fail +# transiently in CI; retry a few times before giving up. +max_attempts <- as.integer(Sys.getenv("PKG_INSTALL_RETRIES", "3")) +retry_delay <- as.integer(Sys.getenv("PKG_INSTALL_RETRY_DELAY", "15")) - cat(paste0("Installing package: ", lib, "\n")) - - # Try to install the package - install.packages(lib, repos='https://cloud.r-project.org') +install_with_retry <- function(lib) { + for (attempt in seq_len(max_attempts)) { + cat(sprintf("Installing package: %s (attempt %d/%d)\n", lib, attempt, max_attempts)) + try(install.packages(lib, repos = 'https://cloud.r-project.org'), silent = FALSE) + if (requireNamespace(lib, quietly = TRUE)) return(TRUE) + if (attempt < max_attempts) { + cat(sprintf(" ...install of %s failed, retrying in %ds\n", lib, retry_delay)) + Sys.sleep(retry_delay) + } + } + FALSE +} - # Verify installation - if ( ! library(lib, character.only=TRUE, logical.return=TRUE) ) { +for (lib in packages) { + if (!install_with_retry(lib) || !library(lib, character.only=TRUE, logical.return=TRUE)) { cat(paste0("\n#########################\nCannot install ", lib, "\n")) cat(paste0("System info: ", Sys.info()["sysname"], " ", Sys.info()["release"], "\n")) cat(paste0("R version: ", R.version.string, "\n")) diff --git a/tools/setup.sh b/tools/setup.sh index f074e03..6d3a453 100755 --- a/tools/setup.sh +++ b/tools/setup.sh @@ -99,6 +99,9 @@ rm -rf $LIBKRIGING_SRC_PATH/dependencies/pybind11 rm -rf $LIBKRIGING_SRC_PATH/dependencies/optim rm -rf $LIBKRIGING_SRC_PATH/docs rm -rf $LIBKRIGING_SRC_PATH/tests +# libKriging repo root files that are not part of the R package and would +# otherwise trip R CMD check (e.g. a CITATION.cff in a non-standard place). +rm -f $LIBKRIGING_SRC_PATH/CITATION.cff echo "Disabling tests and benchmarks in CMakeLists.txt..." if [ ! -f "$LIBKRIGING_SRC_PATH/CMakeLists.txt" ]; then