Rcpp: cannot open shared object file

落花浮王杯 提交于 2020-01-25 03:59:27

问题


I'm trying to develop an R package, which makes use of Arrayfire, thanks to Rcpp library. I've started writing a sample code (let's name it hello_world.cpp) which looks like this:

#include <arrayfire.h>

// [[Rcpp::export]]
bool test_array_fire(){
    af::randu(1, 4);    
    return true;
}

Then, I tried to compile it using a sourceCpp function

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

My first suprise was the fact I had to set some flags manually (sourceCpp seems to ignore Makevars config when compiling a piece of C++ code). I did it with:

Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
Sys.setenv("PKG_CPPFLAGS"="-I/opt/arrayfire/include/")
Sys.setenv("PKG_LIBS"="-L/opt/arrayfire/lib64/ -laf")

However, the code still does not compile properly. Each trial finishes with the following output:

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

Unfortunately, I could not find an solution for my problem (even if some Stack Overflow questions raise issues which are more or less similar at first glance).

How can I fix it?


回答1:


The error occurs very late in the process when R tries to load the shared object file. This means that compilation and linking worked fine with the help of the environment variables you set. But in the final step the run-time linker does not know where libaf.so.3 is located. This is a configuration one normally does at the OS level, e.g. on my system

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

And if I try your example it works without problems with a shared object file that is linked against 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)

I expect that in your case the first command will provide no result and the second (adjusted) command will lead a "file not found"(?) error.

There are several ways to tell the run-time linker about the location of the library:

  • Edit /etc/ld.so.conf or (better) place a file in /etc.ld.so.conf.d/, c.f. http://arrayfire.org/docs/installing.htm#Linux.
  • Set LD_LIBRARY_PATH.
  • Add -Wl,-rpath,/opt/arrayfire/lib64/ to PKG_LIBS
  • Install ArrayFire into a directory that the linker searches by default. That's what I am doing since I compile from source and use the resulting DEB packages.

As for Rcpp::sourceCpp not respecting a Makevars file: The problem is that the C++ file you write cannot be used directly. Instead Rcpp attributes has to create additional wrapper functions, which is done in a temporary directory. Now one could in principle copy a Makevars file into that directory as well. However, one normally sets such variables with the help of Rcpp::plugins and Rcpp::depends attributes. For example, switching on C++11 is done using // [[Rcpp::plugins(cpp11)]]. For the other variables, you could write your own plugin or us the one provided by my RcppArrayFire.

However, I suggest you start with a package if that is your goal. Rcpp::sourceCpp is great for many things, but interfacing with a system installed library without the help of an R package is not one of them.




回答2:


A few things, quickly:

  • when you use sourceCpp() you are not using a package
  • randomly dropping variable used with a package do not help
  • there actually is a package by Ralf whi will probably chime in
  • and we have a writeup about it here at the Rcpp Gallery

So I would probably start by redoing / rebuilding the examples from the Rcpp Gallery article about RcppArrayFire.



来源:https://stackoverflow.com/questions/58477576/rcpp-cannot-open-shared-object-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!