[Rcpp-devel] Compiling RcppArmadillo through R CMD SHLIB on Windows XP

Romain Francois romain at r-enthusiasts.com
Sun Dec 12 12:57:37 CET 2010


Le 12/12/10 04:03, Savitsky, Terrance a écrit :
> Hello,
>
> I employ a variant of the following lines in a cygwin bash session in
> Windows XP to compile my .cpp file.
>
> $ export PKG_LIBS=`Rscript.exe -e "RcppArmadillo:::LdFlags()"`
>
> $ export PKG_CXXFLAGS=`Rscript.exe -e "RcppArmadillo:::CxxFlags()"`
>
> $ R CMD SHLIB fastLm.cpp
>
> I receive the following compile error:
>
> G++ -I”C:/PROGRA~1/R/R-212~1.0/include” Rscript.exe –e
> ”RcppArmadillo:::CxxxFlags()” –O2 – Wall –pedantic – c fastLm.cpp – o
> fastLm.o
>
> G++:Rscript.exe: No such file or directory
>
> fastLm.cpp:1:27: error: RcppArmadillo.h: No such file or directory
>
> fastLm.cpp:2: error: ‘SEXP’ does not have name a type
>
> I’ve included the R bin directory containing Rscript.exe to the PATH
> environment statement. Should one use a different syntax for windows to
> capture RcppArmadillo dependencies? (Fyi, I am able to build using
> inline, though my code is 600 lines and I will have multiple versions,
> so using the old approach may provide the most modular de-bugging
> approach vs. re-installing a package as I add files).
>
> Thanks, Terrance Savitsky

Hello,

I would strongly advise you to make it a package, especially if you deal 
with multiple files, etc ...

One thing you might want to consider is to use the verbose argument of 
cxxfunction, so that inline shows you how it runs the show.

For example:

require(RcppArmadillo)
require(inline)

f <- cxxfunction( , '
arma::mat x(2,2) ;
NumericMatrix res = wrap( x + x ) ;
return res ;
', plugin = "RcppArmadillo", verbose = TRUE )

When you run this, you'll see what inline does with the PKG_LIBS, etc ...:

For example, it shows me this on OSX:

romain at naxos ~/svn/rcpp/pkg $ Rscript bla.R
Le chargement a nécessité le package : RcppArmadillo
Le chargement a nécessité le package : Rcpp
Le chargement a nécessité le package : methods
Le chargement a nécessité le package : inline
  >> setting environment variables:
PKG_LIBS = 
/Library/Frameworks/R.framework/Versions/2.12/Resources/library/Rcpp/lib/x86_64/libRcpp.a 
$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

  >> LinkingTo : RcppArmadillo, Rcpp
CLINK_CPPFLAGS = 
-I"/Library/Frameworks/R.framework/Versions/2.12/Resources/library/RcppArmadillo/include" 
-I"/Library/Frameworks/R.framework/Versions/2.12/Resources/library/Rcpp/include" 


  >> Program source :

    1 :
    2 : // includes from the plugin
    3 : #include <RcppArmadillo.h>
    4 : #include <Rcpp.h>
    5 :
    6 :
    7 : #ifndef BEGIN_RCPP
    8 : #define BEGIN_RCPP
    9 : #endif
   10 :
   11 : #ifndef END_RCPP
   12 : #define END_RCPP
   13 : #endif
   14 :
   15 : using namespace Rcpp;
   16 :
   17 :
   18 : // user includes
   19 :
   20 :
   21 : // declarations
   22 : extern "C" {
   23 : SEXP file313a14a1( ) ;
   24 : }
   25 :
   26 : // definition
   27 :
   28 : SEXP file313a14a1(  ){
   29 : BEGIN_RCPP
   30 :
   31 : arma::mat x(2,2) ;
   32 : NumericMatrix res = wrap( x + x ) ;
   33 : return res ;
   34 :
   35 : END_RCPP
   36 : }
   37 :
   38 :
Compilation argument:
  /Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB 
file313a14a1.cpp 2> file313a14a1.cpp.err.txt
g++ -arch x86_64 -I/Library/Frameworks/R.framework/Resources/include 
-I/Library/Frameworks/R.framework/Resources/include/x86_64 
-I/usr/local/include 
-I"/Library/Frameworks/R.framework/Versions/2.12/Resources/library/RcppArmadillo/include" 
-I"/Library/Frameworks/R.framework/Versions/2.12/Resources/library/Rcpp/include" 
   -fPIC  -g -O3 -Wall -pipe -c file313a14a1.cpp -o file313a14a1.o
g++ -arch x86_64 -dynamiclib -Wl,-headerpad_max_install_names -undefined 
dynamic_lookup -single_module -multiply_defined suppress 
-L/usr/local/lib -o file313a14a1.so file313a14a1.o 
/Library/Frameworks/R.framework/Versions/2.12/Resources/library/Rcpp/lib/x86_64/libRcpp.a 
-L/Library/Frameworks/R.framework/Resources/lib/x86_64 -lRlapack 
-L/Library/Frameworks/R.framework/Resources/lib/x86_64 -lRblas 
-lgfortran -F/Library/Frameworks/R.framework/.. -framework R 
-Wl,-framework -Wl,CoreFoundation

Then you can just hardcode PKG_LIBS and CLINK_CPPFLAGS (or use 
PKG_CPPFLAGS if you prefer).



Another tip with inline is that you can read the code from a file, e.g :

f <- cxxfunction( ,
	paste( readLines("bla.cpp"), collapse = "\n") ,
	plugin = "RcppArmadillo", verbose = TRUE )

This way you can import multiple files, etc ... while keeping the C++ 
code out of the R code. I would still however very strongly recommend 
you to make a package. It is well documented, easy and it will save you 
some time.

Romain

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/fT2rZM : highlight 0.2-5
|- http://bit.ly/gpCSpH : Evolution of Rcpp code size
`- http://bit.ly/hovakS : RcppGSL initial release




More information about the Rcpp-devel mailing list