Following up on this question here, I am having issues using dyn.load
to load a shared library that is linked to a Rust dylib. I suspect it has something to do with where R is looking for the Rust dylib, but I have not found a way to specify another location than whatever the default is.
From R, I execute the following:
> dyn.load('src/test.so')
And receive this error message:
Error in dyn.load("src/test.so") :
unable to load shared object '/Users/Zelazny7/r-dev/rustr/src/test.so':
dlopen(/Users/Zelazny7/r-dev/rustr/src/test.so, 6): Library not loaded: libglue.dylib
Referenced from: /Users/Zelazny7/r-dev/rustr/src/test.so
Reason: image not found
How do I load a shared library that depends on another shared library?
The documentation for dyn.load
does not specify how to do this.
Update:
Thanks to shepmaster I was able to successfully build and import a shared library in R. The shared library was compiled in C and is itself linked to a Rust library. These were my steps:
My directory contents:
C:\Users\gravesee\test>ls
rglue.dll rglue.rs rustr.c treble.h
Compiling the final shared library:
gcc -shared -m64 -I"C:\Program Files\R\R-3.2.0\include" rustr.c -L"C:\Program Files\R\R-3.2.0\bin\x64" -lR -L. -lrglue -o test.dll
Loading the library in R:
> dyn.load("test.dll")
> is.loaded("triple")
[1] TRUE
> .Call("triple", as.integer(32))
The triple is 96
The problem is going to boil down to the fact that your shared libraries are not in the directories that your system expects them to be by default.
There are a few tricks that you can use, 2 of which I was able to make work:
Run R from the same directory you compiled the libraries.
Set the LD_LIBRARY_PATH
(Linux) or DYLD_LIBRARY_PATH
(OS X) before launching R.
DYLD_LIBRARY_PATH=/path/to/rust/lib/ R
You should be able to set the rpath when building the shared library.
g++ -shared treble.cxx -o treble.so -L/tmp/ -Wl,-rpath,/tmp -lglue
However, I wasn't able to get this to work nicely on OS X, so I'm not sure what I'm doing wrong.
(OS X only) After building your C++ library, you can change the install name that refers to the original Rust library and include the absolute path:
install_name_tool -change libglue.dylib /tmp/libglue.dylib treble.so
Basically, you will want to look up how to have shared libraries that depend on other shared libraries when multiple of those libraries do not exist in your default linker search paths.
Sources
Linking a dynamic library (libjvm.dylib) in Mac OS X (rpath issue)
Print rpath of executable on OSX
@executable_path, @load_path and @rpath
How do I modify the install name of a .dylib at build time
clang, change dependent shared library install name at link time
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With