如何编译相同的源代码生成不同的目标文件?

经过长时间的debugging,我的问题已经缩小到一个文件。 而问题在于,当其他所有内容相同时,文件在两个不同的目录中编译方式不同。

我使用CodeSourcery的arm gcc编译器(gcc版本4.3.3,Sourcery G ++ Lite 2009q1-161)来编译一个简单的文件。 我在一个没有问题的模块中使用它,然后将其复制到另一个模块以在那里使用。 编译时,目标文件显着不同。 编译这两个文件的命令行是相同的(我使用linux历史logging来确认),并且这3个包含文件也是相同的副本(使用diff进行检查)。

我在两个目标文件上做了一个二进制比较,它们有很多独立的字节差异。 我做了一个objdump -D,并且比较了它们,并且有很多不同之处。 这里是dump1 , dump2和diff 。 命令行是“arm-none-eabi-gcc -std = gnu99 -Wall -O3 -g3 -ggdb -Wextra -Wno-unused -c crc.c -o crc.o”。

这怎么可能? 我也用-S编译而不是-c编译器,看看汇编程序的输出,除了目录path外,它们是一样的。 那么目标文件又如何呢?

我真正的问题是,当我尝试将dump2的目标文件链接到我的程序中时,我得到未定义的引用错误,所以对象中的某些内容是错误的,而dump1的对象没有得到这样的错误并链接正常。

对于大规模的软件,有很多实现正在做指针的散列。 这是导致结果随机化的一个主要原因。 通常如果程序逻辑是正确的,一些内部数据结构的顺序可能是不同的,在大多数情况下是无害的。

另外,不要比较'objdump -D'输出,因为你正在编译来自不同目录的代码,字符串表,符号表,DWARF或eh_frame应该是不同的。 你一定会得到很多的差异线。

唯一有意义的比较是比较只处理文本部分的'objdump -d'的输出。 如果文本部分相同(类似),则可以认为是相同的。

您的文件很可能会挑选不同的包含文件。 这是最可能的原因。

检查包含路径是否完全相同,包含语句中的路径。 他们可能会指向不同的目录。 C和C ++有一个特性,当你#include abcd.h它会尝试从调用文件的目录加载abcd.h 检查这个。