6

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

4

5 回答 5

1

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

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

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

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

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

完全迷惑了……

于 2013-02-27T17:22:52.000 回答
1

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

于 2013-05-09T19:34:19.683 回答
0

为什么要有所不同?总是相同的结果。尝试这个:

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

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

gcc上面计算了在多次编译相同源时生成了多少不同的可执行文件1000

于 2013-02-27T10:42:58.050 回答
0

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

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

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

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

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

如果我在 dir1 中构建,我得到相同的可执行文件,然后在 dir1 中再次重建。如果我从 dir2 一遍又一遍地构建相同的源代码,也是一样的。

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

于 2016-10-06T01:18:27.470 回答
-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

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

于 2015-09-02T08:07:24.133 回答