我有这样的目录结构:指向目录的symlink和指向库的符号链接:
$ libtrotl.so -> /usr/local/lib64/tora-3.1/../libtrotl.so
$ instantclient -> /usr/lib/oracle/12.1/client64/lib
当我dlopen库libtrotl.so时,所有依赖库都被解析并加载。 感谢RPATH。
$ readelf -d libtrotl.so
Dynamic section at offset 0x17e7a8 contains 31 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libclntsh.so.12.1]
0x0000000000000001 (NEEDED) Shared library: [libboost_system.so.1.60.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libtrotl.so]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/instantclient/]
0x000000000000000c (INIT) 0xe7898
$ ldd libtrotl.so
linux-vdso.so.1 (0x00007ffdc25d1000)
libclntsh.so.12.1 => /home/ivan/.TOra3/poracle/./instantclient/libclntsh.so.12.1 (0x00007f6cd0c37000)
libboost_system.so.1.60.0 => /lib64/libboost_system.so.1.60.0 (0x00007f6cd0a24000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f6cd069c000)
libm.so.6 => /lib64/libm.so.6 (0x00007f6cd0393000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f6cd017b000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6ccfdb9000)
libmql1.so => /home/ivan/.TOra3/poracle/./instantclient/libmql1.so (0x00007f6ccfb43000)
libipc1.so => /home/ivan/.TOra3/poracle/./instantclient/libipc1.so (0x00007f6ccf7c4000)
libnnz12.so => /home/ivan/.TOra3/poracle/./instantclient/libnnz12.so (0x00007f6ccf0ba000)
我只使用-Wl,-rpath,"\$ORIGIN/instantclient/"
作为编译标志,它可以在任何地方使用 - 除了Gentoo。
Gentoo链接器(GNU gold(Gentoo 2.25.1 p1.1 2.25.1)1.11)添加了RPATH的RUNPATH insead。
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/instantclient/]
然后动态链接器不解析库。
(Gentoo)$ ldd libtrotl.so
linux-vdso.so.1 (0x00007ffe5c3e9000)
libclntsh.so.12.1 => /home/ivan/.TOra3/poracle/./instantclient/libclntsh.so.12.1 (0x00007f245dc9e000)
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/libstdc++.so.6 (0x00007f245d933000)
libm.so.6 => /lib64/libm.so.6 (0x00007f245d62e000)
libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.4/libgcc_s.so.1 (0x00007f245d417000)
libc.so.6 => /lib64/libc.so.6 (0x00007f245d07d000)
libmql1.so => not found
libipc1.so => not found
libnnz12.so => not found
libons.so => not found
正如您所看到的,在第二种情况下,libmql1.so虽然存在于instantclient子目录中,但未找到它。如何在Gentoo上设置RPATH?
答案 0 :(得分:1)
DT_RPATH
标记,DT_RUNPATH
是具有两种不同语义的现代实现。 Gentoo链接编辑器(ld
和gold
)默认情况下不会生成已弃用的标记。您可以(但可能不应该)通过传递-Wl,--disable-new-dtags
来禁用这些功能,但我建议不要这样做。
Qt中有一个较旧的底池解释了使用插件时这两者的区别:http://blog.qt.io/blog/2011/10/28/rpath-and-runpath/