From f5379ab80661c8dcc94f30194fd6fcfb350bc8ec Mon Sep 17 00:00:00 2001 From: Rafael Kitover Date: Sat, 7 Oct 2017 14:00:47 -0700 Subject: [PATCH] read version and subversion info from Git To get the version, find the last tag in git tag of the form "v2.0.0" or "2.0.0". If this is the last tag and the current commit matches the ref of this tag, the revision will be empty. In the case that the current commit is not tagged with a version, to get the revision, use the short sha unless the current commit is tagged with something that is not a version string, e.g. "feature-foo", in which case the revision will be "feature-foo". If the current commit is tagged as e.g. "v2.0.1-foo" or "2.0.1-foo" then the version will be "2.0.1" and the revision will be "foo". Tags of this form are also checked when finding the current version. This is all done in cmake. If there is no git detected, the version will be "2.0.0" and the revision will be "unknown". --- CMakeLists.txt | 10 +++---- cmake/GitTagVersion.cmake | 63 +++++++++++++++++++++++++++++++++++++++ src/version.h.in | 4 +-- 3 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 cmake/GitTagVersion.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a31c15bc..c7d07583 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,10 +105,8 @@ endif( NOT ENABLE_DEBUGGER AND ENABLE_SDL ) find_package(Git) if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git") - INCLUDE(GetGitRevisionDescription) - EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD OUTPUT_VARIABLE SHORT_SHA OUTPUT_STRIP_TRAILING_WHITESPACE) - - SET(REVISION ${SHORT_SHA} CACHE STRING "git short sha" FORCE) + include(GitTagVersion) + git_version(VERSION REVISION VERSION_RELEASE) # only use the plugin to tie the configure state to the sha to force rebuilds # of files that depend on version.h @@ -117,7 +115,9 @@ if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git") else() message(WARNING "Git not found, cannot set version info") - SET(REVISION "unknown") + set(VERSION 2.0.0) + set(REVISION "unknown") + set(VERSION_RELEASE 0) endif() # generate version.h diff --git a/cmake/GitTagVersion.cmake b/cmake/GitTagVersion.cmake new file mode 100644 index 00000000..ca484a96 --- /dev/null +++ b/cmake/GitTagVersion.cmake @@ -0,0 +1,63 @@ +function(git_version version revision version_release) + set(${version} "" CACHE STRING "Latest Git Tag Version" FORCE) + set(${revision} "" CACHE STRING "Latest Git Tag Revision" FORCE) + set(${version_release} 0 CACHE STRING "Is this a versioned release without revision" FORCE) + + find_package(Git) + if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git") + # get latest version from tag history + execute_process(COMMAND ${GIT_EXECUTABLE} tag --sort=-creatordate OUTPUT_VARIABLE sorted_tags OUTPUT_STRIP_TRAILING_WHITESPACE) + + # convert to list (see: https://public.kitware.com/pipermail/cmake/2007-May/014222.html) + string(REGEX REPLACE ";" "\\\\;" sorted_tags "${sorted_tags}") + string(REGEX REPLACE "\n" ";" sorted_tags "${sorted_tags}") + + foreach(tag ${sorted_tags}) + if(tag MATCHES "^v?(([0-9]+\\.?)*[0-9]*)(-(.*))?$") + set(${version} "${CMAKE_MATCH_1}" CACHE STRING "Latest Git Tag Version" FORCE) + set(revision_str "${CMAKE_MATCH_4}") + break() + endif() + endforeach() + + if(revision_str) + # don't need to read revision from tags + set(${revision} "${revision_str}" CACHE STRING "Latest Git Tag Revision" FORCE) + return() + endif() + + # get the current revision + execute_process(COMMAND ${GIT_EXECUTABLE} tag "--format=%(align:width=20)%(refname:short)%(end)%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end)" --sort=-creatordate OUTPUT_VARIABLE sorted_tags_refs OUTPUT_STRIP_TRAILING_WHITESPACE) + + # convert to list (see: https://public.kitware.com/pipermail/cmake/2007-May/014222.html) + string(REGEX REPLACE ";" "\\\\;" sorted_tags_refs "${sorted_tags_refs}") + string(REGEX REPLACE "\n" ";" sorted_tags_refs "${sorted_tags_refs}") + + # get the newest tag + list(GET sorted_tags_refs 0 tag_ref) + + string(REGEX REPLACE "^([^ ]+) +([^ ]+)$" "\\1" tag "${tag_ref}") + string(REGEX REPLACE "^([^ ]+) +([^ ]+)$" "\\2" ref "${tag_ref}") + + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD OUTPUT_VARIABLE current_ref OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(tag MATCHES "^v?(([0-9]+\\.?)*[0-9]*)(-(.*))?$" AND ref STREQUAL current_ref) + set(revision_str "${CMAKE_MATCH_4}") + + # version and no revision tagged for current commit + if(NOT revision_str) + set(${revision} "" CACHE STRING "Latest Git Tag Revision" FORCE) + set(${version_release} 1 CACHE STRING "Is this a versioned release without revision" FORCE) + else() + set(${revision} "${revision_str}" CACHE STRING "Latest Git Tag Revision" FORCE) + endif() + elseif(ref STREQUAL current_ref) + # revision name tagged + set(${revision} "${tag}" CACHE STRING "Latest Git Tag Revision" FORCE) + else() + # dev version, use short sha for ref + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD OUTPUT_VARIABLE short_sha OUTPUT_STRIP_TRAILING_WHITESPACE) + set(${revision} "${short_sha}" CACHE STRING "Latest Git Tag Revision" FORCE) + endif() + endif() +endfunction() diff --git a/src/version.h.in b/src/version.h.in index b6b95287..02bce794 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -18,13 +18,13 @@ // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define VBA_NAME "VisualBoyAdvance-M" -#define VBA_CURRENT_VERSION "2.0.0" +#define VBA_CURRENT_VERSION "@VERSION@" #define VBA_FEATURE_STRING "" #define _STRINGIFY(N) #N -#if defined(PUBLIC_RELEASE) +#if @VERSION_RELEASE@ #define VBA_SUBVERSION_STRING "" #else #define VBA_SUBVERSION_STRING "-" "@REVISION@"