Saving the Git information to the version.hpp header file at build time will require the following operations:
- We will move most of the code from theĀ CMakeLists.txt of the previous recipe to a separate file, and will call the fileĀ git-hash.cmake:
# in case Git is not available, we default to "unknown"
set(GIT_HASH "unknown")
# find Git and if available set GIT_HASH variable
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%h
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
endif()
message(STATUS "Git hash is ${GIT_HASH}")
# generate file version.hpp based on version.hpp.in
configure_file(
${CMAKE_CURRENT_LIST_DIR}/version.hpp.in
${TARGET_DIR}/generated/version.hpp
@ONLY
)
- The CMakeLists.txt is now left with a part that we recognize very well:
# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# project name and language
project(recipe-07 LANGUAGES CXX)
# require C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# example code
add_executable(example example.cpp)
# needs to find the generated header file
target_include_directories(example
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/generated
)
- The remaining part of CMakeLists.txt records the Git hash every time we build the code, as follows:
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/generated/version.hpp
ALL
COMMAND
${CMAKE_COMMAND} -D TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/git-hash.cmake
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
)
# rebuild version.hpp every time
add_custom_target(
get_git_hash
ALL
DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/generated/version.hpp
)
# version.hpp has to be generated
# before we start building example
add_dependencies(example get_git_hash)