Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile date and time using cmake

Tags:

c++

c

cmake

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)?

like image 670
Gerald Senarclens de Grancy Avatar asked Jun 18 '14 18:06

Gerald Senarclens de Grancy


2 Answers

For relatively recent versions of CMake (>=2.8.11):

string(TIMESTAMP {output variable} [{format string}] [UTC])

(see http://www.cmake.org/cmake/help/v3.0/command/string.html). For example:

string(TIMESTAMP TODAY "%Y%m%d")
like image 148
mathias Avatar answered Nov 06 '22 09:11

mathias


My cross-platform solution on the first run of CMake creates a file timestamp.cmake in the binary directory and defines a target timestamp which runs the generated file. The file timestamp.cmake forms an ISO 8601 time stamp string using the STRING CMake command and writes it to a file timestamp.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.

# build time in UTC ISO 8601
FILE (WRITE ${CMAKE_BINARY_DIR}/timestamp.cmake "STRING(TIMESTAMP TIMEZ UTC)\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(WRITE timestamp.h \"#ifndef TIMESTAMP_H\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define TIMESTAMP_H\\n\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define _TIMEZ_ \\\"\${TIMEZ}\\\"\\n\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#endif // TIMESTAMP_H\\n\")\n")
ADD_CUSTOM_TARGET (
    timestamp
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/timestamp.cmake
    ADD_DEPENDENCIES ${CMAKE_BINARY_DIR}/timestamp.cmake)

Then use the ADD_DEPENDENCIES CMake command to make your main target (probably the main executable file) dependent on the timestamp 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.

ADD_DEPENDENCIES (${CMAKE_BINARY_DIR}/${BINARY_NAME} timestamp)

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 for STRING 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 the STRING 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.

like image 7
dbanet Avatar answered Nov 06 '22 08:11

dbanet