我的问题可以归纳如下:
小节c:
#include <stdio.h>
void bar() {
printf("bar\n");
}
主文件c:
#include <stdio.h>
void __attribute__((weak)) bar() {
printf("foo\n");
}
int main() {
bar();
return 0;
}
生成文件:
all:
gcc -c bar.c
ar -rc libbar.a bar.o
gcc main.c -L. -lbar
输出:
$ ./a.out
foo
因此,main. c中的弱符号栏不会被bar. c中的强符号覆盖,因为bar. c链接到静态库libbar. a中的main. c。
我怎样才能让gcc在libbar. a中使用强符号来覆盖main.c中的弱符号?
3条答案
按热度按时间xdyibdwo1#
我对max.haredoom给出的答案感到困惑(而且它被接受了),答案涉及共享库和动态链接,而问题显然是关于使用静态库的静态链接的行为,我认为这是误导。
链接静态库时,
ld
不关心弱/强符号默认情况下:它只是将未定义的符号解析为第一次遇到的符号(因此命令行中静态库的顺序很重要)。但是,可以使用
--whole-archive
选项更改此默认行为。如果您将Makefile中的最后一步重写为如下所示:然后你会看到:
简而言之,
--whole-archive
强制链接器扫描其所有符号(包括那些已经解析的符号),如果存在已经被弱符号解析的强符号(如我们的例子),则强符号将否决弱符号。也可以看到一篇关于静态库和它们的链接过程"Library order in static linking" by Eli Bendersky和this SO question的文章。
kfgdxczn2#
一般来说:如果你没有在
main
中实现一个弱的实现,那么链接器最终会在运行时解析它,但是如果你在main.c
中实现它,那么在链接这个静态变量时,你只能用一个强绑定(bar.c
)覆盖它。请阅读https://bottomupcs.com/ch09s05.html-它包含了很多关于这个主题的有趣的东西。
我自己做了个测试:
bar.c
baz.c
main.c
我的生成文件:
看一下main1 & main2 ......如果你没有把任何弱实现放到
main.c
中,而是把弱实现放在一个库中,把强实现放在另一个库中,那么如果强库定义了bar()
的强实现,你就可以覆盖弱实现。wpcxdonn3#
您应该将弱实现分离到另一个库中。
只在main中声明它。