How can I force a particular 'compile/link timestamp' in OBJ/EXE/DLL files?

Posted on 2007-03-23
Medium Priority
Last Modified: 2013-12-04
Is there a way to control the 'time date stamp' which the Microsoft VC++ 6.0 compiler and linker put into object files and EXE/DLL files?

I have a relatively large project, comprising about 1000 source files, mostly JAVA and TEXT files, but a small number of Windows C/C++ sources.

The build process is automated using ANT, and produces jar files, war files and eventually exe files using NSIS.

I keep all the sources under version control using Subversion.

What I want to do is verify the MD5 checksum of the final build product, so I can have absolute confidence that a particular EXE was built from a particular set of checked out sources.

This mechanism works great for anything not using Microsoft tools.

For JAR and WAR files, all you have to do is TOUCH the individual components before packaging, (to force a predefined Build timestamp), and the MD5 of the JAR/WAR will be stable.

For NSIS EXE files, the same applies. If you TOUCH the component files, before running the .nsi script, the MD5 of the final product will be repeatable. The same is true for ZIP files and similar.

But for the Microsoft C++ source files, which are compiled using CL.EXE and linked using LINK.EXE, I cannot find how to force the compile timestamp and link timestamp to have a particular value.

Instead, the tools always use current time.

Microsoft embeds these timestamps into the COFF object and EXE/DLL files, so the object files are always slightly different on each build, and this makes the MD5 signature of the EXE/DLL (or any archive with such a file as a subcomponent) different.

This makes checking the resulting MD5 useless for confirming that a particular set of sources generates a particular release version of the deliverable.

Does anyone know how to get around this?

I was expecting some command line switch or environment variable settings or something like that which would cause the designated time to be used instead of current time.

The toolchain is Microsoft Visual Studio 6.0 Professional (the latest and greatest before .NET)

I have spent a lot of time experimenting in the past with workarounds, and getting really frustrated
each time.

I really would like to avoid having to keep copies of large binary files just to make my ZIP/WAR/NSIS files stable.

Question by:aswales
  • 3
  • 2
LVL 86

Expert Comment

ID: 18781432
Why don't you 'touch' (http://unxutils.sourceforge.net/) these also after they were built using a custom Post Build Command?
LVL 49

Expert Comment

ID: 18786892
It does ineed seem that the Linker puts a timesamp into the EXE header.  This google groups post

shows some code the poster used to obtain the "LinkTimestamp"  Perhaps you can use that as a starting point for writing code to modifying the EXE in a post-link step.
LVL 49

Expert Comment

ID: 18786903
A program here:
   Windows XP Service Pack 2 Support Tools

might be used to locate the exact position of the timestamp in the file, by comparing the results of two identical compiles.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 49

Accepted Solution

DanRollins earned 750 total points
ID: 18786911
In this KB article:
    How to compare binary images of the same project builds
Microsoft suggests:
>> Use the Microsoft Portable Executable and Common Object File Format
     Specification from the MSDN Library to alter the date/time stamps so
     that they won't be a factor in the comparison

Author Comment

ID: 18788033
Thanks for the confirmation.

I had experimented before by using the COFF spec and perfoming in-situ surgery on the timestamps. Worked fine at the OBJ level, but when I tried doing the same thing on the LINK output I hit another problem (sorry I forgot this bit)

It appears that LINK.EXE is unpredictable about which order it throws symbols and entry points into the output file.

I ran the same version of LINK.EXE, but different versions of the OS, on two different computers. One computer was running W2000SP4, the other running XP-SP2. (Actually I tried multiple computers, but it seemed the difference was OS-dependent).

When given exactly the same binary object files, library files, and command parameters, the binary output was different. Inspection using the appropriate MS tools showed that the differences were in entry point ordering.

This came as a big surprise. I suspected that LINK.EXE was using some external DLL routine for manipulating the entry point table, and the versions provided for XP and W2K were different (so much for thorough OS regression testing....)

And, of course, if I couldn't repeatably control the order of records in the output, then getting a signature such as MD5 to be consistent would be impossible.

What surprised me most about all of this was that I expected this type of operation to be routine. I would expect any program when given the same inputs to generate the same outputs. Otherwise the developers themselves would have a hard time doing reliable regression tests. It's an awful lot easier to check results for simple equality than to perform detailed analysis of the output by eye or program. To me, It's a very simple extension of unit testing philosophy.

Anyhow, I figured I must be missing something obvious, since any other professional organization releasing a product in EXE or DLL form would want a reliable way of confirming that their build process and toolchain generated accurate results. The term 'ISO-9001' came to mind.....

So there were two possibilities here. Either there was a way to force the Microsoft tools to do the job properly, or everyone else with the same interests as me chooses to bypass the MS tools and goes for some third party equivalent which does the right thing. But rather than hunt this down myself, I hoped this forum would help.

So the bottom line, I guess, is this:

If you have to verify that your delivered EXE/DLL product  can be repeatably rebuilt from a given set of sources and tools, but on different computers, how do you do it?

Thanks much

Author Comment

ID: 18792800
I realize my problems with LINK.EXE generating different results were likely 'DLL HELL', since the version of the library MSVCRT.DLL was different. Perhaps a hashing function was different or something like that, leading to the iteration order varying when the entry point table was dumped.

So since my original question was answered, I'll close it off


Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

569 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question