Reputation: 689
I have a shared library libbcd.so
generated from C
source code.
I also have some interface code Rinterface.h, Rinterface.cpp
, which looks as follows:
Rinterface.h:
#pragma once
#include <R.h>
#include <Rcpp.h>
extern "C" {
#include "bcd.h"
}
void call_bcd();
Rinterface.cpp
#include "Rinterface.h"
// [[Rcpp::export]]
void call_bcd() {
mm_problem* pr = mm_problem_alloc();
bcd_vars* vars = bcd_vars_alloc();
bcd(pr, vars);
}
Where mm_problem_alloc(), bcd_vars_alloc(), bcd(mm_problem*, bcd_vars*)
are all functions from libbcd.so
and mm_problem
and bcd_vars
are user defined types from libbcd.so
.
I have created a package with Rcpp.package.skeleton("bcd")
put the Rinterface files under src
folder with the following Makevars
PKG_CPPFLAGS=-I/usr/local/lib/R/site-library/Rcpp/include/ -I/path/to/bcd/headers/
PKG_LIBS=-L/path/to/bcd/library/file -lbcd
R CMD SHLIB Rinterface.cpp
R CMD build .
If I try to install the package from source with install.packages("/path/to/bcd_1.0.tar.gz", type = "source")
after the compilation step I get an error when it tries to load libbcd.so
:
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for ‘bcd’ in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object '/home/gomfy/R/x86_64-pc-linux-gnu-library/3.6/00LOCK-bcd/00new/bcd/libs/bcd.so':
libbcd.so: cannot open shared object file: No such file or directory
Based on this post it seems to me that a workaround would be to rename the .c
source files of libbcd.so
to .cpp
and then put them in the src
folder. Is this correct?
In general, what is a recommended way of leveraging Rcpp to be able to call a third party shared library from R
? I've found a related question here but it doesn't go into details of building the package. I've looked at Writing R extensions vignette("Rcpp-introduction")
, vignette("Rcpp-package")
but I wasn't able to come to a clear conclusion. So, I'd appreciate an expert's help here. Thank you!
Upvotes: 2
Views: 667
Reputation: 368181
In short, you can't.
A system-level shared library will be loaded on demand for you by ld.so
(on Linux, similar on other OSs and same idea). So if your package depends on a non-standard or uncommon shared library, tough luck. This can only work if ld.so
knows about it, and an R package cannot make it so.
What you can do is bundle the sources of your libbcd
with your package and them built as a static library linked to from your package. That will work. As will the simpler approach of maybe just putting the source files of libbcd
into the package src/
directory -- and R will take care of the rest.
Upvotes: 6