简体   繁体   English

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

[英]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.somm_problembcd_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
  • I can create the interface library with R CMD SHLIB Rinterface.cpp我可以使用R CMD SHLIB Rinterface.cpp创建接口库
  • I can also build a package tarball with 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM