3

我正在尝试构建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

笔记

请注意,character_only=F参数 inpackage_native_routine_registration_skeleton是必需的,如此处所述;否则命令失败并显示no native symbols were extracted.

软件

Arch Linux 5.3.10、R 3.6.1、Rcpp 1.0.3

4

1 回答 1

4

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

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

于 2019-11-14T09:57:52.710 回答