例如(这是在我的Mac上,但在x64 linux中也是如此):
$ cat foo.h
int foo();
$ cat foo.c
#include "foo.h"
int foo() { return 3; }
$ gcc -fno-pic -m64 -arch x86_64 -I/usr/local/include -O3 -c foo.c -o foo.o -fpic
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 0d0e6606185de4e994c47f4a0e54c1c4
$ mv libfoo.a libfoo.a1
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 22a69d42e1325ae8f978c2a18a4886da
为了向自己证明唯一的区别是时间,我采用了基于hexdump的差异:
$ diff <(hexdump libfoo.a) <(hexdump libfoo.a1)
2,3c2,3
< 0000010 20 20 20 20 20 20 20 20 31 33 31 31 30 34 33 30
< 0000020 38 36 20 20 35 30 31 20 20 20 32 30 20 20 20 20
---
> 0000010 20 20 20 20 20 20 20 20 31 33 31 31 30 34 32 38
> 0000020 37 31 20 20 35 30 31 20 20 20 32 30 20 20 20 20
,如果使用标题格式进行后向解析,则对应于时间字段。
Manpage未指示是否可以覆盖标头中的时间戳。有什么想法吗?
编辑:是的,可以返回并物理破解文件以使用任意时间戳。是的,可以改变程序的行为。考虑到情况的情况,并非所有情况都是严格技术性的,手动更改时间戳的工具是不可接受的,也不是ar
的修改版本,也不会弄乱实际的系统时间。 / p>
编辑:在这种情况下,我必须证明,在没有任何不可接受的构建路径偏离的情况下,二进制文件可以从源代码生成。在某些行业(例如金融业),这显然是一种标准做法。用于更改时间戳的手动工具是不可接受的(因为使用了一个不在原始构建路径中的特殊工具)。 ar
的手动版本是不可接受的(类似问题)。改变系统时钟的问题在于构建必须完美协调(这是一个长达一小时的构建,有很多库和二进制文件)。可接受的解决方案包括:
答案 0 :(得分:17)
在ar中使用“确定性模式”。有关手册中的ar,请参阅选项“D”。
me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be libfoo.a
me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be libfoo.a
如果您之后使用ranlib
,请确保使用ranlib -D
;否则ranlib
会将时间戳恢复。
答案 1 :(得分:5)
使用dd可以覆盖所需文件的一部分:
dd if=libfoo.a1 of=libfoo.a skip=30 seek=30 count=4 bs=1 conv=notrunc
当然这意味着你需要你的时间戳在其他地方(你可以有一个非常基本的c程序,它需要当前时间并以小端或大端输出,然后用dd你可以覆盖库文件) 。使用dd,我可以覆盖.a文件并获得没有差异结果
答案 2 :(得分:0)
如果二进制文件的其余部分始终完全相同,那么您可以在.a
文件中找到时间戳并用固定值覆盖它(如全零)。
答案 3 :(得分:-2)
默认答案是“ar工具无法完成”