如果你点击这个因为你认为这是不可能的,那么在我遇到它之前我会想到同样的事情。
我正在开发一个用C语言编写的PIC项目,它是用Makefile构建的。 Makefile非常混乱,所以我想清理它。为了确保在我做的时候我没有破坏任何东西,我记录了所有文件的哈希值,以及新的make :(此项目中没有子目录。使用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文件在每次编译之间都会发生变化。
是什么导致这种情况?
答案 0 :(得分:3)
即使代码严格相同,对象中的调试信息(符号,日期)也可以使对象发生变化。
为确保您没有任何更改,只需剥离对象:
strip *.o
比较对象/对它们执行校验和的最佳方法是在剥离的对象上,否则你永远无法确定。
(相同的技术可以应用于可执行文件)
注意:剥离对象后,您可以链接它们,但是您将很难进行调试。您可以在副本上进行(theobject.o
不变,然后):
strip theobject.o -o theobject_stripped.o
我们在交付前执行可执行文件的“正式生产”时使用该流程。
实际上我们反过来这样做:我们比较剥离的可执行文件,如果存在差异,我们比较剥离的对象以找到罪魁祸首并缩小范围。 然后我们在源上使用我们的版本控制系统来查找它发生变化的原因。
编辑:如果使用自定义的时间相关宏来定义目标文件中的日期(-DDATE=\"somedate\"
),则校验和过程将需要多个条带操作。从目标文件(或文件)中反向操作(删除日期/版本/等)必须使用自定义工具完成。
您可以从此功能中受益,并且通过仅在包含导出符号上的版本(Version.o
)的一个文件上应用宏来使大多数目标文件不受影响。
该文件的校验和将有所不同,但其他文件将是相同的(或者你的同事们对你毫无意义地使你很难)
编辑:对于SDCC,你有一个名为sdobjcopy
的类似工具,其界面看起来非常像objcopy
,并具有剥离对象的功能
sdobjcopy --strip-all theobject.o theobject_stripped.o
(如果--strip-debug
选项太“暴力”,还有一个--strip-all
选项。
检查sdobjcopy man page了解详情。