I'm currently working on a R package that depends on Eigen, EigenRand, and GSL. I was able to successfully build the package when it just depended on Eigen and GSL. Now, when I build, the compile is successful, but R is not able to link the .so file.
this is my Makevars file:
PKG_LIBS = $(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"` `gsl-config --libs`
PKG_CPPFLAGS = -I '/path/to/include/eigen-3.4.0' -I '/path/to/include/EigenRand'
this is the error message:
Error: package or namespace load failed for ‘pkgname’ in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object '/tmp/RtmpwgpGqO/Rinst855c41160545/00LOCK-pkgname/00new/pkgname/libs/pkgname.so':
/tmp/RtmpwgpGqO/Rinst855c41160545/00LOCK-pkgname/00new/pkgname/libs/pkgname.so: undefined symbol: _ZN4Rcpp9RcppEigen10eigen_wrapIN5Eigen5ArrayIiLin1ELin1ELi0ELin1ELin1EEEEEP7SEXPRECRKT_
Error: loading failed
Execution halted
ERROR: loading failed
I’ve changed the actual name to “pkgname” where it fits.
I was able to successfully compile and link to a package when the code just involved Eigen and GSL so I don’t think it’s a problem with these two libraries, and installing RcppEigen led to error with unknown includes, so I didn’t switch to RcppEigen.
Edit: I think I can reproduce the problem with this setup. I guess I couldn't build with Eigen, but because I didn't return the array created with Eigen, the compiler optimised it away for me. I would still be interested in knowing what went wrong though because even if I were to use the RcppEigen library, I still need to import EigenRand, which does not have a R package yet.
src/pkgexports.cpp:
#include <Rcpp.h>
using namespace Rcpp;
List pkgfn();
RcppExport SEXP pkgfn_pkgfn() {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::traits::input_parameter< int >::type seed(seedSEXP);
__result = Rcpp::wrap(pkgfn());
return __result;
END_RCPP
}
src/pkgfn.cpp:
#include <R.h>
#include <Rmath.h>
#include <Rcpp.h>
#include <Eigen/Dense>
using Rcpp::List;
using Rcpp::_;
using namespace Eigen;
List pkgfn(){
ArrayXd r_beta = ArrayXd::Random(4);
return List::create(_["r_beta"] = r_beta);
}
Makevars:
PKG_CPPFLAGS = -I '/usr/local/include/eigen3'
Edit2: I've installed all other libraries using Mamba/Conda in another enviroment, but because Eigen & EigenRand doesn't seem to have channels for that I have installed them from source and added them to /usr/local/include
This seems to solve the problem. There was nothing wrong with including the libraries.
src/pkgfn.cpp:
#include <R.h>
#include <Rmath.h>
#include <Rcpp.h>
#include <Eigen/Dense>
using Rcpp::List;
using Rcpp::_;
using namespace Eigen;
List pkgfn(){
ArrayXd r_beta = ArrayXd::Random(4);
auto r_beta_vec = vector<double>(r_beta.data(), r_beta.data()+4);
return List::create(_["r_beta"] = r_beta_vec);
}