如何使用Makevars链接到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文件中添加哪些标志以获得可移植的解决方案?
已添加摘要
我在这里总结了我的结果。我相信一些极端简单的例子在开始时是有用的。
2个外部库放入inst:
/inst/include/dwa.h /inst/include/trzy.h /inst/jeden/libdwa.so /inst/jeden/libtrzy.so
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
文件/src/Makevars.in的格式为:
CXX_STD = CXX11 PKG_CPPFLAGS = -I../inst/include/ -I. PKG_LIBS = -ldwa -ltrzy -L../inst/jeden -Wl,-rpath,@rpath@
/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; }
纯R库_/src/Hello_World.cpp_也存在:
#include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] String hello_world() { String hw = "Hello World"; return hw ; }
最终/命名空间文件:
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中。
相关文章