我正在尝试使用RcppArmadillo创建一个共享对象,并且无法让编译器找到所有标头。这个问题与我的代码中RcppArmadillo的实际使用无关。
我在Linux / Ubuntu上运行。
这是一个非常简单的cpp文件,说明了这一点。这是真实文件的精简版本。你会发现我甚至已经剥夺了对RcppArmadillo的任何使用(虽然它确实使用了Rcpp)。由于我包括RcppArmadillo.h,我知道我应该注意包括Rcpp.h。然而,我最终得到了同样的错误。
//simpleexample.cpp
#include <RcppArmadillo.h>
#include <cstdlib>
#include <iostream>
using namespace Rcpp;
using namespace RcppArmadillo;
using namespace std;
RcppExport SEXP test_nnls(SEXP Ain, SEXP bin){
int m,n;
NumericMatrix Amat(Ain);
NumericMatrix bvec(bin);
m = Amat.nrow(); n = Amat.ncol();
NumericMatrix xvec(n,1);
return(xvec);
}
相关的头文件位于此目录中。
arwen$ pwd
/usr/local/linux/lib/R/Current/x86_64/site-library/RcppArmadillo/include
arwen$ ls -al
total 89
drwxr-xr-x 5 scf scfstaff 15 Feb 22 01:44 ./
drwxr-xr-x 13 scf scfstaff 18 Feb 22 01:44 ../
-rw-r--r-- 1 scf scfstaff 19882 Feb 22 01:44 armadillo
drwxr-xr-x 2 scf scfstaff 390 Feb 22 01:44 armadillo_bits/
drwxr-xr-x 2 scf scfstaff 8 Feb 22 01:44 RcppArmadillo/
-rw-r--r-- 1 scf scfstaff 6963 Feb 22 01:44 RcppArmadilloAs.h
-rw-r--r-- 1 scf scfstaff 2763 Feb 22 01:44 RcppArmadilloConfig.h
drwxr-xr-x 2 scf scfstaff 3 Feb 22 01:44 RcppArmadilloExtensions/
-rw-r--r-- 1 scf scfstaff 4529 Feb 22 01:44 RcppArmadilloForward.h
-rw-r--r-- 1 scf scfstaff 2169 Feb 22 01:44 RcppArmadillo.h
-rw-r--r-- 1 scf scfstaff 1084 Feb 22 01:44 RcppArmadilloLapack.h
-rw-r--r-- 1 scf scfstaff 1084 Feb 22 01:44 RcppArmadilloLapack.h.in
-rw-r--r-- 1 scf scfstaff 1280 Feb 22 01:44 RcppArmadilloSugar.h
-rw-r--r-- 1 scf scfstaff 10817 Feb 22 01:44 RcppArmadilloWrap.h
-rw-r--r-- 1 scf scfstaff 232 Feb 22 01:44 README
所以现在我尝试使用R CMD SHLIB创建一个共享对象但是得到以下错误。
arwen$ PKG_LIBS=`Rscript -e "Rcpp:::LdFlags()"`
arwen$ PKG_CXXFLAGS=`Rscript -e "RcppArmadillo:::CxxFlags()"`
arwen$ R CMD SHLIB simpleexample.cpp
g++ -I/usr/share/R/include -DNDEBUG -I"/server/linux/lib/R/3.0/x86_64/sitelibrary/RcppArmadillo/include" -fpic -O3 -pipe -g -c simpleexample.cpp -o simpleexample.o
In file included from /server/linux/lib/R/3.0/x86_64/site-library/RcppArmadillo/include/RcppArmadillo.h:30:0,
from simpleexample.cpp:2:
/server/linux/lib/R/3.0/x86_64/site-library/RcppArmadillo/include/RcppArmadilloForward.h:26:24: fatal error: RcppCommon.h: No such file or directory
compilation terminated.
make: *** [simpleexample.o] Error 1
所以正在发生的事情是编译器确实找到了RcppArmadillo.h,如下所示:
...
#include <RcppArmadilloForward.h>
#include <Rcpp.h>
#include <RcppArmadilloWrap.h>
#include <RcppArmadilloAs.h>
#include <RcppArmadilloSugar.h>
...
然后转到RcppArmadillo.h,后者又如下所示:
...
#include <RcppCommon.h>
...
和RcppCommon.h不在/usr/local/linux/lib/R/Current/x86_64/site-library/RcppArmadillo/include
中。相反,它位于/usr/local/linux/lib/R/Current/x86_64/site-library/Rcpp/include
。所以我遇到麻烦并不奇怪。
问题:如何设置PKG_LIBS和PKG_CXXFLAGS(以及其他任何内容),以便编译器可以找到这两个目录?如果我尝试将PK_CXXFLAGS指向Rcpp目录,那么编译器找不到RcppArmadillo.h。
答案 0 :(得分:1)
快速的:
为什么您认为使用命令行方法更好?我们一直在推荐替代品。
我理解并重视从命令行执行此操作的优点,并在Rcpp book的第2章中进行全面演练。正如在那里记录的那样,我不打算在此重复。
您可以改用inline包。包中和其他地方有 lot 示例。
更好的是,您可以使用Rcpp属性,如同名的Rcpp包装晕图中所述。 Rcpp Gallery上有许多工作示例。
为了激励,这里是计算外部产品的两行示例:
R> cppFunction('arma::mat opg(arma::vec x) { return x*x.t(); }',
+ depends="RcppArmadillo")
R> opg(1:3)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 4 6
[3,] 3 6 9
R>
这可能很容易。如果您确实想知道如何设置相应的标记,请在verbose=TRUE
模式下运行它,它会告诉您......