the .a archive format header requires a timestamp. This has led to countless headaches when I rebuild a static library, mainly because I can't exactly reproduce the original binary.
For example (this is on my Mac, but the same thing happens in 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
To prove to myself that the only difference was time, I took a diff based on 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
which, if you backsolve using the header format, corresponds to the time field.
Manpage gives no indication of whether or not it is possible to override the timestamp from the header. Any thoughts?
Edit: yes, it is possible to go back and physically hack the file to use an arbitrary timestamp. yes, it is possible to change the program's behavior. Given the circumstances surrounding the situation, not all of which are strictly technical in nature, a tool to manually change the timestamp is not acceptable, nor is a modified version of ar
, nor is messing with the actual system time.
Edit: In this circumstance, I have to prove that, without any unacceptable deviation from the build path, the binaries can be produced from source. In some industries (e.g. finance) this is apparently a standard practice. A handrolled tool to change the timestamps is unacceptable (because a special tool, which was not in the original build path, was used). A handrolled version of ar
is unacceptable (similar problem). The problem with changing system clock is that the build would have to be perfectly coordinated (it is an hour-long build with a lot of libraries and binaries). Acceptable solutions include:
- flags to AR or other programs that could override the timestamp in the library
- an existing (age > 1 year) tool to do this
- flags to GCC that could override the timestamp coming from ar when doing the linking
.a
file and override it with a fixed value (like all zeroes). – Sacristanar
option that does what you need and you've ruled out both editing the.a
file and building your own special purpose tool; this boils it down to a simple question of whether you can read a man page or not and you clearly can. The tool doesn't do what you need it to do and you can neither use a different tool or modify the existing tool, where is the question? – Privatestrings
on the binary. Second, your approach breaks with C++ and anonymous namespaces, since the compiler generates a new name for the anonymous namespace on every compile. – Mcalpin