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

2022-06-06 00:00:00 c++ rcpp

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

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

一个简单的例子是:

我有以下文件:a.h,a.cpp函数jeden-这是我的R库accesor.cpp,它向R公开外部库libdwa.so中的函数dwa。我有头文件dwa.h和这个库libdwa.so.

只有当我将库文件libdwa.so放入目录‘/usr/lib’(我使用Debian)时,我才能设法构建二进制包(一切工作正常)。但这不是可解析的解决方案。

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

已添加摘要

我在这里总结了我的结果。我相信一些极端简单的例子在开始时是有用的。

  1. 2个外部库放入inst:

    /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/accesor.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. 最终/命名空间文件:

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

已成功生成源和二进制包,但只有源包有用,因为二进制具有严格写入的库的路径。


解决方案

假设您的目录结构如下:

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

在这种情况下,您可以使用issrc/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,例如在RcppArrayFire或dqmagic中。

相关文章