首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于GCC链接器检索顺序的几个问题

关于GCC链接器检索顺序的几个问题
EN

Stack Overflow用户
提问于 2012-05-14 22:22:42
回答 1查看 794关注 0票数 5

我有几个关于gcc链接顺序的问题。GCC说,默认情况下,链接器从左到右搜索符号,不重复搜索。这是我的测试:

main.c

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int main()
{
        printf("HELLO WROLD\n");
        return 0;
}

printf.c

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int printf(const char *fmt, ...)
{
        write(1, "AAA\n", 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手册页不一致。那为什么呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-15 00:27:12

gcc确实是从左到右处理目标文件的。当你有了

代码语言:javascript
复制
gcc -o test libprintf.a main.o

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

同样,当你拥有:

代码语言:javascript
复制
gcc -o test main.o libprintf.a 

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

当链接到.o文件时:

代码语言:javascript
复制
gcc -o test main.o printf.o

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

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

代码语言:javascript
复制
gcc -o test libprintf.so  main.o
gcc -o test main.o libprintf.so

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

代码语言:javascript
复制
gcc -o test main.o -lc libprintf.so

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

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10585225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档