Linker 在使用--整个存档ld选项后,大大减小了大小

Linker 在使用--整个存档ld选项后,大大减小了大小,linker,ld,Linker,Ld,ld说 --全部档案 对于命令行中在 --“整个存档”选项,在链接中包含存档中的每个对象文件,而不是在存档中搜索所需对象 文件夹。这通常用于将存档文件转换为共享文件 库,强制将每个对象包含在结果共享 图书馆此选项可多次使用 我编写了一个玩具程序,并将其与GNUgmp库(libgmp.a)静态链接。令人惊讶的是,libgmp.a的大小是1.2MB,而生成的可执行文件的大小是526KB。使用ar-x提取.a存档将生成457对象文件。根据文档,如果所有这些都是链接的,而不考虑使用情况,那么为什么链接后

ld

--全部档案

对于命令行中在 --“整个存档”选项,在链接中包含存档中的每个对象文件,而不是在存档中搜索所需对象 文件夹。这通常用于将存档文件转换为共享文件 库,强制将每个对象包含在结果共享 图书馆此选项可多次使用


我编写了一个玩具程序,并将其与GNU
gmp
库(
libgmp.a
)静态链接。令人惊讶的是,
libgmp.a
的大小是
1.2MB
,而生成的可执行文件的大小是
526KB
。使用
ar-x
提取
.a
存档将生成
457
对象文件。根据文档,如果所有这些都是链接的,而不考虑使用情况,那么为什么链接后的大小几乎减少了
50%
?是否有任何方法可以确认所有的对象文件是否都链接到了可执行文件中?

我很好奇,所以我自己尝试了

我将一个空的
main()
扔进一个源文件,编译它,并根据
libm.a
链接,指定了
--整个归档文件。然后,我从
libm.a
中提取了所有对象文件,并将它们链接起来

我在两个可执行文件上都使用了
nm
,去掉了符号名,并
diff
删除了输出。它是相同的,两个可执行文件都有2003个符号

我还从
libm.a
本身提取了符号名,并将它们与可执行文件中的符号名进行了比较。再一次,它们没有区别(当然,除了可执行文件中的C运行时符号)

因此,我认为可以肯定地说,
——整个归档文件
的工作原理与广告完全一样


至于大小上的巨大差异,很可能是因为对象文件是成熟的ELF二进制文件。它们塞满了信息(比如ELF头文件),而这些信息并没有进入最终的可执行文件。

确切地说,这是我能想到的唯一可行的解释。