因此,我正在从事的项目使用非系统目录来保存代码使用的一些 DLL。我不想将它们放在系统目录中,因此可执行文件设置了一个 rpath 来查找 DLL。然而,随着越来越多的库被添加,现在有 DLL 依赖于该目录中的其他 DLL。
这些库无法找到它们所依赖的 DLL,因为它们不位于链接器正在查找的目录中,例如系统目录。
有没有办法让 DLL 搜索这个特定的非系统目录?比如rpath?图书馆是如何做到这一点的?该项目使用的构建系统是 CMake(如果这有助于回答)。
这个答案不起作用,因为库中没有 rPath 标签:https://unix.stackexchange.com/a/272286/4193
我考虑过使用LD_LIBRARY_PATH
, 这很有效,但打字很烦人,而且让其他人使用该应用程序也不是那么好。如果有办法将rPath
标签添加到库中,那将是最好的选择。
感谢指向以前的相关问题和答案。
答案1
有动态链接库的rpath吗?
就在这里。您可以使用-Wl,-rpath
ELF 共享对象,就像使用 ELF 可执行文件一样。克隆我提出的一个小例子
这里:
git clone https://gist.github.com/ardrabczyk/6aeb8545c9b754d6b15be390af4bdff0
运行make
编译。检查main
ELF 可执行文件需要哪些库:
$ readelf -d ./main
Dynamic section at offset 0xe30 contains 22 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libtwo.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [.]
(...)
并检查需要哪些库libtwo.so
:
$ readelf -d ./libtwo.so
Dynamic section at offset 0xe38 contains 22 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libone.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [libs]
(...)
正如您所看到的,两者main
都libtwo.so
需要一些共享对象,并且都设置了 rpath。您不需要设置 LD_LIBRARY_PATH 来运行 ./main:
$ ./main
I'm in bar()
.
main 将始终在当前目录中查找其 libtwo.so 依赖项,而 libtwo.so 将始终在libs
目录中查找其 libone.so 依赖项。如果libs
缺少 ./main 将无法启动:
$ mv libs libs.bak
$ ./main
./main: error while loading shared libraries: libone.so: cannot open shared object file: No such file or directory
恢复它:
$ mv libs.bak libs
$ ./main
I'm in bar()
答案2
既然您不想将其视为系统的一部分,那就按原样使用它;用户应用程序!
如果您添加~/.local/lib/
到您的LD_LIBRARY_PATH
,您可以将所有内容放在那里。只需在~/.local/
类似下创建部分FHS结构垃圾桶,ETC,库和分享。这样您就不需要使用前面的环境变量来调用程序。所有其他系统只需要将此目录附加到其库路径环境变量中。非常整洁和unixish。
如果你也拒绝这个解决方案,那么就只剩下一种可能性了。您可以使用每个系统都期望的固定路径,也可以使用包含路径并且也是期望的环境变量。