gcc在静态库中链接未解析符号的顺序是什么? [英] What's the order for gcc to link unresolved symbol in static library
问题描述
当调试函数符号冲突问题时,我发现了一个奇怪的gcc行为,我无法理解,通过以下示例代码说明:
main.c
#include< stdio.h>
int main()
{
b();
a();
$ / code>
ac
#include< stdio.h>
void a(void)
{
printf(func a in a \\\
);
bc
#include< stdio.h>
void a()
{
printf(func a in b\\\
);
void b()
{
printf(func b try to call a \\\
);
a();
}
汇编:
gcc -c ac
gcc -c bc
ar -cr liba.a ao
ar -cr libb.a bo
gcc main .c liba.a libb.a
执行:
./ a.out
func b尝试调用
func a中的b
func a中的b
我的问题是:
- 为什么在
main
函数中调用函数a
是a in bc a in ac
? - 更改库命令后:
gcc main.c libb.a liba。一个
,结果是一样的。为什么? - 为什么在这种情况下链接器不报告符号冲突? 解决方案解决方案
$ b在对象文件中按照对象文件的外观顺序从左到右搜索要解析的符号。 $ b
假设已准备好以下链接:
gcc -c main.c
gcc -c ac
gcc -c bc
ar -cr liba.a ao
ar -cr libb.a bo
然后这个
gcc -o main main.o liba.a libb .a
会产生:
<$ p $ (ao):
bc :(。text + 0x0):多重定义'a'
liba.a(bo):在函数`a' :ac :(。text + 0x0):首先在这里定义
collect2:ld返回1退出状态
main.o
需要 a()
和 b()
。首先搜索 liba
:找到 a()
, b()
不是。所以其次搜索 libb
。找到 b()
,但也会导致链接器错误另一个 a()
如上所示。
如果这样做:
gcc -o main main main .o libb.a liba.a
没有错误,
链接器执行以下操作:
main.o
需要 a()
和 b()
。先搜索 libb
: a()
和 b()
被发现。由于没有任何东西可以解决,所以甚至没有人去查看/发现 libb
liba
in。
在后一种情况下,程序( main
)的输出为:
func b尝试调用
func a中的b
func a中的b
链接器将为/ c显示所有其他可能的排列 main .o
, liba.a
和 libb.a
留作练习读者。 ;-)
When debug the function symbols conflicts problem, I find a strange behavior of gcc i couldn't understand, illustrate by the following sample code:
main.c
#include <stdio.h>
int main()
{
b();
a();
}
a.c
#include <stdio.h>
void a(void)
{
printf("func a in a\n");
}
b.c
#include <stdio.h>
void a()
{
printf("func a in b\n");
}
void b()
{
printf( "func b try to call a \n");
a();
}
compile:
gcc -c a.c
gcc -c b.c
ar -cr liba.a a.o
ar -cr libb.a b.o
gcc main.c liba.a libb.a
execute:
./a.out
func b try to call a
func a in b
func a in b
My question is :
- Why calling function
a
inmain
function isa in b.c
instead ofa in a.c
? - After change the library order:
gcc main.c libb.a liba.a
, the result is the same. Why? - Why the linker don't report symbol conflict in this situation?
Object files are searched for symbols to be resolved in the order of the object files' appearances, left to right, in the options passed to the linker.
Assumed the following had been run in preparation to linking:
gcc -c main.c
gcc -c a.c
gcc -c b.c
ar -cr liba.a a.o
ar -cr libb.a b.o
Then this
gcc -o main main.o liba.a libb.a
would produce:
libb.a(b.o): In function `a':
b.c:(.text+0x0): multiple definition of `a'
liba.a(a.o):a.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status
The linker did the following:
main.o
needs a()
and b ()
. First liba
is searched: a()
is found, b()
isn't. So secondly libb
is searched. b()
is found, but also another a()
leading to the linker error shown above.
If doing:
gcc -o main main.o libb.a liba.a
No errors are given and main
is created.
The linker did the following:
main.o
needs a()
and b ()
. First libb
is searched: a()
and b()
are is found. As there is nothing to resolve any more libb
liba
isn't even looked at/in.
In the latter case the program's (main
's) output is:
func b try to call a
func a in b
func a in b
What the linker would do/show for all other possible permutation of main.o
, liba.a
and libb.a
is left as an exercise to the reader. ;-)
这篇关于gcc在静态库中链接未解析符号的顺序是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!