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

How to link to already compiled external shared libraries in RCPP using Makevars?

本文关键字:编译 外部 共享 Makevars 何使用 链接 RCPP      更新时间:2023-10-16

我看了很多地方,但没有找到一个简单的例子来解决我的问题。

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

一个简单的例子是:

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

只有当我将库文件libdwa.so放入目录"/usr/lib"(我使用Debian)时,我才能管理构建二进制包(一切都很好)。但这不是一个可分割的解决方案。

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

已添加摘要

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

  1. inst2个外部库:

    /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/accesser.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:]]+")
    

构建sourcebinary包是成功的,但只有source一个是可用的,因为binary具有严格编写的库的路径。

假设您有一个类似的目录结构

/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@

并编写检查环境并基于发现创建CCD_ 4的CCD_。编写configure脚本有不同的策略。我通常使用autoconf,例如在RcppArrayFire或dqmagic中。