https://github.com/PecanProject/pecan
Tip revision: 34b103c1c9f6b6b6aaaf1e3698c58adc1a7c3946 authored by Michael Dietze on 04 April 2024, 22:53:26 UTC
Merge pull request #3283 from Sweetdevil144/develop
Merge pull request #3283 from Sweetdevil144/develop
Tip revision: 34b103c
Makefile
NCPUS ?= 1
BASE := logger utils db settings visualization qaqc remote workflow
MODELS := basgra biocro clm45 dalec dvmdostem ed fates gday jules linkages \
ldndc lpjguess maat maespa preles sibcasa sipnet stics template
MODULES := allometry assim.batch assim.sequential benchmark \
data.atmosphere data.hydrology data.land \
data.remote emulator meta.analysis \
photosynthesis priors rtm uncertainty
# Components not currently included in the build
# (Most need more development first)
# models: cable
# modules: data.mining, DART
SHINY := $(dir $(wildcard shiny/*/.))
SHINY := $(SHINY:%/=%)
BASE := $(BASE:%=base/%)
MODELS := $(MODELS:%=models/%)
MODULES := $(MODULES:%=modules/%)
ALL_PKGS := $(BASE) $(MODULES) $(MODELS)
BASE_I := $(BASE:%=.install/%)
MODELS_I := $(MODELS:%=.install/%)
MODULES_I := $(MODULES:%=.install/%)
ALL_PKGS_I := $(BASE_I) $(MODULES_I) $(MODELS_I)
SHINY_I := $(SHINY:shiny/%=.shiny_depends/%)
BASE_C := $(BASE:%=.check/%)
MODELS_C := $(MODELS:%=.check/%)
MODULES_C := $(MODULES:%=.check/%)
ALL_PKGS_C := $(BASE_C) $(MODULES_C) $(MODELS_C)
BASE_T := $(BASE:%=.test/%)
MODELS_T := $(MODELS:%=.test/%)
MODULES_T := $(MODULES:%=.test/%)
ALL_PKGS_T := $(BASE_T) $(MODULES_T) $(MODELS_T)
BASE_D := $(BASE:%=.doc/%)
MODELS_D := $(MODELS:%=.doc/%)
MODULES_D := $(MODULES:%=.doc/%)
ALL_PKGS_D := $(BASE_D) $(MODULES_D) $(MODELS_D)
SETROPTIONS := "options(Ncpus = ${NCPUS})"
EXPECTED_ROXYGEN_VERSION := 7.2.3
INSTALLED_ROXYGEN_VERSION := $(shell Rscript \
-e "if (requireNamespace('roxygen2', quietly = TRUE)) {" \
-e "cat(as.character(packageVersion('roxygen2')))" \
-e "}")
### Macros
# Generates a list of all files and subdirectories at any depth inside its argument
recurse_dir = $(foreach d, $(wildcard $1*), $(call recurse_dir, $d/) $d)
# Filters a list from recurse_dir to remove paths that are directories
# Caveat: Really only removes *direct parents* of other paths *in the list*:
# $(call drop_dirs,a a/b a/b/c) => 'a/b/c',
# but $(call drop_dirs,a a/b d d/e/f) => 'a/b d d/e/f'
# For output from recurse_dir this removes all dirs, but in other cases beware.
drop_parents = $(filter-out $(patsubst %/,%,$(dir $1)), $1)
# Generates a list of regular files at any depth inside its argument
files_in_dir = $(call drop_parents, $(call recurse_dir, $1))
# HACK: NA vs TRUE switch on dependencies argument is an ugly workaround for
# a circular dependency between benchmark and data.land.
# When this is fixed, can go back to simple `dependencies = TRUE`
depends_R_pkg = ./scripts/time.sh "depends ${1}" ./scripts/confirm_deps.R ${1} \
$(if $(findstring modules/benchmark,$(1)),NA,TRUE)
install_R_pkg = ./scripts/time.sh "install ${1}" Rscript \
-e ${SETROPTIONS} \
-e "remotes::install_local('$(strip $(1))', force=TRUE, dependencies=FALSE, upgrade=FALSE)"
check_R_pkg = ./scripts/time.sh "check ${1}" Rscript scripts/check_with_errors.R $(strip $(1))
test_R_pkg = ./scripts/time.sh "test ${1}" Rscript \
-e "devtools::test('$(strip $(1))'," \
-e "stop_on_failure = TRUE," \
-e "stop_on_warning = FALSE)" # TODO: Raise bar to stop_on_warning = TRUE when we can
doc_R_pkg = \
$(if \
$(filter ${EXPECTED_ROXYGEN_VERSION},${INSTALLED_ROXYGEN_VERSION}), \
./scripts/time.sh "document ${1}" \
Rscript -e "devtools::document('"$(strip $(1))"')", \
$(error Roxygen2 version is ${INSTALLED_ROXYGEN_VERSION}, \
but PEcAn package documentation must be built with exactly \
version ${EXPECTED_ROXYGEN_VERSION}))
depends = .doc/$(1) .install/$(1) .check/$(1) .test/$(1)
### Rules
.PHONY: all install check test document shiny \
check_base check_models check_modules
all: install document
check_base: $(BASE_C)
check_models: $(MODELS_C)
# Install base first as Modules has a circular dependency on base,
# and then run a check on modules
check_modules: $(BASE_I) $(MODULES_C)
document: $(ALL_PKGS_D) .doc/base/all
install: $(ALL_PKGS_I) .install/base/all
check: $(ALL_PKGS_C) .check/base/all
test: $(ALL_PKGS_T) .test/base/all
shiny: $(SHINY_I)
# Render the PEcAn bookdown documentation
book:
cd ./book_source && make build
# Make the timestamp directories if they don't exist yet
.doc .install .check .test .shiny_depends $(call depends,base) $(call depends,models) $(call depends,modules):
mkdir -p $@
### Dependencies
# models import Roxygen docs from *installed* version of template,
# so changes in template mean the models need to be redocumented
$(subst .doc/models/template,,$(MODELS_D)): .install/models/template
### Order-only dependencies
# (i.e. prerequisites must exist before building target, but
# target need not be rebuilt when a prerequisite changes)
.doc/base/all: | $(ALL_PKGS_D)
.install/base/all: | $(ALL_PKGS_I)
.check/base/all: | $(ALL_PKGS_C)
.test/base/all: | $(ALL_PKGS_T)
include Makefile.depends
clean:
rm -rf .install .check .test .doc
find modules/rtm/src \( -name \*.mod -o -name \*.o -o -name \*.so \) -delete
find models/basgra/src \( -name \*.mod -o -name \*.o -o -name \*.so \) -delete
.install/devtools: | .install
+ ./scripts/time.sh "devtools ${1}" Rscript -e ${SETROPTIONS} -e "if(!requireNamespace('devtools', quietly = TRUE)) install.packages('devtools')"
echo `date` > $@
.install/roxygen2: | .install .install/devtools
+ ./scripts/time.sh "roxygen2 ${1}" Rscript -e ${SETROPTIONS} \
-e "if (!requireNamespace('roxygen2', quietly = TRUE)" \
-e " || packageVersion('roxygen2') != '7.2.3') {" \
-e " cran <- c(getOption('repos'), 'cloud.r-project.org')" \
-e " remotes::install_version('roxygen2', '7.2.3', repos = cran, upgrade = FALSE)" \
-e "}"
$(eval INSTALLED_ROXYGEN_VERSION := 7.2.3)
echo `date` > $@
.install/testthat: | .install
+ ./scripts/time.sh "testthat ${1}" Rscript -e ${SETROPTIONS} -e "if(!requireNamespace('testthat', quietly = TRUE)) install.packages('testthat')"
echo `date` > $@
.install/mockery: | .install
+ ./scripts/time.sh "mockery ${1}" Rscript -e ${SETROPTIONS} -e "if(!requireNamespace('mockery', quietly = TRUE)) install.packages('mockery')"
echo `date` > $@
$(ALL_PKGS_I) $(ALL_PKGS_C) $(ALL_PKGS_T) $(ALL_PKGS_D): | .install/devtools .install/roxygen2 .install/testthat
.SECONDEXPANSION:
.doc/%: $$(call files_in_dir, %) | $$(@D)
+ $(call depends_R_pkg, $(subst .doc/,,$@))
$(call doc_R_pkg, $(subst .doc/,,$@))
echo `date` > $@
.install/%: $$(call files_in_dir, %) .doc/% | $$(@D)
+ $(call install_R_pkg, $(subst .install/,,$@))
echo `date` > $@
.check/%: $$(call files_in_dir, %) | $$(@D)
+ $(call check_R_pkg, $(subst .check/,,$@))
echo `date` > $@
.test/%: $$(call files_in_dir, %) | $$(@D)
$(call test_R_pkg, $(subst .test/,,$@))
echo `date` > $@
# Install dependencies declared by Shiny apps
.shiny_depends/%: $$(call files_in_dir, %) | $$(@D)
Rscript scripts/install_shiny_deps.R $(subst .shiny_depends/,shiny/,$@)
echo `date` > $@