-
-
Notifications
You must be signed in to change notification settings - Fork 218
Description
Here is a minimal example. First consider a simple C++ class defined in foo.h
:
#ifndef foo_h
#define foo_h 1
// class to set/get a scalar double
class foo {
private:
double x;
public:
double get_x() {return x;}
void set_x(double _x) {x = _x; return;}
foo(double _x) {set_x(_x);}
};
#endif
Now let's create an R package exporting the class as an Rcpp module:
options(useFancyQuotes = FALSE) # Rcpp::exposeClass uses dQuote
pkg_path <- getwd() # where to create package
pkg_name <- "ModuleLoadTest" # name of package
pkg_dir <- file.path(pkg_path, pkg_name) # package root directory
# create package set up to export Rcpp modules
Rcpp::Rcpp.package.skeleton(name = pkg_name,
path = pkg_path,
force = TRUE,
example_code = FALSE, module = TRUE)
# remove module sample code
file.remove(list.files(file.path(pkg_dir, c("src", "R")),
full.names = TRUE))
# add foo header file to package (assuming foo.h is in current directory)
file.copy(from = "foo.h", to = file.path(pkg_dir, "src", "foo.h"))
Finally to wrap the class into a module. First with the R and C++ classes both named foo
, which works as expected:
Rcpp::exposeClass(class = "foo",
constructors = list("double"),
fields = character(),
methods = c("get_x", "set_x"),
header = '#include "foo.h"',
CppClass = "foo",
file = file.path(pkg_dir, "src", "fooModule.cpp"),
Rfile = file.path(pkg_dir, "R", "fooClass.R"))
devtools::install(pkg_dir) # install package
# simple unit test for getter/setter
bar <- ModuleLoadTest::foo(0) # create object
replicate(n = 10, {
x <- rnorm(1)
bar$set_x(x)
bar$get_x() - x
}) # should return an array of zeros
However, when I change class = "foo"
to class = "fooR"
in the above, and rerun devtools:install
(also checked with R CMD install
and with CRAN and GitHub versions of Rcpp), I get the following output/error message:
Installing ModuleLoadTest
'/Library/Frameworks/R.framework/Resources/bin/R' --no-site-file --no-environ \
--no-save --no-restore --quiet CMD INSTALL \
'/Users/mlysy/Documents/R/test/class/ModuleLoadTest' \
--library='/Users/mlysy/Documents/data/R/library' --install-tests
* installing *source* package ‘ModuleLoadTest’ ...
** libs
/usr/local/opt/llvm/bin/clang++ -arch x86_64 -ftemplate-depth-256 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I"/Users/mlysy/Documents/data/R/library/Rcpp/include" -I/usr/local/include -fPIC -I/usr/local/opt/llvm/include -O3 -ffast-math -mtune=native -march=native -Wno-unused-variable -Wno-unused-function -Wno-pragmas -c fooModule.cpp -o fooModule.o
/usr/local/opt/llvm/bin/clang++ -arch x86_64 -ftemplate-depth-256 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/opt/llvm/lib -o ModuleLoadTest.so fooModule.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
installing to /Users/mlysy/Documents/data/R/library/ModuleLoadTest/libs
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error: package or namespace load failed for ‘ModuleLoadTest’ in .doLoadActions(where, attach):
error in load action .__A__.1 for package ModuleLoadTest: Rcpp::loadRcppClass(Class = "fooR", CppClass = "foo", where = NS): No object "foo" in module "class_fooR"
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/Users/mlysy/Documents/data/R/library/ModuleLoadTest’
* restoring previous ‘/Users/mlysy/Documents/data/R/library/ModuleLoadTest’
Error: Command failed (1)
It seems that the problem is entirely with R/fooClass.R
. That is, if I set Rfile = FALSE
in the above and construct the object with bar <- new("fooR", x)
, install and test both work fine.
Moreover, a small adjustment to R/fooClass.R
seems to overcome the issue (at least, for this particular example). Here is the original content of fooClass.R
:
fooR <- setRcppClass("fooR", "foo")
If I switch the second argument from foo
to fooR
, then devtools::install
runs without errors and so does the unit test above (via original bar <- ModuleLoadTest::fooR(0)
).
Here is the R sessionInfo()
after the first call to devtools::install
:
R version 3.5.0 (2018-04-23)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.3
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
locale:
[1] en_CA.UTF-8/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.5.0 tools_3.5.0 withr_2.1.2 memoise_1.1.0
[5] Rcpp_0.12.17 pkgKitten_0.1.4 git2r_0.21.0 digest_0.6.15
[9] devtools_1.13.5