【发布时间】:2016-09-23 18:58:11
【问题描述】:
如果您因为认为这不可能而点击它,那么在遇到它之前我也是这么想的。
我正在做一个项目,用 C 语言为 PIC 编写,它是用 Makefile 构建的。 Makefile 非常杂乱无章,所以我想清理它。为了确保在执行此操作时没有破坏任何内容,我在新制作后记录了所有文件的哈希值:(此项目中没有子目录。使用 SDCC 和 GPUTILS 构建。)
make clean
make
md5sum ./* > ../allsums.txt
然后我修改了 Makefile 并再次尝试,这次将生成的文件与 allsums.txt 进行比较。
make clean
vim Makefile
make
md5sum -c ../allsums.txt
有趣的是,.o 文件的哈希值不匹配,但最终结果匹配。假设问题是我以某种方式造成的,我花了很多时间试图找出它。
然后,凭直觉,我使用原始 Makefile 进行了此操作:
make clean
make
md5sum ./* > ../allsums.txt
make clean
make
md5sum -c ../allsums.txt
我发现这里的目标文件也发生了变化!一些搜索将我带到this question,它确认(至少对于 gcc).o 文件在每次编译之间都会发生变化。
是什么原因造成的?
【问题讨论】:
-
不,
gcc将创建相同的文件(即匹配),除非构建更改了某些内容。如果源文件有类似 (char build_time[] = DATE) 的东西,其中有一个编译参数-DDATE="`date`",那可能会改变事情。 -
理解/解决此问题的更好方法是获取每个文件的十六进制转储(使用
od或xxd)和diff以查看哪些部分发生了变化。然后,您可以向后工作以查看给定.o部分中的哪个偏移量发生了变化。然后,将其与特定符号相关联。然后,在.h或.c文件中查找符号的定义。另外,长度一样吗? -
将特定于构建的信息嵌入到对象和可执行文件中并不少见。例如,PE 头包含一个由链接器填充的时间戳字段(PE 是 Windows 上的可执行文件和 DLL 格式)。