One reason R has become so popular is the vast array of add-on packages available at the CRAN and Bioconductor repositories. R's package system along with the CRAN framework provides a process for authoring, documenting and distributing packages to millions of users. However, users and administrators wanting to build packages requiring C++ on 64-bit Solaris SPARC systems often are unable to compile their packages using Oracle Developer Studio.
R uses $R_HOME/etc/Makeconf as a system-wide default for C, C++ and Fortran build variables. The options in Makeconf are defined during configuration prior to build time and are subsequently the build options used to compile R packages. Base R does not require C++ during build time and therefore, when using the Oracle Developer Studio compiler, the resulting build variables are often insufficient for building R packages that use C++ templates. This blog outlines the build flags required for compiling the popular open source R package Rcpp using R-3.3.0 under Oracle Developer Studio 12.5 for Solaris SPARC.
For Rcpp, we focus on the following compiler options:
- CC: Program for compiling C programs; default ‘cc’.
- CXX: Program for compiling C++ programs; default ‘g++’.
- CXXFLAGS: Extra flags to give to the C++ compiler.
- CPPFLAGS: Extra flags to give to the C preprocessor and programs that use it (the C compiler).
- SHLIB_CXXLDFLAGS: Extra flags for the shared library linker.
By default The Oracle Developer Studio C++ compiler uses an older STL which is incompatible with modern C++. There are several options to use a modern STL, and we used g++ STL/binary compatible mode for Solaris versions 10, 11 and 12: -std=c++03.
- CC = <Oracle Studio 12.5 path>/bin/cc -xc99 -m64
- CXX = <Oracle Studio 12.5 path>/bin/CC -m64 -std=c++03
- CXXFLAGS = -xO3 -m64 -std=c++03
- CXX1X = <Oracle Studio 12.5 path>/bin/CC -m64 -std=c++03
Additionally, the CC -G command does not pass any -l options to ld. If you want the shared library to have a dependency on another shared library, you must pass the necessary -l option on the command line. For example, if you want the shared library to be dependent upon libCrunG3.so.1, you must pass -lCrunG3 on the command line.
Rcpp requires the libraries libstdc++, libgc and libCrunG3, so the flags for the shared library linker will be:
- SHLIB_CXXLDFLAGS = -G -L/<Oracle Studio 12.5 path>/lib -lstdc++ -lgcc_s -lCrunG3
With these updates to $RHOME/etc/Makeconf, we can now install Rcpp:
trying URL 'http://camoruco.ing.uc.edu.ve/cran/src/contrib/Rcpp_0.12.12.tar.gz'
Content type 'application/x-gzip' length 2421289 bytes (2.3 MB)
downloaded 2.3 MB
* installing *source* package ‘Rcpp’ ...
** package ‘Rcpp’ successfully unpacked and MD5 sums checked
** building package indices
** installing vignettes
** testing if installed package can be loaded
* DONE (Rcpp)
Note that directly including C++ library linking options in $R_HOME/etc/Makeconf is a global approach. You can override variables in Makeconf with either of two approaches:on a per-user basis, by modifying ~/.R/Makevars, or on a per-package basis, by modifying <package name>/src/Makevars.
For example, with package Rcpp, adding PKG_LIBS = -lstdc++ -lgcc_s -lCrunG3 to Rccp/src/Makevars would satisfy the flags for the shared library linker and thus it would not be necessary to define SHLIB_CXXLDFLAGS globally.
For more information on custom R build configurations, refer to the R manuals on Writing R Extensions and Custom Package Compilation.