我在一个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
网友评论