Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 关于GCC链接器搜索顺序的几个问题_Linux_Gcc_Linker_Shared Libraries_Static Libraries - Fatal编程技术网

Linux 关于GCC链接器搜索顺序的几个问题

Linux 关于GCC链接器搜索顺序的几个问题,linux,gcc,linker,shared-libraries,static-libraries,Linux,Gcc,Linker,Shared Libraries,Static Libraries,我有一些关于gcc链接顺序的问题。GCC人说链接器从左到右搜索符号,默认情况下不会重复搜索。这是我的测试: main.c #include <stdio.h> #include <stdlib.h> int main() { printf("HELLO WROLD\n"); return 0; } #包括 #包括 int main() { printf(“HELLO WROLD\n”); 返回0; } printf.c #includ

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

main.c

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

int main()
{
        printf("HELLO WROLD\n");
        return 0;
}
#包括
#包括
int main()
{
printf(“HELLO WROLD\n”);
返回0;
}
printf.c

#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
#包括
#包括
int printf(常量字符*fmt,…)
{
写入(1,“AAA\n”,4);
}
[root@lenovotestcode]#gcc-c-fno内置printf*.c
[root@lenovotestcode]#gcc-o test main.o printf.o
[root@lenovo测试代码]#/测试
AAA
[root@lenovotestcode]#gcc-o测试printf.o main.o
[root@lenovo测试代码]#/测试
AAA
[root@lenovotestcode]#ar rcs libprintf.a printf.o
[root@lenovotestcode]#gcc-o测试libprintf.a main.o
[root@lenovo测试代码]#/测试
你好,沃罗德
[root@lenovotestcode]#gcc-o test main.o libprintf.a
[root@lenovo测试代码]#/测试
AAA
[root@lenovotestcode]#gcc-shared-o libprintf.so printf.o
[root@lenovotestcode]#gcc-o test libprintf.so main.o
[root@lenovotestcode]#导出LD_库_路径=。
[root@lenovo测试代码]#/测试
AAA
[root@lenovotestcode]#gcc-o test main.o libprintf.so
[root@lenovo测试代码]#/测试
AAA

从结果中,我们可以看到.o和.o的顺序,.o和.a的顺序没有区别,只有.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
库再次被视为是在命令行末尾指定的。与静态库不同的是,
*从左到右的顺序。因此
库决定运行时动态符号搜索顺序。由于此顺序在隐式
libprintf.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
使用的
printf
版本,而不是
libprintf.so
,因为
-lc
按从左到右的顺序排在
libprintf.so
之前。

我使用了-v,但我仍然不明白为什么。你能详细解释一下吗?我不能使用-nodefaultlibs,因为crt中应该存在一些函数,比如_start;艾德博士以前也说过。您认为“it”与gcc amn页面在哪些方面不一致?顺序是.o和.o、.o和.so,这意味着它应该得到与.o和.a相同的结果。正如你从我的结果中看到的,它不是。编辑以添加对这些案例的解释。。。很抱歉,在最初的回复中忽略了这些内容。