Skip to content

Commit

Permalink
Merge pull request #1054 from stan-dev/stock-rtools-default
Browse files Browse the repository at this point in the history
Use stock Rtools toolchain by default for RTools44+
  • Loading branch information
andrjohns authored Jan 7, 2025
2 parents 369b93a + 3f09369 commit 79d3779
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 32 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ jobs:
echo "CMDSTAN_PATH=${HOME}/.cmdstan" >> $GITHUB_ENV
shell: bash

- name: Use stock RTools for Windows R-Devel
if: ${{ matrix.config.os == 'windows-latest' && matrix.config.r == 'devel' }}
run: |
echo "CMDSTANR_USE_RTOOLS=TRUE" >> $GITHUB_ENV
shell: bash

- uses: n1hility/cancel-previous-runs@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ URL: https://mc-stan.org/cmdstanr/, https://discourse.mc-stan.org
BugReports: https://github.com/stan-dev/cmdstanr/issues
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
Roxygen: list(markdown = TRUE, r6 = FALSE)
SystemRequirements: CmdStan (https://mc-stan.org/users/interfaces/cmdstan)
Depends:
Expand Down
35 changes: 29 additions & 6 deletions R/install.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,19 @@
#'
#' The `check_cmdstan_toolchain()` function attempts to check for the required
#' C++ toolchain. It is called internally by `install_cmdstan()` but can also
#' be called directly by the user.
#' be called directly by the user. On Windows only, calling the function with
#' the `fix = TRUE` argument will attempt to install the necessary toolchain
#' components if they are not found. For Windows users with RTools44 no additional
#' toolchain configuration is required. For users with older versions of RTools,
#' the function will install `mingw32-make` and `g++` from MSYS using the
#' RTools-provided `pacman` package manager. This can also be manually requested
#' by setting the environment variable `CMDSTANR_USE_MSYS_TOOLCHAIN` to 'true'
#'
#' NOTE: When installing CmdStan on Windows with RTools44 and CmdStan versions
#' prior to 2.35.0, the above additional toolchain configuration
#' is still required. To enable this configuration, set the environment variable
#' `CMDSTANR_USE_MSYS_TOOLCHAIN` to 'true' and call
#' `check_cmdstan_toolchain(fix = TRUE)`.
#'
#' @export
#' @param dir (string) The path to the directory in which to install CmdStan.
Expand Down Expand Up @@ -103,6 +114,15 @@ install_cmdstan <- function(dir = NULL,
} else {
.cmdstanr$WSL <- FALSE
}
if (os_is_windows() && !os_is_wsl() && isTRUE(version < "2.35.0")) {
# RTools44 can be used unmodified with CmdStan 2.35+
# For new installs of older versions, users need to install mingw32-make and MSYS gcc
if (Sys.getenv("CMDSTANR_USE_MSYS_TOOLCHAIN") == "" && rtools4x_version() == "44") {
stop("CmdStan versions prior to 2.35.0 require additional toolchain configuration on Windows.\n",
"Please set the environment variable CMDSTANR_USE_MSYS_TOOLCHAIN to 'true' and \n",
"call `check_cmdstan_toolchain(fix = TRUE)` before installing CmdStan.", call. = FALSE)
}
}
if (check_toolchain) {
check_cmdstan_toolchain(fix = FALSE, quiet = quiet)
}
Expand Down Expand Up @@ -643,7 +663,8 @@ check_rtools4x_windows_toolchain <- function(fix = FALSE, quiet = FALSE) {
call. = FALSE
)
}
if (Sys.getenv("CMDSTANR_USE_RTOOLS") != "") {
# No additional utilities/toolchains are needed with RTools44
if (rtools4x_version() >= "44" && Sys.getenv("CMDSTANR_USE_MSYS_TOOLCHAIN") == "") {
return(invisible(NULL))
}
if (!is_toolchain_installed(app = "g++", path = toolchain_path) ||
Expand Down Expand Up @@ -855,10 +876,12 @@ toolchain_PATH_env_var <- function() {
}

rtools4x_toolchain_path <- function() {
toolchain <- ifelse(is_ucrt_toolchain(), "ucrt64", "mingw64")
if (Sys.getenv("CMDSTANR_USE_RTOOLS") != "") {
if (arch_is_aarch64()) {
toolchain <- "aarch64-w64-mingw32.static.posix"
if (arch_is_aarch64()) {
toolchain <- "aarch64-w64-mingw32.static.posix"
} else {
if (rtools4x_version() < "44" || Sys.getenv("CMDSTANR_USE_MSYS_TOOLCHAIN") != "" ||
isTRUE(cmdstan_version(error_on_NA=FALSE) < "2.35.0")) {
toolchain <- ifelse(is_ucrt_toolchain(), "ucrt64", "mingw64")
} else {
toolchain <- "x86_64-w64-mingw32.static.posix"
}
Expand Down
3 changes: 2 additions & 1 deletion R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ arch_is_aarch64 <- function() {
make_cmd <- function() {
if (Sys.getenv("MAKE") != "") {
Sys.getenv("MAKE")
} else if (os_is_windows() && !os_is_wsl() && (Sys.getenv("CMDSTANR_USE_RTOOLS") == "")) {
} else if (os_is_windows() && !os_is_wsl() &&
(rtools4x_version() < "44" || Sys.getenv("CMDSTANR_USE_MSYS_TOOLCHAIN") != "" || isTRUE(cmdstan_version(error_on_NA=FALSE) < "2.35.0"))) {
"mingw32-make.exe"
} else {
"make"
Expand Down
2 changes: 1 addition & 1 deletion man/fit-method-save_object.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion man/install_cmdstan.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 14 additions & 16 deletions tests/testthat/test-install.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
context("install")
# Current tests need CmdStan 2.35 for stock rtools, but is not yet released
skip_if(Sys.getenv("CMDSTANR_USE_RTOOLS") != "")

cmdstan_test_tarball_url <- Sys.getenv("CMDSTAN_TEST_TARBALL_URL")
if (!nzchar(cmdstan_test_tarball_url)) {
Expand Down Expand Up @@ -28,13 +26,13 @@ test_that("install_cmdstan() successfully installs cmdstan", {

test_that("install_cmdstan() errors if installation already exists", {
install_dir <- cmdstan_default_install_path()
dir <- file.path(install_dir, "cmdstan-2.23.0")
dir <- file.path(install_dir, "cmdstan-2.35.0")
if (!dir.exists(dir)) {
dir.create(dir, recursive = TRUE)
}
expect_warning(
install_cmdstan(dir = install_dir, overwrite = FALSE,
version = "2.23.0", wsl = FALSE),
version = "2.35.0", wsl = FALSE),
"An installation already exists",
fixed = TRUE
)
Expand Down Expand Up @@ -76,13 +74,13 @@ test_that("install_cmdstan() errors if it times out", {

test_that("install_cmdstan() errors if invalid version or URL", {
expect_error(
install_cmdstan(version = "2.23.2", wsl = os_is_wsl()),
"Download of CmdStan failed with error: cannot open URL 'https://github.com/stan-dev/cmdstan/releases/download/v2.23.2/cmdstan-2.23.2.tar.gz'\nPlease check if the supplied version number is valid."
install_cmdstan(version = "2.35.5", wsl = os_is_wsl()),
"Download of CmdStan failed with error: cannot open URL 'https://github.com/stan-dev/cmdstan/releases/download/v2.35.5/cmdstan-2.35.5.tar.gz'\nPlease check if the supplied version number is valid."
)
expect_error(
install_cmdstan(release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.23.2/cmdstan-2.23.2.tar.gz",
install_cmdstan(release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.35.5/cmdstan-2.35.5.tar.gz",
wsl = os_is_wsl()),
"Download of CmdStan failed with error: cannot open URL 'https://github.com/stan-dev/cmdstan/releases/download/v2.23.2/cmdstan-2.23.2.tar.gz'\nPlease check if the supplied release URL is valid."
"Download of CmdStan failed with error: cannot open URL 'https://github.com/stan-dev/cmdstan/releases/download/v2.35.5/cmdstan-2.35.5.tar.gz'\nPlease check if the supplied release URL is valid."
)
expect_error(
install_cmdstan(release_url = "https://github.com/stan-dev/cmdstan/releases/tag/v2.24.0", wsl = os_is_wsl()),
Expand All @@ -100,9 +98,9 @@ test_that("install_cmdstan() works with version and release_url", {
expect_message(
expect_output(
install_cmdstan(dir = dir, overwrite = TRUE, cores = 4,
release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.33.0/cmdstan-2.33.0.tar.gz",
release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.35.0/cmdstan-2.35.0.tar.gz",
wsl = os_is_wsl()),
"Compiling, linking C++ code",
"Compiling C++ code",
fixed = TRUE
),
"Finished installing CmdStan",
Expand All @@ -112,11 +110,11 @@ test_that("install_cmdstan() works with version and release_url", {
expect_message(
expect_output(
install_cmdstan(dir = dir, overwrite = TRUE, cores = 4,
version = "2.33.0",
version = "2.35.0",
# the URL is intentionally invalid to test that the version has higher priority
release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.27.3/cmdstan-2.27.3.tar.gz",
wsl = os_is_wsl()),
"Compiling, linking C++ code",
"Compiling C++ code",
fixed = TRUE
),
"Finished installing CmdStan",
Expand All @@ -125,7 +123,7 @@ test_that("install_cmdstan() works with version and release_url", {
"version and release_url shouldn't both be specified",
fixed = TRUE
)
expect_true(dir.exists(file.path(dir, "cmdstan-2.33.0")))
expect_true(dir.exists(file.path(dir, "cmdstan-2.35.0")))
set_cmdstan_path(cmdstan_default_path())
})

Expand Down Expand Up @@ -256,18 +254,18 @@ test_that("Install from release file works", {
dir <- tempdir(check = TRUE)
}

destfile = file.path(dir, "cmdstan-2.33.1.tar.gz")
destfile = file.path(dir, "cmdstan-2.35.0.tar.gz")

download_with_retries(
"https://github.com/stan-dev/cmdstan/releases/download/v2.33.1/cmdstan-2.33.1.tar.gz",
"https://github.com/stan-dev/cmdstan/releases/download/v2.35.0/cmdstan-2.35.0.tar.gz",
destfile)

expect_message(
expect_output(
install_cmdstan(dir = dir, cores = 2, quiet = FALSE, overwrite = TRUE,
release_file = destfile,
wsl = os_is_wsl()),
"Compiling, linking C++ code",
"Compiling C++ code",
fixed = TRUE
),
"CmdStan path set",
Expand Down

0 comments on commit 79d3779

Please sign in to comment.