I want to use cmake to set VERSION to a release version in case of release builds and to the compile time otherwise.
When using make for development builds, obtaining the compile time was easy via
-DVERSION=`date +%Y-%m-%d_%H:%M`
which could be used straight forward by c/c++ source code. Unfortunately, I haven't found out how the same can be achieved when using cmake.
string(TIMESTAMP VERSION "%Y-%m-%d %H:%M")
add_definitions(-DVERSION="${VERSION}")
sets VERSION to the time cmake was executed. How can I set VERSION to the compile time when using cmake (to avoid having to fiddle with __DATE__
and __TIME__
in the absence of a RELEASE flag)?
I end up with the following solution:
Binary target
${PROJECT_NAME}
linked every time with updated section.Qt code to get this timestamp:
My cross-platform solution on the first run of CMake creates a file
timestamp.cmake
in the binary directory and defines a targettimestamp
which runs the generated file. The filetimestamp.cmake
forms an ISO 8601 time stamp string using theSTRING
CMake command and writes it to a filetimestamp.h
with a#define _TIMEZ_
preprocessor directive prepended (defines with one leading underscore are okay; defines with two leading underscores should not be user-defined).Include the following in your main CMake file.
Then use the
ADD_DEPENDENCIES
CMake command to make your main target (probably the main executable file) dependent on thetimestamp
target. It is always considered out-of-date by CMake, so it is being refreshed every time the main target rebuilds, refreshing the build time, as requested.You can specify multiple additional dependencies separated by a white space with this command, if you need to.
Then you can just
#include "timestamp.h"
(assuming that the CMake binary dir is in the include path, which usually is. If not, that's simple:INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR})
), and use_TIMEZ_
whenever you want to have the build time stamp in ISO 8601 format (or, in fact, whatever you like: you can specify it yourself, see CMake documentation forSTRING
command usage).This could've been made simpler by directly (by hand) creating the file
timestamp.cmake
and adding it to your code repository, but I've considered it as not being clean enough. It is a general drawback of CMake you cannot access the time stamp string forming procedure (the one used in theSTRING
CMake command) at the stage where CMake's backend, whatever it is (for example, GNU make) runs so one has to use a separate CMake file and call it at that stage. This could've been done much much simpler and cleaner if you could call the CMake time stamp string forming procedure in the "CMake command mode" (cmake -E
type of invocation), for example, like this:cmake -E date [format] [UTC]
, but alas. I've filed a ticket in the CMake's Mantis bug tracker.You can help that to happen by supporting my feature request posting some comments showing how much you need this on it.
Maybe you could use the compiler macros
__DATE__
__TIME__
inside your code instead getting it from cmake. Worth mentioning that you will need to do clean/make to update these values (since GCC embeds it, if the object is already compiled it wont compile again, so no date/time change)For relatively recent versions of CMake (>=2.8.11):
(see http://www.cmake.org/cmake/help/v3.0/command/string.html). For example: