-
-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot include Rcpp code by following the vignette #295
Comments
How about this: Instead of all the code above, one could maybe use the Rcpp caching feature? This requires write access to the module directory or a cache (e.g. #264). I still do not know how to unload the linked library when the module is unloaded (
# Keep Rcpp exports in a subenvironment
cpp <- new.env()
# Compile. Has a caching function
Rcpp::sourceCpp(
file.path(box::file(), "cpp","hello.cpp"), # source file
cacheDir = box::file("rcpp-cache"), # permanent cache directory
env = cpp) # default is globalenv(), use a local environment instead
#' Hello World function
#' @export
hello_world <- cpp$hello_world Rcpp decides on its own whether it needs to compile. Comparison of time after first vs. second import:
|
... # === Compile or load C++ code ====================
cpp <- new.env() # R bindings to compiled functions go here
build_dirs <- list() # Directories that contain DLLs
# Compile/load and save the build path for later unloading
build_dirs$hello_world <- Rcpp::sourceCpp(
box::file("cpp","hello.cpp"),
cacheDir = box::file("rcpp-cache"),
env = cpp)$buildDirectory
.on_unload <- function(nm){
# Unlink libraries in all build directories of this module
pat <- utils::glob2rx(paste0("*",.Platform$dynlib.ext))
dlls <- list.files(unlist(build_dirs), full.names = TRUE, pattern = pat)
for(d in dlls) dyn.unload(d)
}
# === Exports ====================================
#' Hello World
#' @export
hello_world <- cpp$hello_world
|
Hi, Rcpp requires a fairly complicated additional setup when invoking the C++ compiler. Unfortunately Rcpp does not (or at least used to not) export the required functions1, so we need to mess around with its internals. I haven’t tried this in a long time so some or all of these internals might have changed. But have a look at the source code of the previous Rcpp usage vignette: https://github.com/klmr/modules/blob/develop/vignettes/rcpp/__install__.r. This won’t work out of the box but it might be adaptable. In particular, pay attention to the following points:
I figured the above out by reverse engineering the internals of 1 Unfortunately the official stance is that Rcpp compilation is only supported for packages, not via any other route (except via the wrapper |
Hi, thanks for taking a look onto this. Did I get your point correctly that Rcpp supports only compilation via packages and In that case the approach I suggest above should be a solution, right? Because the only function of Rcpp it needs is indeed the supported way via
So persistent storage of compiled code seems to be explicitly supported by Rcpp Also, if you figured out the mentioned internals from the source of |
For a single C++ source file without dependencies, |
I see, thanks for explaining. |
Error description
The vignette on compiled code says:
However, I fail in following the steps outlined there. It cannot find the Rcpp libraries. Did I miss something or should the vignette be extended with more steps? #13 mentions a very old demo file that GitHub shows with a warning that it does not belong to this repository, but I do not understand enought to see whether it is still relevant. Also, it seems to use private Rcpp calls, so I wonder whether there is a way using the Rcpp public API instead.
This is my code:
box/cpptest/cpp/hello.cpp
box/cpptest/
__setup__.R
:Call:
R version
‘box’ version
1.1.0
The text was updated successfully, but these errors were encountered: