rstantools
rstantools copied to clipboard
rstan_package_skeleton: multiple translation units
I am using rstantools::rstan_package_skeleton to implement a dozen stan models in an R package. While tools/make_cpp.R
creates multiple .cc
files in src
, the cleanup
file has the lines
cat src/*.cc > src/Modules.cpp
rm src/*.cc
effectively leading to one translation unit. This means when I modify any of the stan models they all need to be recompiled, which makes development burdensome.
Unfortunately, removing the lines above (i.e., multiple translation units) leads to "duplicate symbols" linker errors. To my understanding, this is because stan
declares + defines functions inside namespaces inside header files only, for which header guarding + inline
keyword does not seem to prevent symbol duplication.
I'd like to fix this issue and can think of two ways of going about it:
- Modify the
stan
library so as to somehow nest thestan
namespace within each model. I'm reluctant to do this, and have tried many many ways around this, including:- creating separate
src/include/models.hpp
files for each model. Didn't work, asstan/model/model.hpp
goes into each.o
which all get linked into one.so
. - something like
I.e., I'm trying to nest thenamespace myModel { #include "src/include/models.hpp" // ... }
stan
namespace into the namespace for each model. Unfortunately this doesn't work either because within thestan
namespace there areusing
declarations which no longer refer to the right things when you nest them.
- creating separate
- A different approach is to build the
stan
models when the package is installed, and then save them as.RData
files in thedata
folder. Then later when the installed package gets loaded, the models aren't rebuilt.
Perhaps I should point out that I implemented approach 2 long before rstantools
was released. It worked perfectly until I had to install on a multi-architecture Windows platform. There the models only got built on one platform, and of course R crashed when I tried to load them from the other.
I thought about this some more and I believe the problem can be resolved by building architecture-dependent .RData
files at install time, and sealing the objects into the package namespace at load time. However, I don't want to veer off from the stan
-supported way of doing things, so I'm asking for advice/feedback on how to proceed.