为什么gcc在使用-l时动态链接?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么gcc在使用-l时动态链接?相关的知识,希望对你有一定的参考价值。

我使用pthread库做了一个“Hello World”程序。我用这个简单的方式编译它:

$ gcc main.c -lpthread

根据gcc文档(“链接选项”部分):

-llibrary [...]链接器搜索库的标准目录列表,实际上是一个名为liblibrary.a的文件。然后,链接器使用此文件,就好像它已按名称精确指定一样。 [...]

所以,我的理解是:gcc正在寻找libpthread.a。鉴于.a结尾,这应该是一个静态库。

但是,这是动态链接:

$ ldd a.out
        linux-vdso.so.1 =>  (0x00007fffde3c3000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb345820000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb345456000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fb345a3d000)

我错过了什么?

答案

GCC手册中的-l|--library选项的文档具有误导性,因为它没有在支持共享库的系统上指定选项的行为,或者警告我们它不会这样做。

-l选项传递给链接器,通常是GNU ld(或插件替代)。 ld manual中选项的文档是优越的,并且清楚地表明共享库将满足-l选项而不是静态库。

-l namespec

--library = namespec

将namespec指定的存档或目标文件添加到要链接的文件列表中。此选项可以使用任意次。如果namespec的格式为:filename,则ld将在库路径中搜索名为filename的文件,否则将搜索>库路径以查找名为libnamespec.a的文件。

在支持共享库的系统上,ld也可以搜索libnamespec.a以外的文件。具体来说,在ELF和SunOS系统上,在搜索名为libnamespec.a的库之前,ld将在目录中搜索名为libnamespec.so的库。 (按照惯例,.so扩展名表示共享库。)请注意,此行为不适用于:filename,它始终指定名为filename的文件。

链接器将仅在命令行上指定的位置搜索一次存档。如果存档定义了在命令行上存档之前出现的某个对象中未定义的符号,则链接器将包含存档中的相应文件。但是,稍后在命令行中出现的对象中的未定义符号将不会导致链接器再次搜索存档。

...

(我的重点)

以上是关于为什么gcc在使用-l时动态链接?的主要内容,如果未能解决你的问题,请参考以下文章

救命啊救命啊, 两种装载动态链接库的区别?

gcc/g++实战之动态链接库与静态链接库编写

LLINUX GCC 编译C使用自定义动态链接库.so的问题

gcc 编译使用动态链接库和静态链接库

如何在 AIX 中使用 GCC 编译器链接 *.so 文件

linux自己写的静态库gcc报错