【发布时间】:2018-06-04 18:23:06
【问题描述】:
我有一个将 Rcpp 用于某些内部功能的 R 包。这些函数不会导出供用户直接访问(请参阅rcpptest 存储库中的最小可重现示例)。
我现在尝试将 Stan 代码添加到 src/ 目录,以便在安装包时进行编译(rcppstan 存储库中的可重现示例)。但是,当我修改包以使用 Stan 时,我在 R CMD CHECK 中收到以下错误:
#> ❯ checking R code for possible problems ... NOTE
#> meanC: no visible binding for global variable ‘_rcppstan_meanC’
#> Undefined global functions or variables:
#> _rcppstan_meanC
事实上,当我尝试调用使用 meanC 函数的 R 函数时,我收到一条错误消息 Error in meanC(x) : object '_rcppstan_meanC' not found。
据我所知,当我修改包以使用 rstan 时发生了什么变化,因此可能是原因。
-
仅使用Rcpp时,
src/RcppExports.cpp中如下:static const R_CallMethodDef CallEntries[] = { {"_rcpptest_timesTwo", (DL_FUNC) &_rcpptest_timesTwo, 1}, {NULL, NULL, 0} }; RcppExport void R_init_rcpptest(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } -
当 Stan 被合并时,
src/RcppExports.cpp文件中不再生成该代码。相反,这似乎是由 rstantools 包创建的src/init.cpp文件处理的。该文件中的相关块在这里:static const R_CallMethodDef CallEntries[] = { {NULL, NULL, 0} }; void attribute_visible R_init_rcppstan(DllInfo *dll) { // next line is necessary to avoid a NOTE from R CMD check R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, TRUE); // necessary for .onLoad() to work }
为什么src/init.cpp 中的代码使 Rcpp 函数未定义?相反,有没有办法编辑 src/init.cpp 以便 Stan 模型能够正确编译和访问,同时仍然允许定义 Rcpp 函数?
【问题讨论】:
-
当我们编写
rstantools::rstan_package_skeleton时,我们从未考虑过除了Stan 程序的C++ 表示之外,还有其他编译代码的情况。如果你只是删除src/init.cpp会发生什么?它在基于 Stan 的包中没有多大用处,但它避免了来自R CMD check的关于存在 C++ 代码但注册的警告。您可能需要将src/RcppExports.cpp中的R_useDynamicSymbols(dll, FALSE);更改为R_useDynamicSymbols(dll, TRUE);。 -
当我删除
src/init.cpp时,包无法构建:make: *** No rule to make target 'init.o', needed by 'rcppstan.so'. Stop. rm stan_files/uni_irt.cc ERROR: compilation failed for package ‘rcppstan’似乎init.o被src/Makevars引用,由rstantools::rstan_package_skeleton生成 -
此外,请参阅显示为对 rstan 具有反向
LinkTo依赖的 10 多个其他软件包:cran.r-project.org/web/packages/rstan -
@coatless 有两个链接。第一个用于仅包含 Rcpp (rcpptest) 的包,第二个用于包含 Rcpp 和 rstan (rcppstan) 的包。两者都包含在内以说明在添加 rstan 时访问 Rcpp 函数时出现的问题。此外,问题不在于 rstan(我已经编写了其他依赖于 rstan 的软件包),而是同时具有 rstan 和 Rcpp。如果我能进一步澄清,请告诉我。
-
@JakeThompson 尝试将
src/Makevars{.win}中的行从OBJECTS = $(SOURCES:.stan=.o) init.o更改为OBJECTS = $(SOURCES:.stan=.o)。