Rcpp:无法打开共享对象文件



我正在尝试开发一个R包,它利用了Arrayfire,这要归功于Rcpp库。 我已经开始编写一个示例代码(我们将其命名为 hello_world.cpp(,如下所示:

#include <arrayfire.h>
// [[Rcpp::export]]
bool test_array_fire(){
af::randu(1, 4);    
return true;
}

然后,我尝试使用sourceCpp函数编译它

Rcpp::sourceCpp('src/hello_world.cpp')

我的第一个惊喜是我必须手动设置一些标志(sourceCpp在编译一段C++代码时似乎忽略了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")

但是,代码仍然无法正确编译。每个试用都以以下输出结束:

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

不幸的是,我找不到解决我的问题的方法(即使一些堆栈溢出问题提出了乍一看或多或少相似的问题(。

我该如何解决它?

当 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

如果我尝试您的示例,它可以与链接到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)

我希望在您的情况下,第一个命令不会提供任何结果,第二个(调整后的(命令将导致"找不到文件"(?(错误。

有几种方法可以告知运行时链接器有关库的位置:

  • 编辑/etc/ld.so.conf或(最好(将文件放在/etc/ld.so.conf.d/,c.f. http://arrayfire.org/docs/installing.htm#Linux。
  • 设置LD_LIBRARY_PATH.
  • -Wl,-rpath,/opt/arrayfire/lib64/添加到PKG_LIBS
  • 将 ArrayFire 安装到链接器默认搜索的目录中。这就是我正在做的事情,因为我从源代码编译并使用生成的 DEB 包。

至于Rcpp::sourceCpp不尊重Makevars文件:问题是你写的C++文件不能直接使用。相反,Rcpp 属性必须创建额外的包装函数,这是在临时目录中完成的。现在原则上也可以将Makevars文件复制到该目录中。但是,通常借助Rcpp::pluginsRcpp::depends属性来设置此类变量。例如,打开 C++11 是使用// [[Rcpp::plugins(cpp11)]]完成的。对于其他变量,您可以编写自己的插件,或者编写我的RcppArrayFire提供的插件。

但是,如果这是您的目标,我建议您从软件包开始。Rcpp::sourceCpp适用于许多事情,但无需 R 包帮助即可与系统安装的库接口不是其中之一。

有几件事,很快:

  • 当您使用sourceCpp()时,您没有使用软件包
  • 随机丢弃与包一起使用的变量无济于事
  • 实际上有一个包裹 拉尔夫·惠 可能会插话
  • 我们在 Rcpp 画廊有一篇关于它的文章

因此,我可能会从重做/重建Rcpp Gallery文章中关于RcppArrayFire的示例开始。

相关内容

  • 没有找到相关文章

最新更新