I want to use the libDAI C++ library within an R-package and want the package:
- to be usable on Linux and Windows
- save disc space (the external library has ~60 Mb)
- the end user does not need to install boost and gmp for compilation
My current setup is:
- precompile libDAI
- copy libdai.a to lib/
- copy all libDAI header files to inst/include
- add Makevar to src/
Modify Makevar file:
# include libraries
PKG_CPPFLAGS =-I../inst/include/
PKG_LIBS = -Llib -l../lib/libdai.a
My script for accessing the libDAI library is (test.cpp in src/):
#include <dai/factorgraph.h>
#include <Rcpp.h>
#include <cmath>
using namespace Rcpp;
using namespace std;
using namespace dai;
//'
//' Creates libDAI factor graph object
//'
//' @param factor_graph character definition of the factor graph
//' @export
// [[Rcpp::export]]
void initialize_factor_graph(const char* factor_graph) {
// read the factor graph from the string
std::istringstream fgStream(factor_graph);
FactorGraph net;
net.ReadFromString( fgStream );
// Output some information about the factorgraph
cout << "Factor graph has " << net.nrVars() << " variables" << endl;
cout << "Factor graph has " << net.nrFactors() << " factors" << endl;
}
running Rscript -e "Rcpp::compileAttributes('libdai')"
, followed by R CMD INSTALL libdai
returns the error:
Error: package or namespace load failed for 'libdai' in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object
'/home/jk/libs/R/libdai/libs/libdai.so':
/home/jk/libs/R/libdai/libs/libdai.so: undefined symbol: _ZTVN3dai11FactorGraphE
Error: loading failed
So my questions are:
- What is wrong with my setup?
- what is the best procedure to share my final package on CRAN?
- What is the nicest setup for sharing the package?
My question is closely related to this and this question and several other post related to referencing static libraries, however I was not able to solve my problem with these links.
How to link with a static library
You can either use
-L<directory> -l<name>
or<path>
, i.e. in your caseor
Header placement
The headers for
libDAI
are only used internally. One cannot link to the functions declared in these headers. I would therefore not useinst/include
for these headers.Dependencies on CRAN
The gmp library seems to be available on the CRAN builders, c.f. https://github.com/cran/gmp and https://cran.r-project.org/package=gmp. It seems that libDAI requires linking to boost (program options), c.f. https://bitbucket.org/jorism/libdai/src/83bd24a4c5bf17b0592a7b5b21e26bf052881833/Makefile.LINUX?at=master&fileviewer=file-view-default#Makefile.LINUX-49. However, looking at the actual
Makefile
it seems this is only used for tests and utility programs. So you might get away with the boost headers provided by the BH package.Pre-building static libraries
This is a common approach on Windows (c.f. https://github.com/rwinlib), but I find it unusual for Linux. The more common approach would be one of:
For all three approaches there are numerous examples on CRAN and GitHub. It is difficult to make a recommendation, though. I probably would go for "include the sources in the package" and use the Makefile provided by upstream as a starting point for building the library.