如何使用Makevars链接到RCPP中已编译的外部共享库?

时间:2019-07-04 06:27:58

标签: c++ rcpp

我看过多个地方,但未能找到解决问题的简单示例。

我需要的是能够使用我拥有的多个.so文件(以及.h文件)。

一个简单的例子是:

我有以下文件:a.h,a.cp​​p函数jeden-这是我的R库,accessor.cpp,它从外部库libdwa.so向R公开dwa函数。我有头文件dwa.h和此库libdwa.so。

只有在将库文件libdwa.so放入目录'/ usr / lib'(我使用Debian)时,我才可以管理二进制程序包的构建(并且一切正常)。但这不是解决方案。

我应该在哪里放置库“ dwa”文件(dwa.h和libdwa.so),以及在Makevars文件中添加哪些标志以获得可移植的解决方案?

已添加摘要

我在这里总结我的结果。我相信一些非常简单的示例一开始就很有用。

  1. inst 中放入2个外部库:

    /inst/include/dwa.h
    /inst/include/trzy.h
    /inst/jeden/libdwa.so
    /inst/jeden/libtrzy.so
    
  2. configure 文件 / configure 的格式为(test6是程序包的名称):

    #!/bin/bash
    rpath=$(${R_HOME}/bin/Rscript -e 'cat(file.path(.libPaths()[1], "test6", "jeden"))') #'
    sed -e"s|@rpath@|"${rpath}"|" src/Makevars.in > src/Makevars
    
    exit 0
    
  3. 文件 /src/Makevars.in 的格式为:

    CXX_STD = CXX11
    
    PKG_CPPFLAGS = -I../inst/include/ -I.
    PKG_LIBS     = -ldwa -ltrzy -L../inst/jeden -Wl,-rpath,@rpath@
    
  4. /src/accessor.cpp 将库函数公开给R:

    #include <Rcpp.h>
    #include "../inst/include/dwa.h"
    #include "../inst/include/trzy.h"
    
    // [[Rcpp::export]]
    Rcpp::String r_dwa() {
      Rcpp::String res = dwa();.
      return res;
    }
    
    // [[Rcpp::export]]
    Rcpp::String r_trzy() {
      Rcpp::String res = trzy();.
      return res;
    }
    
  5. 纯R库_ / src / hello_world.cpp_也存在:

    #include <Rcpp.h>
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    String hello_world() {
      String hw = "Hello World";
      return hw ;
    }
    
  6. 最终 / NAMESPACE 文件:

    useDynLib("test6", .registration=TRUE)
    
    import("Rcpp")
    importFrom("utils", "object.size", "packageVersion")
    exportPattern("^[[:alpha:]]+")
    

构建 source binary 软件包是成功的,但是只有 source 有用,因为 binary 可以严格地编写库。

1 个答案:

答案 0 :(得分:6)

假设您的目录结构为

/opt/dwa/include/dwa.h
/opt/dwa/lib/libdwa.so

在这种情况下,您可以使用src/Makevars

PKG_CPPFLAGS = -I/opt/dwa/include
PKG_LIBS = -L/opt/dwa/lib -ldwa -Wl,-rpath,/opt/dwa/lib

当然,由于库和头文件的路径是硬编码的,因此这仍然不是可移植的。为了避免这种情况,请使用一个模板文件,例如src/Makevars.in

PKG_CPPFLAGS = @DWA_INC@
PKG_LIBS = @DWA_LIB@

并编写一个configure脚本,该脚本检查环境并根据发现结果创建src/Makevars。编写configure脚本有不同的策略。我通常使用autoconf,例如在RcppArrayFiredqmagic中。