gcc - 为什么我的二进制文件比我的目标文件小得多?

标签 gcc compilation linker elf

我正在使用 GCC 4.7 编译一个仅包含一个 C++ 源文件的大型应用程序,因此只有一个编译单元,但它包含许多长 header 。最终优化后的可执行文件 myapp 为 40MB,但优化后的目标文件 myapp.o 为 101MB。目标文件怎么可能比二进制文件大?

我运行“nm -AC myapp”和“nm -AC myapp.o”来查看一个符号是否比另一个符号多得多——大约有 1000 个符号差异,但它们大多是你所期望的二进制文件添加用于标准异常处理和静态初始化的符号。

然后我在两者上都运行了“readelf -a”并为 myapp.o 得到了这个:

Number of section headers:         29186
Section header string table index: 29183

但这对于我的应用程序:

Number of section headers:         40
Section header string table index: 37

所以我猜这是大小差异的原因,但我实际上并不知道这意味着什么,也不知道如何缩小大小。我是不是找错树了?我的目标是缩短 myapp 的编译时间,但首先我需要了解哪里出了问题。如果符号是问题所在,我可以考虑使用 GCC 的 -fvisibility=hidden 选项,但如果那是问题所在,我预计 nm 会有更多差异。

编辑:附加信息,我的源文件中未定义的所有内容均来自动态链接库。

最佳答案

目标文件包含大量额外信息,以允许将单独的文件链接在一起。此外,一旦项目中的所有目标文件链接在一起,许多代码可能会被优化掉。 (例如,目标文件中可能包含未调用的库例程,但一旦编译器知道最终二进制文件中实际使用了哪些例程,就不需要了。

关于gcc - 为什么我的二进制文件比我的目标文件小得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12013800/

相关文章:

c - Bare-Metal C : Why are some IDEs startup files doing things crt0. s 无论如何都会处理?

clang - 糟糕的 rand() 实现

c - LNK1120、LNK2001、LNK2019 - 无法追踪原因

c++ - 如何将 C++ 目标文件与 ld 链接

linux - 使用调试符号从源代码编译 glibc

gcc/g++ 参数顺序

c++ - CRTP 的模糊过载

c# - 使用 .net 为 x64 显式编译是否有意义?

c++ - 使用 JACK API 编译源失败

c - 什么是多重编译,它是如何工作的,我为什么要使用它?