Motivation
It’s sometimes useful to see precise date and time an application was compiled. So such information should be embedded into application at compile time and displayed on user’s request.
Initial solution
Usage of such timestamps is quite straightforward. There are two standard
macros that are generally used for this, namely __DATE__
and __TIME__
(see
Standard Predefined Macros). As first try I just
wrote the following piece of code:
list[x++] = strdup("Compiled at: " __DATE__ " " __TIME__);
It displayed message of this form:
Compiled at: Jan 18 2014 14:07:23
The issue is that when the file with this code (version.c
) is not compiled
output of an application never changes (quite obvious…). So that simple code
isn’t enough and build process should satisfy a couple of requirements:
version.c
should be recompiled if any other file is compiled.version.c
should be recompiled if application is relinked.version.c
should not be recompiled if application is not relinked.
Working solution
Adding various fake targets into Makefile.am
didn’t work out great. Search
on the Web didn’t get much good results, but eventually this post
on one of mailing lists helped to do the thing correctly. Here’s a quote from
it:
One way which should work with any make is to have the object in question depend on all source files even though the action only refers to one of them.
In a Makefile.am
it looks like this:
version.o: $(filter-out version.o, $(app_OBJECTS))
Note filtering out version.o
from its list of dependencies to avoid creating
of circular dependency, in which case make
prints warning about dropped
circular dependency.
And here is how it satisfies requirements outlined above. The first
requirement holds as recompilation of any of object files will update
modification date of appropriate .o
-file, thus triggering version.o
compilation rule.
The second requirement also holds simply because list of dependencies for the
link target is almost the same as for version.o
target (it additionally
includes version.o
). Thanks to topological sorting make will recompile
version.o
before linking the application, which is what we need.
Finally, the third requirement works for the same reason as the second one.
When all files (including output executable) are up to date, none of
version.o
prerequisites is newer it, hence version.o
not recompiled, no
need to relink anything.