I recently downloaded the 2013 Rcpp book off amazon to learn how to use C++ with my R code better and I'm trying the first compilation example with the first fibonacci recursion function and wrapper to see if I can do it. I'm on Ubuntu with the latest R.
First my C++:
/* Cpp based recurive function */
int fibonacci(const int x){
if(x == 0) return(0);
if(x == 1) return(1);
return(fibonacci(x - 1) + fibonacci(x - 2));
}
/* Wrapper */
extern "C" SEXP fibWrapper(SEXP xs) {
int x = Rcpp::as<int>(xs);
int fib = fibonacci(x);
return(Rcpp::wrap(fib));
}
Then I start sh and type in:
PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'`
PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'`
R CMD SHLIB Fibonacci.cpp
But I get:
g++ -I/usr/share/R/include -DNDEBUG -fpic -O3 -pipe -g -c Fibonacci.cpp -o Fibonacci.o
Fibbonacci.cpp:10:12: error: 'SEXP' does not name a type
make: *** [Fibonacci.o] Error 1
I figure maybe I need the include directive in my C++ code, so I do it again, but this time with #include<Rcpp.h>
at the top of the C++ file, and do the same commands in sh again, but still no joy:
g++ -I/usr/share/R/include -DNDEBUG -fpic -O3 -pipe -g -c Fibonacci.cpp -o Fibonacci.o
Fibonacci.cpp:1:18: fatal error: Rcpp.h: No such file or directory
compilation terminated.
make: *** [Fibbonacci.o] Error 1
What have I done wrong? If I query the values I've set in sh:
$PKG_CXXFLAGS
sh: 9: -I/local/yrq12edu/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/include: not found
$PKG_LIBS
sh: 10: -L/local/yrq12edu/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/lib: not found
But I think the not found messages are just because of the -L flag since the files are there if I cd to the directory.
You seem to have overlooked an important detail. When you do
PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'`
PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'`
R CMD SHLIB Fibonacci.cpp
the result of the first two should be assigned and exported to the shell. What you do here "assigns and forgets".
What you missed from Listing 2.1 which shows this (or maybe the e-book dropped it -- I do not have the e-book) is the very important trailing backslash which makes everything a single line:
PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'` \
PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'` \
R CMD SHLIB Fibonacci.cpp
Now the assignments happen in the same execution as the call to R (a shell script itself), it has the values and it passes them in the call to g++.
You can tell by the next two lines in which I fully quote the resulting commands which have all the required -I and -L pieces. Hence both (the compile and link step) go over multiple lines.
So the book is correct, and all this works if done the way showns. Both inline (discussed later in the chapter) and attributes (also discussed later in the same chapter) basically make the PKG_CXXFLAGS
and PKG_LIBS
assignments for you.
Edit: Also, your testing is wrong. What you meant may have been this
$ PKG_CXXFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'`
$ echo $PKG_CXXFLAGS
-I/usr/local/lib/R/site-library/Rcpp/include
$
You can't just 'invoke' a shell variable, hence the 'not found' answer you got.
Edit 2: In any event, the example you tried is really just there to motivate the rest of the discussion in Section 2.4 which details just how laborious, error-prone, ... this is -- leading to Sections 2.5 and 2.6 about inline and Attributes. Both are much better; use those.