R CMD SHLIB与RcppArmadillo编译错误

时间:2014-05-22 00:55:41

标签: c++ r rcpp

我正在尝试使用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。

1 个答案:

答案 0 :(得分:1)

快速的:

  1. 为什么您认为使用命令行方法更好?我们一直在推荐替代品。

  2. 我理解并重视从命令行执行此操作的优点,并在Rcpp book的第2章中进行全面演练。正如在那里记录的那样,我不打算在此重复。

  3. 您可以改用inline包。包中和其他地方有 lot 示例。

  4. 更好的是,您可以使用Rcpp属性,如同名的Rcpp包装晕图中所述。 Rcpp Gallery上有许多工作示例。

  5. 为了激励,这里是计算外部产品的两行示例:

    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模式下运行它,它会告诉您......