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

标签 gcc linker ld

看来你可以通过/path/to/libfoo.so作为 gcc 的输入文件并且程序将与它正确链接,就像使用 -lfoo 一样选项与 -L/path/to 结合使用.

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

最佳答案

如果您确定您知道正确库的正确路径,并且该库是静态存档,/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]

关于gcc - 链接时 '-lfoo'和 '/path/to/libfoo.so'的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19241267/

相关文章:

c++ - 有没有办法让 gcc 或 clang 在缺少 'else' 时发出警告?

gcc - 如何在没有任何循环或分支的情况下强制 CPU 按顺序执行程序?

c++ - 与 ‘operator<<’ 不匹配(可能是因为我的 c++/gcc 版本?)

c++ - 如何将 LuaJIT 与 C++ 程序链接起来?

linux - ld -m --verbose 实际上做了什么?

c++ - 链接时如何跟踪库的需求?

c++ - 有没有一种在转换后使用 views::filter 的有效方法? (范围适配器)

C++:对模板使用 "extern"关键字是否有意义?

c++ - Visual Studio 链接器找不到 libboost_system

linux - 将 .org 指令与 .data 部分 : In connection with ld 中的数据一起使用