Git revision as compiler definition in build with CMake

This is how to auto-generate a version header file with git revision (SHA) and the exact build time as C defines. Include header in your source as convenient way to have access to the exact git version for the application version string or diagnostics output.

Header file with the git revision and build timestamp.

// gitversion.h
#pragma once

#define GIT_REVISION "f8d2aca"
#define BUILD_TIMESTAMP "2017-07-14T20:24:36"

CMake script generates the header in cmake build directory

# cmake/gitversion.cmake
cmake_minimum_required(VERSION 3.0.0)

message(STATUS "Resolving GIT Version")

set(_build_version "unknown")

find_package(Git)
if(GIT_FOUND)
  execute_process(
    COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
    WORKING_DIRECTORY "${local_dir}"
    OUTPUT_VARIABLE _build_version
    ERROR_QUIET
    OUTPUT_STRIP_TRAILING_WHITESPACE
  )
  message( STATUS "GIT hash: ${_build_version}")
else()
  message(STATUS "GIT not found")
endif()

string(TIMESTAMP _time_stamp)

configure_file(${local_dir}/cmake/gitversion.h.in ${output_dir}/gitversion.h @ONLY)

It’s possible to run this script only once in configuration, but you could also use it in main CMakeLists.txt to execute it before every build.

# Example CMakeLists.txt
cmake_minimum_required(VERSION 3.7.0)
project(Main)

set(_target Main)
add_executable(${_target} src/main.c)

add_custom_command(TARGET ${_target}
  PRE_BUILD
  COMMAND ${CMAKE_COMMAND}
    -Dlocal_dir="${CMAKE_CURRENT_SOURCE_DIR}"
    -Doutput_dir="${CMAKE_CURRENT_BINARY_DIR}"
    -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/gitversion.cmake"
)

# for finding generated gitversion.h
target_include_directories(${_target} PRIVATE ${CMAKE_BINARY_DIR})

Caveats!
– Build steps are executed only if the build is really needed, if target is up to date no command is executed.
– All build steps are not supported when using the Unix Makefile generator.

Get full example from https://github.com/tikonen/blog/tree/master/cmake/git_version

Leave a comment