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" + )