Reputation: 347
I am trying to create a shared object using RcppArmadillo and am having trouble getting the compiler to find all of the headers. This question has nothing to do with the actual use of RcppArmadillo inside my code.
I'm running on Linux/Ubuntu.
Here is a very simple cpp file that illustrates the point. This is a stripped down version of the real file. You'll see that I have even stripped out any use of RcppArmadillo (though it does use Rcpp). Since I'm including RcppArmadillo.h, I understand that I should note include Rcpp.h as well. Nevertheless, I end up with the same error.
//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);
}
The relevant header file is located in this directory.
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
So now I try to create a shared object using R CMD SHLIB but get the following error.
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
So what's happening is that the compiler does find RcppArmadillo.h, which looks like the following:
...
#include <RcppArmadilloForward.h>
#include <Rcpp.h>
#include <RcppArmadilloWrap.h>
#include <RcppArmadilloAs.h>
#include <RcppArmadilloSugar.h>
...
It then goes to RcppArmadillo.h, which in turn looks like the following:
...
#include <RcppCommon.h>
...
and RcppCommon.h is not in /usr/local/linux/lib/R/Current/x86_64/site-library/RcppArmadillo/include
. Instead, it is in /usr/local/linux/lib/R/Current/x86_64/site-library/Rcpp/include
. So it is not surprising that I run into trouble.
Question: How do I set PKG_LIBS and PKG_CXXFLAGS (and whatever else) such that the compiler can find both directories? If I try pointing PK_CXXFLAGS to the Rcpp directory, then the compiler cannot find RcppArmadillo.h.
Upvotes: 1
Views: 1044
Reputation: 368241
Quick ones:
Why do you think using the command-line approach is better? We have always recommended alternatives.
I do understand and value the merit of doing it from the command-line, and give a full walkthrough in Chapter 2 of the Rcpp book. As it is documented there, I am not going to repeat it here.
You can use the inline package instead. There are lots of examples in the package and other places.
Better still, you can use Rcpp Attributes as documented in the Rcpp package vignette of the same name. There are many working examples at the Rcpp Gallery.
To motivate, here is two-line example computing an outer-product:
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>
It can be that easy. And if you really want to know how to set the appropriate flags, run this in verbose=TRUE
mode and it will tell you...
Upvotes: 1