How to write a makefile that tags a library or an executable with a repository id?
I have code that generates an executable via a makefile. The 开发者_运维问答executable itself generates an output file with data. In the future, when I go back and look at old data that I've kept, I would like to be able to reproduce the data in a reliable and systematic way. In other words, I would need to know an ID number form a repository (GIT) so that I can recover the code, and I would also need to know how I compiled the code and what compiler and flags I used. What is the best way to go about this?
How do I accomplish the same as I've described above but with an old library instead of data, so that I can pick an old library, find out the repository ID number for the code that was used to generate it, and find out the Makefile info used to generate it?
There are many ways to do this; the choice of the best will depend on things like the flexibility of your source control system, and how much user mischief you want to guard against.
One possibility: I am not familiar with GIT, but I bet with some effort you could set up a system such that when you check out a version of the code and makefile, you also produce a small file containing the version number (or ID or whatever). With a little more effort you could write the version number into the makefile to guard against a lost/swapped version file (although this would be conceptually unhygienic, since the makefile would then not be identical to the one under source control). The executable would read the file and append the version number to the data. (Again, the number could be incorporated into the executable if you like, which would make the library a self-contained entity and guard against a swapped makefile/versionfile, but raise the hackles of your QA people.)
Another way: use checksums. The makefile calculates its own checksum and records it in a small file, which the executable uses/incorporates and appends to the data. The executable also calulates its own checksum (with caveats for compiler indeterminacies) and appends that too. A small database of checksums, easily constructed at need, acts as a lookup table for the index back into the repository.
This is straight forward. The trick is to not relink your library if the version has not changed.
.PHONY: version.proto
version.proto:
Run some commands
Which will produce version.proto
Containing something like 'char const Version[] = "MyProj svn rev 19228 tag (null)"
version.c: version.proto
cmp -s $< $@ || cp $< $@
∶
Include version.c
in the source-list of your project, and you are done.
What's all this cmp -s $< $@ || cp $< $@
? The trick is to only update version.c
if it differs from the last version compiled into your project. OTOH if it does not differ, then no error must be returned to the shell.
精彩评论