`ar`库覆盖时间戳

.a归档格式标题需要一个时间戳。 当我重build一个静态库时,这导致了无数的头痛,主要是因为我不能完全复制原始的二进制文件。

例如(这是在我的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 

为了向我自己certificate,唯一的区别是时间,我根据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 

如果您使用标题格式取消parsing,则对应于时间字段。

联机帮助页不显示是否可以覆盖标题中的时间戳。 有什么想法吗?

编辑:是的,有可能回去和物理hack文件使用任意的时间戳。 是的,有可能改变程序的行为。 考虑到这种情况,并不是所有的情况都是严格的技术性的,手工改变时间戳的工具是不可接受的,也不是一个修改后的版本,也不会影响实际的系统时间。

编辑:在这种情况下,我必须certificate,没有任何不可接受的偏离构buildpath,二进制文件可以从源生产。 在一些行业(如金融),这显然是一个标准的做法。 用于更改时间戳的手动工具是不可接受的(因为使用了不在原始构buildpath中的特殊工具)。 ar的手卷版本是不可接受的(类似的问题)。 改变系统时钟的问题是构build必须完美协调(这是一个长达一个小时的构build,有很多库和二进制文件)。 可接受的解决scheme包括:

  • 标志AR或其他程序,可以重写库中的时间戳
  • 一个现有的(年龄> 1年)工具来做到这一点
  • 标志GCC可以覆盖来自ar的时间戳做链接

如果二进制文件的其余部分总是完全一样的话,那么你可以在.a文件中定位时间戳,并用一个固定的值覆盖它(就像所有的零)。

在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会把时间戳放回去。

使用dd会让你覆盖你想要的文件的一部分:

 dd if=libfoo.a1 of=libfoo.a skip=30 seek=30 count=4 bs=1 conv=notrunc 

当然,这意味着你需要你的时间戳到别的地方(你可以有一个非常基本的c程序,它取得当前时间,并输出它在小端或大端,然后用dd你可以覆盖库文件)。 使用dd,我可以覆盖.a文件,并得到没有差异的结果

默认的答案是“不能用ar工具完成”