[英]How do I create an R package that depends on a shared library with Rcpp?
I have a shared library libbcd.so
generated from C
source code.我有一个从
C
源代码生成的共享库libbcd.so
。 I also have some interface code Rinterface.h, Rinterface.cpp
, which looks as follows:我还有一些接口代码
Rinterface.h, Rinterface.cpp
,如下所示:
Rinterface.h :接口.h :
#pragma once
#include <R.h>
#include <Rcpp.h>
extern "C" {
#include "bcd.h"
}
void call_bcd();
Rinterface.cpp接口.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
.其中
mm_problem_alloc(), bcd_vars_alloc(), bcd(mm_problem*, bcd_vars*)
都是libbcd.so
中的函数,而libbcd.so
和mm_problem
是bcd_vars
中的用户定义类型。
I have created a package with Rcpp.package.skeleton("bcd")
put the Rinterface files under src
folder with the following Makevars我创建了一个 package 和
Rcpp.package.skeleton("bcd")
将Rinterface文件放在src
文件夹下,并使用以下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 SHLIB Rinterface.cpp
创建接口库R CMD build.
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
:如果我尝试在编译步骤后使用
install.packages("/path/to/bcd_1.0.tar.gz", type = "source")
从源代码安装 package,我会在尝试加载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.根据这篇文章,在我看来,一种解决方法是将
libbcd.so
的.c
源文件重命名为.cpp
,然后将它们放在src
文件夹中。 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
?一般来说,利用 Rcpp 能够从
R
调用第三方共享库的推荐方法是什么? I've found a related question here but it doesn't go into details of building the package.我在这里找到了一个相关的问题,但它并没有 go 详细介绍构建 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.我看过Writing R extensions
vignette("Rcpp-introduction")
, vignette("Rcpp-package")
但我无法得出明确的结论。 So, I'd appreciate an expert's help here.所以,我会在这里感谢专家的帮助。 Thank you!
谢谢!
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). ld.so
将根据需要为您加载系统级共享库(在 Linux 上,在其他操作系统上类似,想法相同)。 So if your package depends on a non-standard or uncommon shared library, tough luck.因此,如果您的 package 依赖于非标准或不常见的共享库,那么运气不好。 This can only work if
ld.so
knows about it, and an R package cannot make it so.这只有在
ld.so
知道它的情况下才有效,而 R package 不能做到这一点。
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.您可以做的是将您的
libbcd
的源代码与您的 package捆绑在一起,并将它们构建为static 库,链接到您的 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.可能只是将
libbcd
的源文件放入 package src/
目录的更简单的方法 - 并且 R 将负责 rest。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.