在R中加载链接到Rust库的共享库

Zel*_*ny7 7 r shared-libraries rust

这里跟进这个问题,我在使用dyn.load加载链接到Rust dylib的共享库时遇到问题.我怀疑它与R在哪里寻找Rust dylib有关,但我没有找到一种方法来指定另一个位置而不是默认值.

从R开始,我执行以下操作:

> dyn.load('src/test.so')
Run Code Online (Sandbox Code Playgroud)

并收到此错误消息:

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
Run Code Online (Sandbox Code Playgroud)

如何加载依赖于另一个共享库的共享库?

文件对于dyn.load没有规定如何做到这一点.

更新:

感谢shepmaster,我能够在R中成功构建和导入共享库.共享库是用C编译的,并且本身链接到Rust库.这些是我的步骤:

  1. 编译共享的Rust库
  2. 使用以下命令编译共享C库并链接到Rust库(在Windows中,因为我今天早上在工作)

我的目录内容:

C:\Users\gravesee\test>ls
rglue.dll  rglue.rs  rustr.c  treble.h
Run Code Online (Sandbox Code Playgroud)

编译最终的共享库:

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
Run Code Online (Sandbox Code Playgroud)

在R中加载库:

> dyn.load("test.dll")
> is.loaded("triple")
[1] TRUE
> .Call("triple", as.integer(32))
The triple is 96
Run Code Online (Sandbox Code Playgroud)

She*_*ter 4

问题归结为这样一个事实:您的共享库不在系统默认的目录中。

您可以使用一些技巧,其中 2 个是我能够实现的:

  1. 从编译库的同一目录运行 R。

  2. 在启动 R 之前设置LD_LIBRARY_PATH(Linux) 或DYLD_LIBRARY_PATH(OS X)。

    DYLD_LIBRARY_PATH=/path/to/rust/lib/ R
    
    Run Code Online (Sandbox Code Playgroud)
  3. 应该能够在构建共享库时设置 rpath。

    g++ -shared treble.cxx -o treble.so -L/tmp/ -Wl,-rpath,/tmp -lglue
    
    Run Code Online (Sandbox Code Playgroud)

    然而,我无法让它在 OS X 上很好地工作,所以我不确定我做错了什么。

  4. (仅限 OS X)构建 C++ 库后,您可以更改引用原始 Rust 库的安装名称并包含绝对路径:

    install_name_tool -change libglue.dylib /tmp/libglue.dylib treble.so
    
    Run Code Online (Sandbox Code Playgroud)

基本上,当默认链接器搜索路径中不存在多个这些库时,您将需要查找如何拥有依赖于其他共享库的共享库。

来源

在 Mac OS X 中链接动态库 (libjvm.dylib)(rpath 问题)

在 OSX 上打印可执行文件的 rpath

@executable_path、@load_path 和 @rpath

如何在构建时修改 .dylib 的安装名称

clang,在链接时更改依赖共享库安装名称