目标文件(C语言)的gcc输出在编译之间是否有所不同?没有特定于时间的信息,编译选项或源代码没有变化。链接库,环境变量也没有变化。这是一个VxWorks MIPS64交叉编译器,如果有帮助的话。我个人认为不应该改变。但我观察到有时随机,指令产生了变化。我不知道是什么原因。任何人都可以对此有所了解吗?
答案 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.c
和a.out
以满足您的需求。
以上计算gcc
在1000
次编译相同来源时生成的可执行文件的数量。
答案 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
如果有人遇到同样的效果,请告诉我。