diff --git a/R/model.R b/R/model.R index 1de220b69..ff5b637e4 100644 --- a/R/model.R +++ b/R/model.R @@ -582,6 +582,7 @@ compile <- function(quiet = TRUE, } stancflags_standalone <- c("--standalone-functions", stancflags_val, stancflags_combined) self$functions$hpp_code <- get_standalone_hpp(temp_stan_file, stancflags_standalone) + self$functions$external <- !is.null(user_header) if (compile_standalone) { expose_functions(self$functions, !quiet) } diff --git a/R/utils.R b/R/utils.R index c32f50ea7..8317e293f 100644 --- a/R/utils.R +++ b/R/utils.R @@ -878,6 +878,10 @@ expose_functions <- function(function_env, global = FALSE, verbose = FALSE) { "WSL CmdStan and will not be compiled", call. = FALSE) } + if (function_env$external && cmdstan_version() < "2.32") { + stop("Exporting standalone functions with external C++ is not available before CmdStan 2.32", + call. = FALSE) + } require_suggested_package("Rcpp") require_suggested_package("RcppEigen") require_suggested_package("decor") diff --git a/tests/testthat/test-model-expose-functions.R b/tests/testthat/test-model-expose-functions.R index dfc2f74c4..3be219e0f 100644 --- a/tests/testthat/test-model-expose-functions.R +++ b/tests/testthat/test-model-expose-functions.R @@ -147,3 +147,36 @@ test_that("Overloaded functions give meaningful errors", { expect_error(funmod$expose_functions(), "Overloaded functions are currently not able to be exposed to R! The following overloaded functions were found: fun1, fun3") }) + +test_that("Exposing external functions errors before v2.32", { + skip_if(os_is_wsl()) + + if (getRversion() < '3.5.0') { + dir <- tempdir() + } else { + dir <- tempdir(check = TRUE) + } + install_cmdstan(dir = dir, cores = 2, quiet = FALSE, + overwrite = TRUE, version = "2.31.0", + wsl = os_is_wsl()) + + tmpfile <- tempfile(fileext = ".hpp") + hpp <- + " + #include + namespace standalone_external_model_namespace { + int rtn_int(int x, std::ostream *pstream__) { return x; } + }" + cat(hpp, file = tmpfile, sep = "\n") + stanfile <- file.path(tempdir(), "standalone_external.stan") + cat("functions { int rtn_int(int x); }\n", file = stanfile) + expect_error({ + cmdstan_model( + stan_file = stanfile, + user_header = tmpfile, + compile_standalone = TRUE + ) + }, + "Exporting standalone functions with external C++ is not available before CmdStan 2.32", + fixed = TRUE) +})