使用 GCC 编译非必要的目标文件
Posted
技术标签:
【中文标题】使用 GCC 编译非必要的目标文件【英文标题】:Compiling nonessential object files with GCC 【发布时间】:2010-02-07 03:53:47 【问题描述】:考虑以下示例
g++ a.o b.o c.o -o prog
如果c.o
没有向prog
贡献任何可执行代码,并且在任何其他文件中也没有对c.o
的任何依赖,那么GCC 是否还会将c.o
的内容包含在prog
?
换句话说,除了编译时间之外,将不必要的文件编译成可执行文件会产生什么(如果有的话)负面后果?
提前致谢;干杯!
【问题讨论】:
您可以尝试使用和不使用额外库进行链接,看看可执行文件的大小是否相同。 我不了解 GCC,但无论您是否引用它们,MSVC 都会包含所有 .obj 文件的内容,但它只会包含您引用的 .lib 文件的部分。我希望 GCC 也一样 所描述的步骤通常称为“链接”。术语“编译”通常用于描述目标文件的生成。 【参考方案1】:除了您的可执行文件可能不必要地大之外,没有任何负面影响。链接器可能会为您删除未使用的代码,这会将事情缩小。您可以在输出可执行文件上使用某种对象查看工具(otool
、objdump
、nm
等)来查看您的程序中是否有额外的符号。
我使用的是 Mac,所以如果您使用的是标准的 gcc 工具集,会有一些差异,但这里有一个示例:
$ make
gcc -o app main.c file2.c
gcc -Wl,-dead_strip -o app_strip main.c file2.c
$ ls -l app*
-rwxr-xr-x 1 carl staff 8744 Feb 6 20:05 app
-rwxr-xr-x 1 carl staff 8704 Feb 6 20:05 app_strip
我认为在非 Apple gcc 世界中,您将通过 -Wl,--gc-sections
而不是我的示例中的 -Wl,-dead_strip
。您可以看到的两个可执行文件的大小差异是由于剥离了额外的功能:
$ nm app | cut -c 20- > app.txt
$ nm app_strip | cut -c 20- > app_strip.txt
$ diff app.txt app_strip.txt
8d7
< _function2
【讨论】:
【参考方案2】:llvm
可以消除链接步骤中的死代码。它使用特殊的链接器llvm-ld
。
此外,使用-fwhole
或-ipo
(英特尔)将有助于去除死符号。
【讨论】:
【参考方案3】:我只是用我目前正在使用的一些 C 代码尝试了它——我链接到一个对象,该对象包含一个(尚未)在程序中其他任何地方使用的方法。该代码包含在生成的可执行文件中,通过针对 elf 文件运行 nm
并观察方法 T 确实存在进行检查,即使使用了 -O2 和 -O3 也是如此。
【讨论】:
【参考方案4】:是的,GCC 将包括所有目标文件。使用最新的编译器(开发版本 4.5.0),您可以使用 -flto
(链接时优化)来执行此操作。
【讨论】:
以上是关于使用 GCC 编译非必要的目标文件的主要内容,如果未能解决你的问题,请参考以下文章