似乎您可以将/path/to/libfoo.so
as 输入文件传递给gcc
并且程序将与其正确链接,就像将-lfoo
选项与-L/path/to
.
如果我知道所需版本库的完整路径,有什么区别?
如果您确定您知道正确库的正确路径,并且该库是静态存档,/path/to/libfoo.a
那么没有区别,但对于共享库来说,它会有所不同。
如果您在可执行文件上运行ldd
和/或运行,readelf
您将看到链接器已在该特定位置向库添加了依赖项,例如,这是一个使用-L
and的链接-l
:
$ g++ main.cc -lfoo -L.
$ readelf -d ./a.out | fgrep libfoo
0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
$ ldd ./a.out
linux-vdso.so.1 => (0x00007fff9b1fa000)
libfoo.so => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003ebe200000)
libm.so.6 => /lib64/libm.so.6 (0x0000003ebc200000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003ebd200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ebbe00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ebba00000)
请注意,依赖项只是libfoo.so
(并且由于.
不在我的共享库搜索路径中而未找到,暂时忽略它。)
这是相同的测试,但使用了库的路径名:
$ g++ main.cc /dev/shm/libfoo.so
$ readelf -d ./a.out | fgrep libfoo
0x0000000000000001 (NEEDED) Shared library: [/dev/shm/libfoo.so]
$ ldd ./a.out
linux-vdso.so.1 => (0x00007fff963f4000)
/dev/shm/libfoo.so (0x00007fad91c48000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003ebe200000)
libm.so.6 => /lib64/libm.so.6 (0x0000003ebc200000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003ebd200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ebbe00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ebba00000)
请注意,现在依赖项是/dev/shm/libfoo.so
.
这意味着如果程序没有安装在您的开发机器和您计划运行它的机器上的同一位置,您的程序将无法在运行时找到该库。
但是,这仅适用于库没有 SONAME 的情况,如果我重新链接指定 soname 的库(使用链接器-h
选项),然后重新链接我的可执行文件,则依赖项使用库的 soname,即使我指定了完整路径:
$ g++ -shared foo.cc -o libfoo.so -Wl,-h,libfoo.so
$ readelf -d libfoo.so | fgrep libfoo
0x000000000000000e (SONAME) Library soname: [libfoo.so]
$ g++ main.cc /dev/shm/libfoo.so
$ readelf -d ./a.out | fgrep libfoo
0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
为了真正证明依赖项使用了 soname,我们可以给它一个与文件名完全不匹配的 soname:
$ g++ -shared foo.cc -o libfoo.so -Wl,-h,libbar.so
$ readelf -d libfoo.so | fgrep SONAME
0x000000000000000e (SONAME) Library soname: [libbar.so]
$ g++ main.cc /dev/shm/libfoo.so
$ readelf -d ./a.out | fgrep libbar
0x0000000000000001 (NEEDED) Shared library: [libbar.so]
好吧,最明显的情况是路径中有多个具有该名称的库。严格来说这是一个配置错误(搜索错误的路径)。