在 R 中加载链接到 Rust 库的共享库
Load a shared library linked to Rust library in R
跟进这个问题 ,我在使用 dyn.load
加载 linked 到 Rust dylib 的共享库时遇到问题。我怀疑这与 R 寻找 Rust dylib 的位置有关,但我还没有找到一种方法来指定默认位置以外的其他位置。
在 R 中,我执行以下命令:
> dyn.load('src/test.so')
并收到此错误消息:
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
如何加载依赖于另一个共享库的共享库?
dyn.load
的 documentation 未指定如何执行此操作。
更新:
感谢 shepmaster,我能够在 R 中成功构建和导入一个共享库。共享库是用 C 编译的,它本身 linked 到 Rust 库。这些是我的步骤:
- 编译共享 Rust 库
- 使用以下命令将共享 C 库和 link 编译为 Rust 库(在 Windows 中,因为我今天早上在工作)
我的目录内容:
C:\Users\gravesee\test>ls
rglue.dll rglue.rs rustr.c treble.h
编译最终的共享库:
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
正在加载 R 中的库:
> dyn.load("test.dll")
> is.loaded("triple")
[1] TRUE
> .Call("triple", as.integer(32))
The triple is 96
问题归结为您的共享库不在系统默认的目录中。
您可以使用一些技巧,其中 2 个是我能够做到的:
运行 R 来自您编译库的同一目录。
在启动 R 之前设置 LD_LIBRARY_PATH
(Linux) 或 DYLD_LIBRARY_PATH
(OS X)。
DYLD_LIBRARY_PATH=/path/to/rust/lib/ R
您应该能够在构建共享库时设置 rpath。
g++ -shared treble.cxx -o treble.so -L/tmp/ -Wl,-rpath,/tmp -lglue
但是,我无法让它在 OS X 上很好地工作,所以我不确定我做错了什么。
(OS X only)构建 C++ 库后,您可以更改引用原始 Rust 库的 install name 并包含绝对路径:
install_name_tool -change libglue.dylib /tmp/libglue.dylib treble.so
基本上,当您的默认链接器搜索路径中不存在多个共享库时,您将需要查找如何拥有依赖于其他共享库的共享库。
来源
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
虽然原来的答案很好,但我为此提出了替代方法。
跟进这个问题 dyn.load
加载 linked 到 Rust dylib 的共享库时遇到问题。我怀疑这与 R 寻找 Rust dylib 的位置有关,但我还没有找到一种方法来指定默认位置以外的其他位置。
在 R 中,我执行以下命令:
> dyn.load('src/test.so')
并收到此错误消息:
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
如何加载依赖于另一个共享库的共享库?
dyn.load
的 documentation 未指定如何执行此操作。
更新:
感谢 shepmaster,我能够在 R 中成功构建和导入一个共享库。共享库是用 C 编译的,它本身 linked 到 Rust 库。这些是我的步骤:
- 编译共享 Rust 库
- 使用以下命令将共享 C 库和 link 编译为 Rust 库(在 Windows 中,因为我今天早上在工作)
我的目录内容:
C:\Users\gravesee\test>ls
rglue.dll rglue.rs rustr.c treble.h
编译最终的共享库:
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
正在加载 R 中的库:
> dyn.load("test.dll")
> is.loaded("triple")
[1] TRUE
> .Call("triple", as.integer(32))
The triple is 96
问题归结为您的共享库不在系统默认的目录中。
您可以使用一些技巧,其中 2 个是我能够做到的:
运行 R 来自您编译库的同一目录。
在启动 R 之前设置
LD_LIBRARY_PATH
(Linux) 或DYLD_LIBRARY_PATH
(OS X)。DYLD_LIBRARY_PATH=/path/to/rust/lib/ R
您应该能够在构建共享库时设置 rpath。
g++ -shared treble.cxx -o treble.so -L/tmp/ -Wl,-rpath,/tmp -lglue
但是,我无法让它在 OS X 上很好地工作,所以我不确定我做错了什么。
(OS X only)构建 C++ 库后,您可以更改引用原始 Rust 库的 install name 并包含绝对路径:
install_name_tool -change libglue.dylib /tmp/libglue.dylib treble.so
基本上,当您的默认链接器搜索路径中不存在多个共享库时,您将需要查找如何拥有依赖于其他共享库的共享库。
来源
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
虽然原来的答案很好,但我为此提出了替代方法