我看过多个地方,但未能找到解决问题的简单示例。
我需要的是能够使用我拥有的多个.so文件(以及.h文件)。
一个简单的例子是:
我有以下文件:a.h,a.cpp函数jeden-这是我的R库,accessor.cpp,它从外部库libdwa.so向R公开dwa函数。我有头文件dwa.h和此库libdwa.so。
只有在将库文件libdwa.so放入目录'/ usr / lib'(我使用Debian)时,我才可以管理二进制程序包的构建(并且一切正常)。但这不是解决方案。
我应该在哪里放置库“ dwa”文件(dwa.h和libdwa.so),以及在Makevars文件中添加哪些标志以获得可移植的解决方案?
我在这里总结我的结果。我相信一些非常简单的示例一开始就很有用。
在 inst 中放入2个外部库:
/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/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;
}
纯R库_ / src / hello_world.cpp_也存在:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
String hello_world() {
String hw = "Hello World";
return hw ;
}
最终 / NAMESPACE 文件:
useDynLib("test6", .registration=TRUE)
import("Rcpp")
importFrom("utils", "object.size", "packageVersion")
exportPattern("^[[:alpha:]]+")
构建 source 和 binary 软件包是成功的,但是只有 source 有用,因为 binary 可以严格地编写库。
答案 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
,例如在RcppArrayFire或dqmagic中。