使用GCC编译非必要的目标文件

时间:2010-02-07 03:53:47

标签: c++ gcc linker compilation

考虑以下示例

g++ a.o b.o c.o -o prog

如果c.o没有向prog提供任何可执行代码,在任何其他文件中对c.o没有依赖关系,那么GCC是否还包括c.o中的prog内容?

换句话说,除了编译时间之外,还有什么(如果有的话)将不必要的文件编译成可执行文件的负面后果?

提前致谢;干杯!

4 个答案:

答案 0 :(得分:5)

除了您的可执行文件可能不必要地大,否则没有任何负面后果。链接器可能会为您删除未使用的代码,这会缩减内容。您可以在输出可执行文件上使用某种对象查看工具(otoolobjdumpnm等),以查看您的程序中是否包含额外符号。

我正在使用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

答案 1 :(得分:3)

llvm可以消除链接步骤中的死代码。它使用特殊链接器llvm-ld

此外,使用-fwhole-ipo(英特尔)将有助于消除死亡符号。

答案 2 :(得分:2)

我刚试了一些我正在使用的C代码 - 我在一个对象中链接,该对象包含一个尚未在程序中的任何其他位置使用的方法。代码包含在生成的可执行文件中,通过对elf文件运行nm进行检查,并观察方法T确实存在,即使使用-O2和-O3也是如此。

答案 3 :(得分:1)

是的,GCC将包含所有目标文件。使用最新的编译器(开发版本4.5.0),您可以使用-flto(链接时优化)来执行此操作。

相关问题