我试图开发的R包,它利用了Arrayfire,感谢RCPP库。我已经开始编写一个示例代码(让我们将其命名为hello_world.cpp),如下所示:
#include <arrayfire.h>
// [[Rcpp::export]]
bool test_array_fire(){
af::randu(1, 4);
return true;
}
Run Code Online (Sandbox Code Playgroud)
然后,我尝试使用sourceCpp函数编译它
Rcpp::sourceCpp('src/hello_world.cpp')
Run Code Online (Sandbox Code Playgroud)
我的第一个惊喜是我必须手动设置一些标志(在编译一段 C++ 代码时sourceCpp似乎忽略了Makevars配置)。我是这样做的:
Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
Sys.setenv("PKG_CPPFLAGS"="-I/opt/arrayfire/include/")
Sys.setenv("PKG_LIBS"="-L/opt/arrayfire/lib64/ -laf")
Run Code Online (Sandbox Code Playgroud)
但是,代码仍然无法正确编译。每次试验都以以下输出结束:
Error in 'dyn.load("/tmp/RtmpHaODIU/sourceCpp-x86_64-pc-linux-gnu-1.0.2/sourcecpp_689c5adb8d/sourceCpp_14.so")':
unable to load shared object '/tmp/RtmpHaODIU/sourceCpp-x86_64-pc-linux-gnu-1.0.2/sourcecpp_689c5adb8d/sourceCpp_14.so':
libaf.so.3: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法为我的问题找到解决方案(即使某些 Stack Overflow 问题引发了乍一看或多或少相似的问题)。
我该如何解决?
当 R 尝试加载共享对象文件时,该错误发生在过程中的很晚。这意味着在您设置的环境变量的帮助下,编译和链接工作正常。但是在最后一步中,运行时链接器不知道libaf.so.3位于何处。这是一种通常在操作系统级别进行的配置,例如在我的系统上
ralf@barra:~$ /sbin/ldconfig -p | grep libaf
libafopencl.so.3 (libc6,x86-64) => /lib/libafopencl.so.3
libafopencl.so (libc6,x86-64) => /lib/libafopencl.so
libafcpu.so.3 (libc6,x86-64) => /lib/libafcpu.so.3
libafcpu.so (libc6,x86-64) => /lib/libafcpu.so
libaf.so.3 (libc6,x86-64) => /lib/libaf.so.3
libaf.so (libc6,x86-64) => /lib/libaf.so
Run Code Online (Sandbox Code Playgroud)
如果我尝试你的例子,它与链接到的共享对象文件没有问题libaf:
ralf@barra:~$ ldd /tmp/RtmpcjY9dN/sourceCpp-x86_64-pc-linux-gnu-1.0.2/sourcecpp_13d33790279c/sourceCpp_7.so | grep libaf
libaf.so.3 => /lib/libaf.so.3 (0x00007f21037ed000)
Run Code Online (Sandbox Code Playgroud)
我希望在您的情况下,第一个命令不会提供任何结果,第二个(调整后的)命令将导致“找不到文件”(?)错误。
有几种方法可以告诉运行时链接器有关库位置的信息:
/etc/ld.so.conf或(更好)将文件放在 中/etc/ld.so.conf.d/,参见http://arrayfire.org/docs/installing.htm#Linux。LD_LIBRARY_PATH。-Wl,-rpath,/opt/arrayfire/lib64/到PKG_LIBS至于Rcpp::sourceCpp不尊重Makevars文件:问题是你写的C++文件不能直接使用。相反,Rcpp 属性必须创建额外的包装函数,这是在临时目录中完成的。现在原则上也可以将Makevars文件复制到该目录中。但是,通常在Rcpp::plugins和Rcpp::depends属性的帮助下设置此类变量。例如,使用// [[Rcpp::plugins(cpp11)]]. 对于其他变量,您可以编写自己的插件,也可以编写我的RcppArrayFire提供的插件。
但是,如果这是您的目标,我建议您从一个包开始。Rcpp::sourceCpp在很多方面都很棒,但是在没有 R 包帮助的情况下与系统安装的库接口不是其中之一。
| 归档时间: |
|
| 查看次数: |
388 次 |
| 最近记录: |