Rcpp:使用静态库安装软件包,以独立于平台使用

时间:2018-12-05 11:15:03

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

我想在R包中使用libDAI C++库,并需要该包:

  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上共享我的最终软件包的最佳过程是什么?
  • 共享软件包的最佳设置是什么?

我的问题与thisthis问题以及与引用静态库有关的其他几篇文章密切相关,但是我无法使用这些链接解决我的问题。

1 个答案:

答案 0 :(得分:2)

如何与静态库链接

您可以使用-L<directory> -l<name><path>,例如您的情况

PKG_LIBS = -L../lib -ldai

PKG_LIBS = ../lib/libdai.a

标题位置

libDAI的标头仅在内部使用。不能链接到这些标头中声明的功能。因此,我不会将inst/include用于这些标题。

对CRAN的依赖

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

预构建静态库

这是Windows(参见https://github.com/rwinlib)上的一种常见方法,但是我发现它在Linux中是不常见的。更为常见的方法是:

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

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