getting compile-time date and time without macros

2019-02-14 08:40发布

using c++

I compile my code on an automated schedule and need to use the time at which the code was compiled in the code itself. Currently I'm just using the __DATE__, __TIME__ macros to get the compile- time date and time. However, this causes the binaries to change even if no changes have been made to the source (macros will inflate at compile time) which is not good (i don't want the setup to think that the binary changed if there have been no changes to the source).

Is it possible to get the compile-time without using any means that would cause the source to change?

Thanks

3条回答
虎瘦雄心在
2楼-- · 2019-02-14 08:46

If you use the compile-time IN YOUR binaries, then you will have the binary change.

There are several solutions, but I think the main point is that if you rebuild the binaries on a regular basis, it should really only be done if there are actually some changes (either to the build system or to the source code). So make it part of your build system to check if there are changes, and don't build anything if there isn't any changes. A simple way to do this is to check what the "latest version" in the version control system for the source code is. If the latest version is the same as the one used in the previous build, then nothing needs to be built. This will save you generating builds that are identical (apart from build time-stamp), and will resolve the issue of storgin __DATE__ and __TIME__ in the binary.

查看更多
看我几分像从前
3楼-- · 2019-02-14 08:55

The standard __DATE__ and __TIME__ macros do what you observe, return a time dependent string.

It depends upon the system (and perhaps the compiler) and notably the build system (like GNU make for example).

A possible idea could be to link in a seperate timestamp file, something like (in make syntax)

timestamp.c:
        date +'const char timestamp[]="%c";' > $@

program: $(OBJECTS) timestamp.c
        $(LINKER.cc) $^ -o $@ $(LIBES)
        rm -f timestamp.c

The timestamp.owould then be regenerated and your programwould be relinked at every make (so the generated program will indeed change, but most of the code -thru $(OBJECTS) make variable- will stay unchanged).


Alternatively, you could e.g. log inside some database or textual log file the time of linking, e.g.

program: $(OBJECTS)
      $(LINKER.cc) $^ -o $@ $(LIBES)
      date +'$@ built at %c' >> /var/log/build.log

(you might use logger instead of date to get that logged in the syslog)

Then the generated program won't change, but you'll have logged somewhere a build timestamp. BTW you could log also some checksum (e.g. $(shell md5sum program) in make syntax) of your binary program.

查看更多
混吃等死
4楼-- · 2019-02-14 08:57

It's not clear to me what you want. If it's the last modified time of the file, getting it will depend on your system and build system: something like -D $(shell ls -l --time-style=long-iso $< | awk '{ print $7, $8 }') could be used in the compiler invocation with GNU make under Linux, for example. But of course, it means that if an include file was changed, but not the source, the time and date wouldn't reflect it.

查看更多
登录 后发表回答