RcppChoose is an example of project that combines two parts, C++ code (libChoose/) and R package (rpackage/).
# 1. compile the c++ library
# - output: libChoose/libChoose.a
pushd libChoose/
make
popd
# 2. prepare Makefile for R package
# - output: rpkg/RcppChoose/src/Makevars
pushd rpkg
autoconf
./configure
popd
# 3. check R package is ready to use
Rscript --slave -e "devtools::load_all('rpkg/RcppChoose')"
devtools::load_all("rpkg/RcppChoose")
#> Loading RcppChoose
This is a basic example which shows you how to choose k
out of n
numbers.
library(RcppChoose)
# 1. choose: base R vs. RcppChoose implementation
# 1a. choose(10, 5)
choose(10, 5)
#> [1] 252
rcpp_choose(10, 5)
#> [1] 252
# 1b. choose(40, 20)
choose(40, 20)
#> [1] 137846528820
rcpp_choose(40, 20)
#> [1] 106285226
# 100 samples of sets of size k = 500 out of n = 1000
rcpp_nchoosek_sample(1000, 500, 100)
#> [1] 100
Main references that explain how to link external C++ libraries to the R/Rcpp package.
- Blog post An Autoconf Primer for R Package Authors.
- Minimal
Makevars.in
example in SO. - Example rbgen R package; see blog posts.
- The R official manual.
configure.ac
is included in the list of known files relevant for the R package development. So addingconfigure.ac
to.Rbuildignore
will have no effect, and the R building/loading commands will executeconfigure.ac
.
Here, this configuration file is separated from the source of R package in the directory rpkg/: rpkg/configure.ac and the R package directory rpkg/RcppChoose/.
- The compilation flag
-fPIC
is necessary for building shared libraries. Ommiting this flag will lead to the following error.
/usr/bin/ld: RcppChoose/rpkg/../libChoose//libChoose.a(choose.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
RcppChoose/rpkg/../libChoose//libChoose.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
/usr/share/R/share/make/shlib.mk:6: recipe for target 'RcppChoose.so' failed
As even the current g++ version does of course support C++11 by default, one still needs to explicitly enable C++11 support which we can do here from R prior to compiling.
Here, we adress this issue by the line CXX_STD = CXX11
in
rpkg/RcppChoose/src/Makevars.in and
the flag -std=c++11
in libChoose/Makefile.