美文网首页R
「Debug R」R包用到Rcpp时,文件名一定要是cpp

「Debug R」R包用到Rcpp时,文件名一定要是cpp

作者: xuzhougeng | 来源:发表于2019-08-19 13:05 被阅读0次

我在一个R包用到了Rcpp,已经写的两个文件都没有啥问题。但是第三个文件在编译R包的时候就出现了报错,。

在Windows上的报错提示为

c:/Rtools/mingw_64/bin/g++  -std=gnu++11 -I"D:/Program Files/R/R-3.6.0/include" -DNDEBUG  -I"C:/Users/DELL/Documents/R/win-library/3.6/Rcpp/include"     -fopenmp    -O2 -Wall  -mtune=generic -c RcppExports.cpp -o RcppExports.o
c:/Rtools/mingw_64/bin/g++ -shared -s -static-libgcc -o scatacr.dll tmp.def RcppExports.o asMatrix.o tabulate2d.o -fopenmp -LD:/Program Files/R/R-3.6.0/bin/x64 -lRlapack -LD:/Program Files/R/R-3.6.0/bin/x64 -lRblas -lgfortran -lm -lquadmath -LD:/Program Files/R/R-3.6.0/bin/x64 -lR
RcppExports.o:RcppExports.cpp:(.text+0xb11): undefined reference to `rowCorCpp(Rcpp::Vector<13, Rcpp::PreserveStorage>, Rcpp::Vector<13, Rcpp::PreserveStorage>, Rcpp::Matrix<14, Rcpp::PreserveStorage>, Rcpp::Matrix<14, Rcpp::PreserveStorage>)'
collect2.exe: error: ld returned 1 exit status
no DLL was created
ERROR: compilation failed for package 'scatacr'
* removing 'C:/Users/DELL/Documents/R/win-library/3.6/scatacr'

Exited with status 1.

在Linux上的报错提示为

...
g++ -std=gnu++11 -I"/opt/sysoft/R-3.5.1/lib64/R/include" -DNDEBUG  -I"/home/xzg/R/x86_64-pc-linux-gnu-library/3.5/Rcpp/include" -I/usr/local/include  -fopenmp  -fpic  -g -O2 -c RcppExports.cpp -o RcppExports.o
g++ -std=gnu++11 -I"/opt/sysoft/R-3.5.1/lib64/R/include" -DNDEBUG  -I"/home/xzg/R/x86_64-pc-linux-gnu-library/3.5/Rcpp/include" -I/usr/local/include  -fopenmp  -fpic  -g -O2 -c asMatrix.cpp -o asMatrix.o
g++ -std=gnu++11 -I"/opt/sysoft/R-3.5.1/lib64/R/include" -DNDEBUG  -I"/home/xzg/R/x86_64-pc-linux-gnu-library/3.5/Rcpp/include" -I/usr/local/include  -fopenmp  -fpic  -g -O2 -c tabulate2d.cpp -o tabulate2d.o
g++ -std=gnu++11 -shared -L/opt/sysoft/R-3.5.1/lib64/R/lib -L/usr/local/lib64 -o scatacr.so RcppExports.o asMatrix.o tabulate2d.o -fopenmp -L/opt/sysoft/R-3.5.1/lib64/R/lib -lRlapack -L/opt/sysoft/R-3.5.1/lib64/R/lib -lRblas -lgfortran -lm -lquadmath -L/opt/sysoft/R-3.5.1/lib64/R/lib -lR
...
Error: package or namespace load failed for 'scatacr' in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/home/xzg/R/x86_64-pc-linux-gnu-library/3.5/scatacr/libs/scatacr.so':
  /home/xzg/R/x86_64-pc-linux-gnu-library/3.5/scatacr/libs/scatacr.so: undefined symbol: _Z9rowCorCppN4Rcpp6VectorILi13ENS_15PreserveStorageEEES2_NS_6MatrixILi14ES1_EES4_
Error: loading failed
Execution halted

问题排查:

通过对编译过程进行观察,发现一个C++函数rowCorCpp并没有被编译。于是我单独对这个文件做了编译

g++ -std=gnu++11 -I"/opt/sysoft/R-3.5.1/lib64/R/include" -DNDEBUG  -I"/home/xzg/R/x86_64-pc-linux-gnu-library/3.5/Rcpp/include" -I/usr/local/include  -fopenmp  -fpic  -g -O2 -c rowCorCpp.Cpp -o rowCorCpp.o

然后就遇到了下面这个问题

linker input file unused because linking notdone

通过一波搜索发现,

但是gcc默认会根据源文件的后缀去判断应该调用处理程序的那些。例如源文件的后缀是.c,则gcc -E使用的是cpp,gcc-c则使用cpp、ccl、as。如果源文件的后缀是.o,则gcc -E 是无法进行的,会报错:linker input file unused because linking notdone。这是gcc发现这个应该进行链接,但是选项指示不使用linker程序,因而报这种错误信息。如果源文件是二进制的文件,但是保存的源文件后缀却是.c,则gcc会当作这是.c文件,如果采用gcc不带参数,则gcc会很多错,因为它把这个文件当作源代码处理的。

简而言之,我保存成Cpp了, 而不是cpp, 结果

参考资料: https://blog.csdn.net/zahuopuboss/article/details/39368817

相关文章

网友评论

    本文标题:「Debug R」R包用到Rcpp时,文件名一定要是cpp

    本文链接:https://www.haomeiwen.com/subject/nkessctx.html