|
1 | | -macro(get_commit_hash VARNAME) |
2 | | - execute_process( |
3 | | - COMMAND git log -1 --format=%h |
4 | | - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
5 | | - OUTPUT_VARIABLE ${VARNAME} |
6 | | - OUTPUT_STRIP_TRAILING_WHITESPACE) |
7 | | -endmacro() |
8 | | - |
9 | | -macro(get_git_describe VARNAME) |
10 | | - execute_process( |
11 | | - COMMAND git describe --always --tags --first-parent |
12 | | - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
13 | | - OUTPUT_VARIABLE ${VARNAME} |
14 | | - OUTPUT_STRIP_TRAILING_WHITESPACE) |
15 | | -endmacro() |
16 | | - |
17 | | -macro(get_git_date VARNAME) |
18 | | - execute_process( |
19 | | - COMMAND git log -1 --format=%ai |
20 | | - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
21 | | - OUTPUT_VARIABLE ${VARNAME} |
22 | | - OUTPUT_STRIP_TRAILING_WHITESPACE) |
23 | | -endmacro() |
24 | | - |
25 | | -macro(extractVCSInformation COMMIT_VARNAME DESCRIBE_VARNAME COMMIT_DATE_VARNAME) |
26 | | - get_commit_hash(${COMMIT_VARNAME}) |
27 | | - get_git_describe(${DESCRIBE_VARNAME}) |
28 | | - get_git_date(${COMMIT_DATE_VARNAME}) |
29 | | - |
30 | | - if("${${COMMIT_VARNAME}}" STREQUAL "") |
31 | | - #If I don't have information I try to get it from the version.info file next to the sources (if one) |
32 | | - message(STATUS "I couldn't get version information from git, using the version.info next to the sources") |
33 | | - file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/version.info FILECONTENT LIMIT_COUNT 3) |
34 | | - list(GET FILECONTENT 0 ${COMMIT_VARNAME}) |
35 | | - list(GET FILECONTENT 1 ${DESCRIBE_VARNAME}) |
36 | | - list(GET FILECONTENT 2 ${COMMIT_DATE_VARNAME}) |
37 | | - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/version.info DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) |
38 | | - else() |
39 | | - #If I have information for the Commit ID, I store it in the version.info file |
40 | | - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/version.info ${${COMMIT_VARNAME}}\n) |
41 | | - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/version.info ${${DESCRIBE_VARNAME}}\n) |
42 | | - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/version.info ${${COMMIT_DATE_VARNAME}}) |
| 1 | +# |
| 2 | +# This cmake module sets the project version and partial version |
| 3 | +# variables by analysing the git tag and commit history. It expects git |
| 4 | +# tags defined with semantic versioning 2.0.0 (http://semver.org/). |
| 5 | +# |
| 6 | +# The module expects the PROJECT_NAME variable to be set, and recognizes |
| 7 | +# the GIT_FOUND, GIT_EXECUTABLE and VERSION_UPDATE_FROM_GIT variables. |
| 8 | +# If Git is found and VERSION_UPDATE_FROM_GIT is set to boolean TRUE, |
| 9 | +# the project version will be updated using information fetched from the |
| 10 | +# most recent git tag and commit. Otherwise, the module will try to read |
| 11 | +# a VERSION file containing the full and partial versions. The module |
| 12 | +# will update this file each time the project version is updated. |
| 13 | +# |
| 14 | +# Once done, this module will define the following variables: |
| 15 | +# |
| 16 | +# ${PROJECT_NAME}_VERSION_STRING - Version string without metadata |
| 17 | +# such as "v2.0.0" or "v1.2.41-beta.1". This should correspond to the |
| 18 | +# most recent git tag. |
| 19 | +# ${PROJECT_NAME}_VERSION_STRING_FULL - Version string with metadata |
| 20 | +# such as "v2.0.0+3.a23fbc" or "v1.3.1-alpha.2+4.9c4fd1" |
| 21 | +# ${PROJECT_NAME}_VERSION - Same as ${PROJECT_NAME}_VERSION_STRING, |
| 22 | +# without the preceding 'v', e.g. "2.0.0" or "1.2.41-beta.1" |
| 23 | +# ${PROJECT_NAME}_VERSION_FULL - Same as ${PROJECT_NAME}_VERSION_STRING_FULL, |
| 24 | +# such as "2.0.0+3.a23fbc" or "1.3.1-alpha.2+4.9c4fd1" |
| 25 | +# ${PROJECT_NAME}_VERSION_MAJOR - Major version integer (e.g. 2 in v2.3.1-RC.2+21.ef12c8) |
| 26 | +# ${PROJECT_NAME}_VERSION_MINOR - Minor version integer (e.g. 3 in v2.3.1-RC.2+21.ef12c8) |
| 27 | +# ${PROJECT_NAME}_VERSION_PATCH - Patch version integer (e.g. 1 in v2.3.1-RC.2+21.ef12c8) |
| 28 | +# ${PROJECT_NAME}_VERSION_TWEAK - Tweak version string (e.g. "RC.2" in v2.3.1-RC.2+21.ef12c8) |
| 29 | +# ${PROJECT_NAME}_VERSION_AHEAD - How many commits ahead of last tag (e.g. 21 in v2.3.1-RC.2+21.ef12c8) |
| 30 | +# ${PROJECT_NAME}_VERSION_GIT_SHA - The git sha1 of the most recent commit (e.g. the "ef12c8" in v2.3.1-RC.2+21.ef12c8) |
| 31 | +# |
| 32 | +# This module is public domain, use it as it fits you best. |
| 33 | +# |
| 34 | +# Author: Nuno Fachada |
| 35 | + |
| 36 | +# Check if git is found... |
| 37 | +if (VERSION_UPDATE_FROM_GIT) |
| 38 | + find_package(Git) |
| 39 | +endif() |
| 40 | + |
| 41 | +if (GIT_FOUND AND VERSION_UPDATE_FROM_GIT) |
| 42 | + |
| 43 | + # Get last tag from git |
| 44 | + execute_process(COMMAND ${GIT_EXECUTABLE} describe --abbrev=0 --tags |
| 45 | + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
| 46 | + OUTPUT_VARIABLE ${PROJECT_NAME}_VERSION_STRING |
| 47 | + OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 48 | + |
| 49 | + #How many commits since last tag |
| 50 | + execute_process(COMMAND ${GIT_EXECUTABLE} rev-list ${${PROJECT_NAME}_VERSION_STRING}^..HEAD --count |
| 51 | + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
| 52 | + OUTPUT_VARIABLE ${PROJECT_NAME}_VERSION_AHEAD |
| 53 | + OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 54 | + |
| 55 | + # Get current commit SHA from git |
| 56 | + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD |
| 57 | + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
| 58 | + OUTPUT_VARIABLE ${PROJECT_NAME}_VERSION_GIT_SHA |
| 59 | + OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 60 | + |
| 61 | + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%ai |
| 62 | + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} |
| 63 | + OUTPUT_VARIABLE ${PROJECT_NAME}_VERSION_GIT_COMMIT_DATE |
| 64 | + OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 65 | + |
| 66 | + # Get partial versions into a list |
| 67 | + string(REGEX MATCHALL "-.*$|[0-9]+" ${PROJECT_NAME}_PARTIAL_VERSION_LIST |
| 68 | + ${${PROJECT_NAME}_VERSION_STRING}) |
| 69 | + |
| 70 | + # Set the version numbers |
| 71 | + list(GET ${PROJECT_NAME}_PARTIAL_VERSION_LIST |
| 72 | + 0 ${PROJECT_NAME}_VERSION_MAJOR) |
| 73 | + list(GET ${PROJECT_NAME}_PARTIAL_VERSION_LIST |
| 74 | + 1 ${PROJECT_NAME}_VERSION_MINOR) |
| 75 | + list(GET ${PROJECT_NAME}_PARTIAL_VERSION_LIST |
| 76 | + 2 ${PROJECT_NAME}_VERSION_PATCH) |
| 77 | + |
| 78 | + # The tweak part is optional, so check if the list contains it |
| 79 | + list(LENGTH ${PROJECT_NAME}_PARTIAL_VERSION_LIST |
| 80 | + ${PROJECT_NAME}_PARTIAL_VERSION_LIST_LEN) |
| 81 | + if (${PROJECT_NAME}_PARTIAL_VERSION_LIST_LEN GREATER 3) |
| 82 | + list(GET ${PROJECT_NAME}_PARTIAL_VERSION_LIST 3 ${PROJECT_NAME}_VERSION_TWEAK) |
| 83 | + string(SUBSTRING ${${PROJECT_NAME}_VERSION_TWEAK} 1 -1 ${PROJECT_NAME}_VERSION_TWEAK) |
43 | 84 | endif() |
44 | | -endmacro() |
| 85 | + |
| 86 | + # Unset the list |
| 87 | + unset(${PROJECT_NAME}_PARTIAL_VERSION_LIST) |
| 88 | + |
| 89 | + # Set full project version string |
| 90 | + set(${PROJECT_NAME}_VERSION_STRING_FULL |
| 91 | + ${${PROJECT_NAME}_VERSION_STRING}+${${PROJECT_NAME}_VERSION_AHEAD}.${${PROJECT_NAME}_VERSION_GIT_SHA}) |
| 92 | + |
| 93 | + # Save version to file (which will be used when Git is not available |
| 94 | + # or VERSION_UPDATE_FROM_GIT is disabled) |
| 95 | + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/version.info ${${PROJECT_NAME}_VERSION_STRING_FULL} |
| 96 | + "*" ${${PROJECT_NAME}_VERSION_STRING} |
| 97 | + "*" ${${PROJECT_NAME}_VERSION_MAJOR} |
| 98 | + "*" ${${PROJECT_NAME}_VERSION_MINOR} |
| 99 | + "*" ${${PROJECT_NAME}_VERSION_PATCH} |
| 100 | + "*" ${${PROJECT_NAME}_VERSION_TWEAK} |
| 101 | + "*" ${${PROJECT_NAME}_VERSION_AHEAD} |
| 102 | + "*" ${${PROJECT_NAME}_VERSION_GIT_SHA} |
| 103 | + "*" ${${PROJECT_NAME}_VERSION_GIT_COMMIT_DATE}) |
| 104 | + |
| 105 | +else() |
| 106 | + |
| 107 | + # Git not available, get version from file |
| 108 | + file(STRINGS ${CMAKE_SOURCE_DIR}/version.info ${PROJECT_NAME}_VERSION_LIST) |
| 109 | + string(REPLACE "*" ";" ${PROJECT_NAME}_VERSION_LIST ${${PROJECT_NAME}_VERSION_LIST}) |
| 110 | + # Set partial versions |
| 111 | + list(GET ${PROJECT_NAME}_VERSION_LIST 0 ${PROJECT_NAME}_VERSION_STRING_FULL) |
| 112 | + list(GET ${PROJECT_NAME}_VERSION_LIST 1 ${PROJECT_NAME}_VERSION_STRING) |
| 113 | + list(GET ${PROJECT_NAME}_VERSION_LIST 2 ${PROJECT_NAME}_VERSION_MAJOR) |
| 114 | + list(GET ${PROJECT_NAME}_VERSION_LIST 3 ${PROJECT_NAME}_VERSION_MINOR) |
| 115 | + list(GET ${PROJECT_NAME}_VERSION_LIST 4 ${PROJECT_NAME}_VERSION_PATCH) |
| 116 | + list(GET ${PROJECT_NAME}_VERSION_LIST 5 ${PROJECT_NAME}_VERSION_TWEAK) |
| 117 | + list(GET ${PROJECT_NAME}_VERSION_LIST 6 ${PROJECT_NAME}_VERSION_AHEAD) |
| 118 | + list(GET ${PROJECT_NAME}_VERSION_LIST 7 ${PROJECT_NAME}_VERSION_GIT_SHA) |
| 119 | + list(GET ${PROJECT_NAME}_VERSION_LIST 8 ${PROJECT_NAME}_VERSION_GIT_COMMIT_DATE) |
| 120 | + |
| 121 | +endif() |
| 122 | + |
| 123 | + |
| 124 | +# Set project version (without the preceding 'v') |
| 125 | +set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}) |
| 126 | +set(${PROJECT_NAME}_VERSION_FULL ${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}) |
| 127 | +if (${PROJECT_NAME}_VERSION_TWEAK) |
| 128 | + set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_VERSION}-${${PROJECT_NAME}_VERSION_TWEAK}) |
| 129 | +endif() |
0 commit comments