Thanks Ben, that's super helpful.
Unfortunately, however, I'm still struggling to get this to work. Further details below; once again, any suggestions very gratefully received.
I think the issue stems from the fact that the cpp code I'm using is an edited version of stan-generated cpp code for a user-defined function. As a result, its reliant on both the headers required by the rest of the stan-generated code, as well as quite a number of other user-defined functions in my .stan file.
This isn't an issue when using the includes argument in rstan::stan_model() (as described
here) because the relevant code is inserted inside the model namespace after the other user defined functions, so I had thought the easiest way to address this would be to edit the make_cpp.R file to replicate this behaviour.
My edited code that attempts to do this (with edits vs. your original version in red) is:
stan_files <- dir("exec", pattern = "stan$", full.names = TRUE)
# include_files <- dir("src", pattern = "hpp$")
include_files <- dir("src", pattern = "hpp$", full.names = TRUE)
include_code <- paste(unlist(sapply(include_files, readLines)),"\n",sep = "",collapse = "")
cat(readLines(file.path("inst", "chunks", "license.stan")),
"#ifndef MODELS_HPP", "#define MODELS_HPP",
"#define STAN__SERVICES__COMMAND_HPP", "#include <rstan/rstaninc.hpp>",
# if (length(include_files)) paste0('#include "', include_files, '"'),
sapply(stan_files, FUN = function(f) {
cppcode <- rstan::stanc_builder(f, allow_undefined = TRUE,
isystem = file.path("inst", "chunks"))$cppcode
cppcode <- gsub("typedef.*stan_model.*;", "", cppcode, perl = TRUE)
if (length(include_files)) cppcode <- sub("(class[[:space:]]+[A-Za-z_][A-Za-z0-9_]*[[:space:]]*: public prob_grad \\{)",
paste(include_code," \\1"),
cppcode)
return(cppcode)
}), "#endif", file = file.path("src", "include", "models.hpp"),
sep = "\n", append = FALSE)