c++ - Rcpp:安装带有静态库的包,以便独立于平台使用

标签 c++ r static-libraries rcpp .a

我想使用 libDAI C++ R 包中的库并想要该包:

  1. 可在 Linux 和 Windows 上使用
  2. 节省磁盘空间(外部库大约有 60 Mb)
  3. 最终用户不需要安装boost和gmp进行编译

我当前的设置是:

  • 预编译 libDAI
    • 将 libdai.a 复制到 lib/
    • 将所有 libDAI 头文件复制到 inst/include
  • 将 Makevar 添加到 src/

修改Makevar文件:

# include libraries
PKG_CPPFLAGS =-I../inst/include/
PKG_LIBS = -Llib -l../lib/libdai.a

我用于访问 libDAI 库的脚本是(src/中的 test.cpp):

#include <dai/factorgraph.h>
#include <Rcpp.h>
#include <cmath>

using namespace Rcpp;
using namespace std;
using namespace dai;

//'
//' Creates libDAI factor graph object
//'
//' @param factor_graph character definition of the factor graph
//' @export
// [[Rcpp::export]]
void initialize_factor_graph(const char* factor_graph) {

  // read the factor graph from the string
  std::istringstream fgStream(factor_graph);
  FactorGraph net;
  net.ReadFromString( fgStream );

  // Output some information about the factorgraph
  cout << "Factor graph has " << net.nrVars() << " variables" << endl;
  cout << "Factor graph has " << net.nrFactors() << " factors" << endl;

}

运行 Rscript -e "Rcpp::compileAttributes('libdai')",然后运行 ​​R CMD INSTALL libdai 返回错误:

Error: package or namespace load failed for 'libdai' in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object 
'/home/jk/libs/R/libdai/libs/libdai.so':
  /home/jk/libs/R/libdai/libs/libdai.so: undefined symbol: _ZTVN3dai11FactorGraphE
Error: loading failed

所以我的问题是:

  • 我的设置有什么问题?
  • 在 CRAN 上分享我的最终包的最佳程序是什么?
  • 共享包的最佳设置是什么?

我的问题与 this 密切相关和 this问题和其他几篇与引用静态库相关的帖子,但是我无法通过这些链接解决我的问题。

最佳答案

如何链接静态库

您可以使用 -L<directory> -l<name><path> ,即在你的情况下

PKG_LIBS = -L../lib -ldai

PKG_LIBS = ../lib/libdai.a

标题位置

libDAI 的 header 仅在内部使用。无法链接到这些 header 中声明的函数。因此我不会使用inst/include对于这些 header 。

对 CRAN 的依赖

gmp 库似乎可以在 CRAN 构建器上使用,参见https://github.com/cran/gmphttps://cran.r-project.org/package=gmp 。看来 libDAI 需要链接来提升(程序选项),参见https://bitbucket.org/jorism/libdai/src/83bd24a4c5bf17b0592a7b5b21e26bf052881833/Makefile.LINUX?at=master&fileviewer=file-view-default#Makefile.LINUX-49 。然而,看看实际的Makefile看来这仅用于测试和实用程序。因此,您可能会摆脱 BH 包提供的 boost header

预构建静态库

这是 Windows 上的常见方法(参见 https://github.com/rwinlib ),但我发现它对于 Linux 来说不寻常。更常见的方法是以下之一:

  • 将源代码包含在包中并在配置或包安装期间进行编译
  • 下载源代码并在配置期间进行编译
  • 与系统库的链接(不过我还没有看到 libDAI 的任何链接)。

对于这三种方法,CRAN 和 GitHub 上都有大量示例。不过,很难提出建议。我可能会选择“在包中包含源代码”并使用上游提供的 Makefile 作为构建库的起点。

关于c++ - Rcpp:安装带有静态库的包,以便独立于平台使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53631025/

相关文章:

c++ - std::vector::erase() 应该销毁被删除的元素吗? (而不是最后一个元素)

r - ggplot2:如何从 geom_密度图例中删除斜线

c++ - 静态库&动态库——更多C++乐趣

iphone - 强制包含不导出任何符号的静态库对象文件 (GCC/iPhone)

c++ - 如何避免相似模板中的代码重复

c++ - 多线程和互斥锁的竞争条件

r - R中的空间聚类(简单示例)

r - 如何让 R 在编辑后自动加载我的 .r 文件?

c++ - 用标准库(静态)编译静态库链接

c++ - 该算法的 Big-O 复杂度