如何创建依赖于Rcpp共享库的R包?

gom*_*mfy 1 c dll r rcpp

我有一个libbcd.soC源代码生成的共享库。我也有一些接口代码Rinterface.h, Rinterface.cpp,如下所示:

Rinterface.h

#pragma once

#include <R.h>
#include <Rcpp.h>
extern "C" {
#include "bcd.h"
}

void call_bcd();
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

mm_problem_alloc(), bcd_vars_alloc(), bcd(mm_problem*, bcd_vars*)来自所有功能libbcd.so,并mm_problembcd_vars来自用户定义的类型libbcd.so

我创建了一个包,其中Rcpp.package.skeleton("bcd")将带有以下MakevarsRinterface文件放在src文件夹下

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
Run Code Online (Sandbox Code Playgroud)
  • 我可以使用创建接口库 R CMD SHLIB Rinterface.cpp
  • 我也可以用 R CMD build .

如果我尝试install.packages("/path/to/bcd_1.0.tar.gz", type = "source")在编译步骤之后从源代码安装软件包,则在尝试加载时收到错误消息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
Run Code Online (Sandbox Code Playgroud)

基于这个帖子在我看来,一个解决办法是重新命名.c的源文件libbcd.so.cpp,然后把他们的src文件夹中。它是否正确?

通常,推荐使用Rcpp调用第三方共享库的方法是R什么?我在这里找到了一个相关的问题但是没有涉及构建软件包的细节。我已经看过Writing R扩展 vignette("Rcpp-introduction")vignette("Rcpp-package")但是无法得出明确的结论。因此,在此感谢专家的帮助。谢谢!

Dir*_*tel 5

简而言之,你不能。

一个系统级的共享库将通过为您按需加载ld.so(在Linux,其他操作系统和同样的想法类似)。因此,如果您的软件包依赖于非标准或不常见的共享库,那么运气不好。 只有ld.so知道这一点,它才能起作用,而R包不能做到这一点。

可以做的是将您的源代码libbcd 与软件包捆绑在一起,并将它们构建为从您的软件包链接到的静态库。那可行。可能只是将源文件libbcd放到package src/目录中的更简单方法-R将负责其余的工作。