Is there a way to embed a (per translation unit) string into an optimized binary?
In our development environment, it is fairly simple to produce a build. It happens that customers sometimes end up with a custom build, and when they experience a problem with that build, it's difficult to figure out what code base that binary came from.
I'm attempting to find a reasonable strategy to be able to reconstruct the build environment when only a forensic analysis of the binaries is possible.
Embed version info into each translation unit
One idea I had was to embed version info into each cpp file. Something like
static const char *__FILEVERSIONINFO = __FILE__ "___$Revision$___Build:" PRODUCT_VER_STR;
and then add svn:keywords property to the file so that when the build was made, I could at least know what SVN revision the file was at. This wouldn't tell me if it had been modified from that revision, but it would at least enable me to get close.
The down side of this is that I cannot get these symbols into a Release build. Because they're not referenced, they get optimized away (and I want to keep that optimization as a global setting). I attempted to Force Symbol References (__FILEVERSIONINFO as the value for "Force Symbol References" in the linker settings), but the linker complained that it couldn't find the symbol.
error LNK2001: unresolved external symbol __FILEVERSIONINFO
dumpbin listed the symbol in the object file as
09E 00000004 SECT5 notype Static | ___FILEVERSIONINFO
but using this name in "Force Symbol References" didn't work either.
Microsoft's documentation doesn't actually give any examples of its use, and my google-fu didn't turn up anything pertinent.
I tried using a #pragma to force its export,
__pragma(comment (linker, "/export:__FILEVERSIONINFO"))
but got the same error from the linker. How do I specify the name of this symbol?
It would be convenient if I didn't have to randomize/uniquify the name of the symbol for each translation unit, but I don't know of the /INCLUDE argument to the linker is able to include all symbols with the same name.
I don't actually care if the symbol itself is accessible, I was just wanting to be able to suck the strings out of a binary and grep for "Revision" to see what revision the binary files were at/near at the time of the build.
Embed a report into the binary
It seems possible to construct a report (e.g. svn diff) and embed some form of that into the binary. This would have the advantage of encapsulating any uncommitted, source-level changes made to the files/project).
This seems a little tedious, but it could be done.
Other solutions?
Changing how the developers/support people do builds is not a feasible option for us. I'm looking for something I can do that will not depend on them reading more documentation and following procedural rules. I realize this is not ideal, but adding more human-driven policies just isn't worth the cost.
For all practical purposes that I forsee, I'm probably only going to use this information to look for problems in a specific revision of a source file, not actually attempt to patch a custom build.
Are there better ways to tag/mark binaries that will enable me to locate a close revision of the source file(s) in question for examination?
static? That has internal linkage.