gcc输出的目标文件是否可以在相同源的编译与相同选项之间变化?

时间:2013-02-27 10:41:14

标签: c gcc code-generation

目标文件(C语言)的gcc输出在编译之间是否有所不同?没有特定于时间的信息,编译选项或源代码没有变化。链接库,环境变量也没有变化。这是一个VxWorks MIPS64交叉编译器,如果有帮助的话。我个人认为不应该改变。但我观察到有时随机,指令产生了变化。我不知道是什么原因。任何人都可以对此有所了解吗?

5 个答案:

答案 0 :(得分:1)

这是如何构建的?例如,如果我构建了相同的Linux内核,它包含一个计数器,每个构建都会递增。如果分析信息发生变化,GCC可以选择使用分析器信息来指导代码生成,代码也是如此。

你分析了什么?生成的程序集,目标文件或可执行文件的objdump?你是如何比较不同版本的?您是否确定您查看了可执行代码,而不是编译器/汇编程序/链接器时间戳?

环境有什么变化吗?新库(以及头文件/声明/宏定义!)?新编译器,链接器?新内核(是的,一些头文件源自内核源并附带它)?

环境变量的任何变化(另一个进行编译的用户,不同的机器,与网络的不同连接提供了一个不同的IP地址,使其进入构建)?

我会尝试详细跟踪构建过程(运行构建并在文件中捕获输出,然后再次执行;比较那些)。

完全神秘......

答案 1 :(得分:1)

我遇到了与g ++类似的问题。 Pre 4.3版本每次都生成完全相同的目标文件。对于4.3(及更高版本?),一些受损的符号名称对于每次运行都是不同的 - 即使没有-g或其他记录。也许使用时间戳或随机数(我希望不是)。显然,这些符号中的一些符号会进入.o符号表,你就会有所不同。 剥离目标文件使它们再次相等(wrt。二进制比较)。 g ++ -c file.C; strip file.o; cmp file.o origfile.o

答案 2 :(得分:0)

为什么会有所不同?始终是同样的结果。试试这个:

for i in `seq 1000`; do gcc 1.c; md5sum a.out; done | sort | uniq | wc -l

答案总是1。替换1.ca.out以满足您的需求。

以上计算gcc1000次编译相同来源时生成的可执行文件的数量。

答案 3 :(得分:0)

我发现,如果后续构建的源树位于不同的目录中,至少在某些环境中,相同的源可能会产生不同的可执行文件。例如:

将项目的原始副本签出到dir1。从头开始进行完全重建。

然后,在同一台计算机上使用相同的用户,将源代码的完全相同的副本签出到dir2(dir1!= dir2)。从头开始做另一次完全重建。

这些版本相隔几分钟,工具链或任何第三方库或代码都没有变化。源代码的二进制比较是一样的。但是,dir1中的可执行文件与dir2中的可执行文件具有不同的md5sum。

如果我比较BeyondCompare的十六进制编辑器中的不同可执行文件,差异不仅仅是一些可能是时间戳的小部分。

如果我在dir1中构建,我获取相同的可执行文件,然后在dir1中再次重建。如果我继续在dir2上反复构建相同的源,那就相同。

我唯一的猜测是包含层次结构的某种绝对路径嵌入在可执行文件中。

答案 4 :(得分:-1)

我的gcc有时会为完全相同的输入生成不同的代码。输出对象文件只有一个字节不同。

有时这会导致链接器错误,因为一个可能的目标文件无效。重新编译另一个版本通常会修复链接器错误。

Suse Linux Enterprise上的gcc版本是4.3.4。 gcc参数是:

cc -std=c++0x -Wall -fno-builtin -march=native -g -I<path1> -I<path2> -I<path3> -o obj/file.o -c file.cpp

如果有人遇到同样的效果,请告诉我。