链接时'-lfoo'和'/path/to/libfoo.so'之间的区别

时间:2013-10-08 07:07:27

标签: gcc linker ld

您似乎可以将/path/to/libfoo.so作为输入文件传递给gcc,程序将与其正确关联,就像将-lfoo选项与{{1}结合使用一样}。

如果我知道所需版本库的完整路径,有什么区别?

2 个答案:

答案 0 :(得分:2)

如果您确定知道正确库的正确路径,并且该库是静态存档/path/to/libfoo.a,则没有区别,但对于共享库,它会产生影响。

如果您在可执行文件上运行ldd和/或readelf,您将看到链接器已在该特定位置添加了对库的依赖关系,例如:这是使用-L-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]

答案 1 :(得分:1)

嗯,显而易见的情况是路径中有多个具有该名称的库。严格来说,这是一个配置错误(搜索错误的路径)。