GNU ld 在使用静态库时生成不带符号的 ELF

GNU ld produces ELF with no symbols when static library is used

我正在尝试将多个目标文件打包到 ar 存档中,然后将存档传递给链接器。

我的 C 源文件 foo.c 包含这一行:

void foo();

使用gcc -c foo.c编译时,生成的目标文件包含此符号:

$ nm foo.o
0000000000000000 T foo

那我存档:

$ ar rcs foo.a foo.o

存档现在包含具有相同符号的文件 foo.o

$ nm foo.a
foo.o:
0000000000000000 T foo

但是链接的 ELF 不包含名为 foo:

的符号
$ ld foo.a
$ nm a.out
0000000000401000 A __bss_start
0000000000401000 A _edata
0000000000401000 A _end
                 U _start

为什么没有?

我想使用这种方法,因为我正在生成多个可执行文件变体,其中一个公共部分(一个存档,为简单起见未显示)和第二部分包含 main 符号([=21 中的目标文件=]).

使用ld标志--whole-archive:

$ ld --whole-archive foo.a

静态库通常链接如下。当链接器看到一个静态库时,它会获取到目前为止未解析的符号集,并在库中查找每个这样的符号。只有解析这些符号的对象才会包含在最终的二进制文件中。

要覆盖此行为,gnu ld 有一个开关 --whole-archive。来自手册页:

For each archive mentioned on the command line after the --whole-archive option, include every object file in the archive in the link, rather than searching the archive for the required object files. This is normally used to turn an archive file into a shared library, forcing every object to be included in the resulting shared library.