gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 06:46:52 25 4
gpt4 key购买 nike

我正在尝试开发一个 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

不幸的是,我找不到我的问题的解决方案(即使某些 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

如果我尝试您的示例,它与链接到 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/ , 引用http://arrayfire.org/docs/installing.htm#Linux .
  • 设置 LD_LIBRARY_PATH .
  • 添加 -Wl,-rpath,/opt/arrayfire/lib64/PKG_LIBS
  • 将 ArrayFire 安装到链接器默认搜索的目录中。这就是我正在做的,因为我从源代码编译并使用 resulting DEB packages .

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

    但是,如果这是您的目标,我建议您从一个包开始。 Rcpp::sourceCpp对很多事情都很好,但是在没有 R 包帮助的情况下与系统安装的库进行交互并不是其中之一。

    关于Rcpp:无法打开共享对象文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58477576/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com