加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 关于GCC链接器搜索顺序的一些问题

发布时间:2020-12-14 01:07:21 所属栏目:Linux 来源:网络整理
导读:我对 gcc链接顺序有一些疑问. GCC man表示链接器从左到右搜索符号,默认情况下不重复搜索.这是我的测试: main.c中 #include stdio.h#include stdlib.hint main(){ printf("HELLO WROLDn"); return 0;} printf.c #include stdio.h#include stdlib.hint print
我对 gcc链接顺序有一些疑问. GCC man表示链接器从左到右搜索符号,默认情况下不重复搜索.这是我的测试:

main.c中

#include <stdio.h>
#include <stdlib.h>

int main()
{
        printf("HELLO WROLDn");
        return 0;
}

printf.c

#include <stdio.h>
#include <stdlib.h>

int printf(const char *fmt,...)
{
        write(1,"AAAn",4);
}

[root@lenovo testcode]# gcc -c -fno-builtin-printf *.c
[root@lenovo testcode]# gcc -o test main.o printf.o
[root@lenovo testcode]# ./test 
AAA
[root@lenovo testcode]# gcc -o test printf.o main.o
[root@lenovo testcode]# ./test
AAA


[root@lenovo testcode]# ar rcs libprintf.a printf.o
[root@lenovo testcode]# gcc -o test libprintf.a main.o
[root@lenovo testcode]# ./test 
HELLO WROLD
[root@lenovo testcode]# gcc -o test main.o libprintf.a 
[root@lenovo testcode]# ./test 
AAA


[root@lenovo testcode]# gcc -shared -o libprintf.so printf.o 
[root@lenovo testcode]# gcc -o test libprintf.so  main.o 
[root@lenovo testcode]# export LD_LIBRARY_PATH=.
[root@lenovo testcode]# ./test 
AAA
[root@lenovo testcode]# gcc -o test main.o libprintf.so 
[root@lenovo testcode]# ./test 
AAA

从结果中,我们可以看到.o和.o,.o和.so的顺序没有区别,只有.o和.a的顺序才有效.但这与gcc手册页不一致.所以为什么?

解决方法

gcc确实从左到右处理目标文件.当你有

gcc -o test libprintf.a main.o

gcc看到的第一个目标文件是libprintf.a.此时输出对象没有未解析的符号,因此使用/需要libprintf.a中的任何内容.接下来,处理main.o,链接器记录了printf未解析的事实,然后继续处理隐式库,它可以解析main.o中未解析的printf符号.

同样,当你有:

gcc -o test main.o libprintf.a

要处理的第一个目标文件是main.o,其中记录了未解析的符号printf,下一个要处理的目标文件是libprintf.a,链接器可以从中解析printf.最终处理libc时,printf已经解析,因此不使用libc中的printf实例.

与.o文件链接时:

gcc -o test main.o printf.o

再次将libc库视为在命令行末尾指定,因此printf符号从定义它的第一个(从左到右)目标文件中解析.

对于这两个libprintf.so情况,libc库再次被视为在命令行末尾指定了它.与静态库情况的不同之处在于* .so库的从左到右排序决定了运行时动态符号搜索顺序.由于此命令在隐式libc.so之前具有libprintf.so,因此使用libprintf.so中的printf版本.

gcc -o test libprintf.so  main.o
gcc -o test main.o libprintf.so

作为额外的实验,您可以尝试:

gcc -o test main.o -lc libprintf.so

这应该显示从libc.so而不是libprintf.so使用的printf的版本,因为-lc以从左到右的顺序出现在libprintf.so之前.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读