From 928a67b77f0aa7b52b26d6273a3b1a670beb60aa Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Wed, 31 Jul 2013 12:04:07 +0200 Subject: [PATCH] Write version information into header file Akin to config.h, we write project-version.h whenever the VCS sha hash of the project changes. This file can then be included to embed this into the project. Since this changes more frequently, we choose another file than config.h. Care is also taken to not rewrite the header if the information doesn't change, but the project is rebuilt. --- cmake/Modules/OpmLibMain.cmake | 3 ++ cmake/Modules/UseVersion.cmake | 25 +++++++++++++ cmake/Scripts/WriteVerSHA.cmake | 63 +++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 cmake/Modules/UseVersion.cmake create mode 100644 cmake/Scripts/WriteVerSHA.cmake diff --git a/cmake/Modules/OpmLibMain.cmake b/cmake/Modules/OpmLibMain.cmake index f9e33eb1..09816a09 100644 --- a/cmake/Modules/OpmLibMain.cmake +++ b/cmake/Modules/OpmLibMain.cmake @@ -230,3 +230,6 @@ configure_file ( "${CMAKE_CURRENT_BINARY_DIR}/dunemod.tmp" COPYONLY ) + +# make sure updated version information is available in the source code +include (UseVersion) diff --git a/cmake/Modules/UseVersion.cmake b/cmake/Modules/UseVersion.cmake new file mode 100644 index 00000000..141f3412 --- /dev/null +++ b/cmake/Modules/UseVersion.cmake @@ -0,0 +1,25 @@ +# - Write version information into the source code +# +# Add an unconditional target to the Makefile which checks the current +# SHA of the source directory and write to a header file if and *only* +# if this has changed (thus we avoid unnecessary rebuilds). By having +# this in the Makefile, we get updated version information even though +# we haven't done any reconfiguring. +# +# The time it takes to probe the VCS for this information and write it +# to the miniature file in negligable. + +if (NOT GIT_FOUND) + find_package (Git) +endif () + +add_custom_target (update-version ALL + COMMAND ${CMAKE_COMMAND} + -DCMAKE_HOME_DIRECTORY=${CMAKE_HOME_DIRECTORY} + -DGIT_EXECUTABLE=${GIT_EXECUTABLE} + -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} + -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} + -DPROJECT_LABEL=${${project}_LABEL} + -P ${PROJECT_SOURCE_DIR}/cmake/Scripts/WriteVerSHA.cmake + COMMENT "Updating version information" + ) diff --git a/cmake/Scripts/WriteVerSHA.cmake b/cmake/Scripts/WriteVerSHA.cmake new file mode 100644 index 00000000..d3b39473 --- /dev/null +++ b/cmake/Scripts/WriteVerSHA.cmake @@ -0,0 +1,63 @@ +# - This script must be passed the following information +# +# GIT_EXECUTABLE Path to the Git executable +# PROJECT_SOURCE_DIR Path to the source directory +# PROJECT_BINARY_DIR Path to the build directory +# PROJECT_LABEL String that identifies the minor +# version of the project, e.g. "2013.03" +# + +# get hash code +exec_program ( + ${GIT_EXECUTABLE} ${PROJECT_SOURCE_DIR} + ARGS rev-parse --short --verify HEAD + OUTPUT_VARIABLE sha1 + RETURN_VALUE has_sha + ) + +# exec_program unfortunately mashes together both output +# and error streams, so we must use the return code to make +# sure that we only get the output +if (NOT ${has_sha} EQUAL 0) + set (sha1 "") +endif () + +# check for local changes +if (sha1) + # unstaged + exec_program ( + ${GIT_EXECUTABLE} ${PROJECT_SOURCE_DIR} + ARGS diff --no-ext-diff --quiet --exit-code + RETURN_VALUE dirty + OUTPUT_VARIABLE _dummy + ) + + # staged + exec_program ( + ${GIT_EXECUTABLE} ${PROJECT_SOURCE_DIR} + ARGS diff-index --no-ext-diff --cached --quiet --exit-code HEAD -- + RETURN_VALUE staged + OUTPUT_VARIABLE _dummy + ) + + # if we found any changes, then append an asterisk to + # the SHA1 so we know that it cannot be trusted + if (dirty OR staged) + set (sha1 "${sha1}*") + endif () + + # make a formatted version that can be appended to the label + set (sha1 " (${sha1})") +endif () + +# write the content to a temporary file in a C compatible format +file (WRITE "${PROJECT_BINARY_DIR}/project-version.tmp" + "#define PROJECT_VERSION \"${PROJECT_LABEL}${sha1}\"\n" + ) + +# only commit this to source code if it actually changed. here +# we use execute_process instead of exec_program to avoid having +# it printed on the console every time +execute_process (COMMAND + ${CMAKE_COMMAND} -E copy_if_different "${PROJECT_BINARY_DIR}/project-version.tmp" "${PROJECT_BINARY_DIR}/project-version.h" + )