无法构建 RcppArmadillo.package.skeleton 测试包:`R_init_<name>' 的多重定义

Unable to build the RcppArmadillo.package.skeleton test package: Multiple definition of `R_init_<name>'

我正在尝试构建 RcppArmadillo.package.skeleton 测试包。像往常一样,我在 R:

> library("Rcpp")
> library("RcppArmadillo")
> RcppArmadillo.package.skeleton("test")
> compileAttributes()
> library(tools)
> package_native_routine_registration_skeleton(".", "src/init.c", character_only=F)

到目前为止,这看起来不错:

$ cat test/src/init.c 
#include <R.h>
#include <Rinternals.h>
#include <stdlib.h> // for NULL
#include <R_ext/Rdynload.h>

/* FIXME: 
   Check these declarations against the C/Fortran source code.
*/

/* .Call calls */
extern SEXP _test_rcpparma_bothproducts(SEXP);
extern SEXP _test_rcpparma_hello_world();
extern SEXP _test_rcpparma_innerproduct(SEXP);
extern SEXP _test_rcpparma_outerproduct(SEXP);

static const R_CallMethodDef CallEntries[] = {
    {"_test_rcpparma_bothproducts", (DL_FUNC) &_test_rcpparma_bothproducts, 1},
    {"_test_rcpparma_hello_world",  (DL_FUNC) &_test_rcpparma_hello_world,  0},
    {"_test_rcpparma_innerproduct", (DL_FUNC) &_test_rcpparma_innerproduct, 1},
    {"_test_rcpparma_outerproduct", (DL_FUNC) &_test_rcpparma_outerproduct, 1},
    {NULL, NULL, 0}
};

void R_init_test(DllInfo *dll)
{
    R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
    R_useDynamicSymbols(dll, FALSE);
}

但是编译不通过:

$ R CMD build test
* checking for file ‘test/DESCRIPTION’ ... OK
* preparing ‘test’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* installing the package to process help pages
      -----------------------------------
* installing *source* package ‘test’ ...
** using staged installation
** libs
g++ -std=gnu++14 -I"/usr/include/R/" -DNDEBUG  -I"/home/<user>/R/x86_64-pc-linux-gnu-library/3.6/Rcpp/include" -I"/usr/lib/R/library/RcppArmadillo/include" -D_FORTIFY_SOURCE=2 -fopenmp  -fpic  -march=x86-64 -mtune=generic -O2 -pipe -fno-plt  -c RcppExports.cpp -o RcppExports.o
gcc -I"/usr/include/R/" -DNDEBUG  -I"/home/<user>/R/x86_64-pc-linux-gnu-library/3.6/Rcpp/include" -I"/usr/lib/R/library/RcppArmadillo/include" -D_FORTIFY_SOURCE=2  -fpic  -march=x86-64 -mtune=generic -O2 -pipe -fno-plt  -c init.c -o init.o
g++ -std=gnu++14 -I"/usr/include/R/" -DNDEBUG  -I"/home/<user>/R/x86_64-pc-linux-gnu-library/3.6/Rcpp/include" -I"/usr/lib/R/library/RcppArmadillo/include" -D_FORTIFY_SOURCE=2 -fopenmp  -fpic  -march=x86-64 -mtune=generic -O2 -pipe -fno-plt  -c rcpparma_hello_world.cpp -o rcpparma_hello_world.o
g++ -std=gnu++14 -shared -L/usr/lib64/R/lib -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -o test.so RcppExports.o init.o rcpparma_hello_world.o -fopenmp -llapack -lblas -lgfortran -lm -lquadmath -L/usr/lib64/R/lib -lR
/usr/bin/ld: init.o: in function `R_init_test':
init.c:(.text+0x0): multiple definition of `R_init_test'; RcppExports.o:RcppExports.cpp:(.text+0xd0): first defined here
collect2: error: ld returned 1 exit status
make: *** [/usr/share/R//make/shlib.mk:6: test.so] Error 1
ERROR: compilation failed for package ‘test’
* removing ‘/tmp/RtmpW9PqbR/Rinst8c72353a56e/test’
      -----------------------------------
ERROR: package installation failed

这里的严重错误是

init.c:(.text+0x0): multiple definition of `R_init_test'; RcppExports.o:RcppExports.cpp:(.text+0xd0): first defined here

备注

注意 package_native_routine_registration_skeleton 中的 character_only=F 参数是必需的 as described here;否则命令失败并显示 no native symbols were extracted.

软件

Arch Linux 5.3.10,R 3.6.1,Rcpp 1.0.3

在这种情况下您不需要使用 utils::package_native_routine_registration_skeleton(),因为 Rcpp::compileAttributes() 将必要的代码添加到 src/RcppExport.cpp。此函数由 RcppArmadillo::RcppArmadillo.package.skeleton().

调用

或者,您可以创建一个 src/init.c 文件并再次调用 Rcpp::compileAttributes()。在这种情况下,src/RcppExport.cpp 中将没有注册码。通常只有当您要注册一些不使用 Rcpp 属性的其他函数时才需要这样做。