xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/tools/j2s4b/cmake/GitVersion.cmake (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1# CMake-GitVersion.
2# (Yet another) automatic version generation for C++ CMake projects.
3
4# * Generates version information using information from git (tags) with fallback options
5#   when building without git (e.g. when building from sources with exported archives).
6# * Use custom templates for generated sources (e.g. also create resource files (see examples))
7# * Uses semantic versioning (https://semver.org/)
8# * Best suited with git-flow workflows
9#   * See: https://www.atlassian.com/de/git/tutorials/comparing-workflows/gitflow-workflow
10#   * See: https://nvie.com/posts/a-successful-git-branching-model/
11# * Generated version strings are compatible to/and can be used by debian and rpm packages.
12
13# ## Version Generation
14
15# Defines
16# - `LAST_TAG_VERSION`: latest tagged version (e.g. 1.2.0 for tag v1.2.0) or 0.0.0 if no tag exists.
17# - `DIST`: commit count distance to latest version tag.
18
19# Version Number rules:
20# - on _master_:  `X.Y.Z`[-`DIST`] (using `LAST_TAG_VERSION`), while `DIST` should always be 0 on the master branch.
21# - on _develop_ and other branches: `X.Y.Z`-`ALPHA_FLAG`.`DIST` (using `LAST_TAG_VERSION`, `Y` incremented by 1)
22# - on release branches: `X.Y.Z`-`RC_FLAG`.`DIST` (extracting `X.Y.Z` from release branch name or from _develop_ as fallback). \
23#   `DIST` is either calculated to last version tag or to the closest `rc-X.Y.Z` tag.
24# - `DIST` is added to all version numbers, except:
25#   - Versions on _master_ and on _hotfix_ branches with `DIST` equal to 0
26# - All version numbers have a pre-release identifier set, except:
27#   - Version on _master_ and
28#   - versions on _hotfix_ branches with `DIST` equal to 0
29# - When creating the version string and the PATCH number is 0 - the patch number is omitted.
30#   (e.g. 1.2.0 will be 1.2)
31
32### Configuration - this may be adjusted to the personal and project requirements
33set(VERSION_TAG_PREFIX v)     # Should be the same as configured in git-flow
34set(VERSION_ALPHA_FLAG alpha) # Pre-release identifier for all builds besides release and hotfix branches
35set(VERSION_RC_FLAG rc)       # Pre-release identifier for all builds from release and hotfix branches
36set(VERSION_RC_START_TAG_PREFIX "rc-") # If available tags with the given prefix are used for distance calculation on release branches.
37set(RC_BRANCH_PREFIX release) # e.g. release/0.2
38set(HOTFIX_BRANCH_PREFIX hotfix) # e.g. hotfix/2.0.3
39
40# Let functions in this module know their own directory
41set(_GitVersion_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}")
42
43# --------------------------------------------------------------------------------------------------
44# Helper method - usually never called directly:
45# Get the version information for a directory, sets the following variables
46# ${prefix}_VERSION_SUCCESS // 0 on error (e.g. git not found), 1 on success
47# ${prefix}_VERSION_MAJOR
48# ${prefix}_VERSION_MINOR
49# ${prefix}_VERSION_PATCH
50# ${prefix}_VERSION_FLAG
51# ${prefix}_VERSION_DISTANCE
52# ${prefix}_VERSION_SHORTHASH
53# ${prefix}_VERSION_FULLHASH
54# ${prefix}_VERSION_ISDIRTY // 0 or 1 if tree has local modifications
55# ${prefix}_VERSION_STRING // Full version string, e.g. 1.2.3-rc.239
56#
57# A created version number can be overruled if the following variables are set and the version number is GREATER
58# than the dynamically created one.
59# - ${prefix}_CUSTOM_VERSION_MAJOR
60# - ${prefix}_CUSTOM_VERSION_MINOR
61# - ${prefix}_CUSTOM_VERSION_PATCH
62#
63# A version 'type' (release or develop) in case the branch cannot be determined via git
64# - #{prefix}_FALLBACK_VERSION_TYPE
65#
66# The environment variable FALLBACK_BRANCH will be used if the branch cannot be determined
67function(get_version_info prefix directory)
68  set(${prefix}_VERSION_SUCCESS 0 PARENT_SCOPE)
69  set(${prefix}_VERSION_MAJOR 0)
70  set(${prefix}_VERSION_MINOR 0)
71  set(${prefix}_VERSION_PATCH 0)
72  set(${prefix}_VERSION_BRANCH unknown)
73  set(${prefix}_VERSION_FLAG unknown)
74  set(${prefix}_VERSION_DISTANCE 0)
75  set(${prefix}_VERSION_STRING 0.0.0-unknown)
76  set(${prefix}_VERSION_ISDIRTY 0 PARENT_SCOPE)
77
78  if("${${prefix}_CUSTOM_VERSION_MAJOR}" STREQUAL "")
79    set(${prefix}_CUSTOM_VERSION_MAJOR 0)
80  endif()
81  if("${${prefix}_CUSTOM_VERSION_MINOR}" STREQUAL "")
82    set(${prefix}_CUSTOM_VERSION_MINOR 0)
83  endif()
84  if("${${prefix}_CUSTOM_VERSION_PATCH}" STREQUAL "")
85    set(${prefix}_CUSTOM_VERSION_PATCH 0)
86  endif()
87
88  find_package(Git)
89  if(GIT_FOUND)
90    # Get the version info from the last tag (using the configured version tag prefix)
91    execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match "${VERSION_TAG_PREFIX}[0-9].[0-9]*"
92      RESULT_VARIABLE result
93      OUTPUT_VARIABLE GIT_TAG_VERSION
94      ERROR_VARIABLE error_out
95      OUTPUT_STRIP_TRAILING_WHITESPACE
96      WORKING_DIRECTORY ${directory}
97    )
98    if(result EQUAL 0)
99      # Extract version major, minor, patch from the result
100      if(GIT_TAG_VERSION MATCHES "^${VERSION_TAG_PREFIX}?([0-9]+)\\.([0-9]+)(\\.([0-9]+))?(-([0-9]+))?.*$")
101        set(${prefix}_VERSION_MAJOR ${CMAKE_MATCH_1})
102        set(${prefix}_VERSION_MINOR ${CMAKE_MATCH_2})
103        if(NOT ${CMAKE_MATCH_4} STREQUAL "")
104          set(${prefix}_VERSION_PATCH ${CMAKE_MATCH_4})
105        endif()
106        if(NOT ${CMAKE_MATCH_6} STREQUAL "")
107          set(${prefix}_VERSION_DISTANCE ${CMAKE_MATCH_6})
108        endif()
109      endif()
110    else()
111      # git describe return with error - just get the distance
112      execute_process(COMMAND ${GIT_EXECUTABLE} rev-list --count HEAD
113        RESULT_VARIABLE result
114        OUTPUT_VARIABLE GIT_DISTANCE
115        OUTPUT_STRIP_TRAILING_WHITESPACE
116        ERROR_VARIABLE error_out
117        WORKING_DIRECTORY ${directory}
118      )
119      if(result EQUAL 0)
120        set(${prefix}_VERSION_DISTANCE ${GIT_DISTANCE})
121      endif()
122    endif()
123
124    # Check for local modifications ...
125    execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --dirty
126      RESULT_VARIABLE result
127      OUTPUT_VARIABLE GIT_ALWAYS_VERSION
128      OUTPUT_STRIP_TRAILING_WHITESPACE
129      ERROR_VARIABLE error_out
130      WORKING_DIRECTORY ${directory}
131    )
132    if(result EQUAL 0)
133      if(GIT_ALWAYS_VERSION MATCHES "^.*-dirty$")
134        set(${prefix}_VERSION_ISDIRTY 1 PARENT_SCOPE)
135      endif()
136    endif()
137
138    # Check the branch we are on
139    execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
140      RESULT_VARIABLE result
141      OUTPUT_VARIABLE GIT_BRANCH
142      OUTPUT_STRIP_TRAILING_WHITESPACE
143      ERROR_VARIABLE error_out
144      WORKING_DIRECTORY ${directory}
145    )
146
147    if(result EQUAL 0)
148      if("${GIT_BRANCH}" STREQUAL "HEAD"
149         AND NOT "$ENV{FALLBACK_BRANCH}" STREQUAL "")
150         set(GIT_BRANCH "$ENV{FALLBACK_BRANCH}")
151      endif()
152
153      set(${prefix}_VERSION_BRANCH "${GIT_BRANCH}")
154      set(${prefix}_VERSION_BRANCH "${GIT_BRANCH}" PARENT_SCOPE)
155
156      # Check for release branch
157      string(LENGTH ${RC_BRANCH_PREFIX} PREFIX_LEN)
158      string(SUBSTRING ${GIT_BRANCH} 0 ${PREFIX_LEN} COMPARE_PREFIX)
159      string(COMPARE EQUAL ${RC_BRANCH_PREFIX} ${COMPARE_PREFIX} ON_RELEASE_BRANCH)
160      # Check for hotfix branch
161      string(LENGTH ${HOTFIX_BRANCH_PREFIX} PREFIX_LEN)
162      string(SUBSTRING ${GIT_BRANCH} 0 ${PREFIX_LEN} COMPARE_PREFIX)
163      string(COMPARE EQUAL ${HOTFIX_BRANCH_PREFIX} ${COMPARE_PREFIX} ON_HOTFIX_BRANCH)
164      # Check for master branch
165      string(COMPARE EQUAL "master" ${GIT_BRANCH} ON_MASTER)
166
167      if(ON_RELEASE_BRANCH)
168        set(${prefix}_VERSION_FLAG ${VERSION_RC_FLAG})
169        set(RC_VERSION_MAJOR 0)
170        set(RC_VERSION_MINOR 0)
171        set(RC_VERSION_PATCH 0)
172        # Check release branch name for version information (e.g. release/0.8)
173        if(GIT_BRANCH MATCHES "^${RC_BRANCH_PREFIX}.*([0-9]+)\\.([0-9]+)(\\.([0-9]+))?.*$")
174          set(RC_VERSION_MAJOR ${CMAKE_MATCH_1})
175          set(RC_VERSION_MINOR ${CMAKE_MATCH_2})
176          if(NOT ${CMAKE_MATCH_4} STREQUAL "")
177            set(RC_VERSION_PATCH ${CMAKE_MATCH_4})
178          endif()
179        endif()
180
181        # If the release branch version is greater, use that version...
182        if("${RC_VERSION_MAJOR}.${RC_VERSION_MINOR}.${RC_VERSION_PATCH}" VERSION_GREATER
183            "${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR}.${${prefix}_VERSION_PATCH}")
184          set(${prefix}_VERSION_MAJOR ${RC_VERSION_MAJOR})
185          set(${prefix}_VERSION_MINOR ${RC_VERSION_MINOR})
186          set(${prefix}_VERSION_PATCH ${RC_VERSION_PATCH})
187        else() # ... else auto increment the version minor number
188          # Auto increment minor number, patch = 0
189          MATH(EXPR ${prefix}_VERSION_MINOR "${${prefix}_VERSION_MINOR}+1")
190          set(${prefix}_VERSION_PATCH 0)
191        endif()
192
193        # Try to get distance from last rc start tag
194        execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match "${VERSION_RC_START_TAG_PREFIX}[0-9].[0-9]*"
195          RESULT_VARIABLE result
196          OUTPUT_VARIABLE GIT_RC_TAG_VERSION
197          ERROR_VARIABLE error_out
198          OUTPUT_STRIP_TRAILING_WHITESPACE
199          WORKING_DIRECTORY ${directory}
200        )
201        if(result EQUAL 0)
202          if(GIT_RC_TAG_VERSION MATCHES "^${VERSION_RC_START_TAG_PREFIX}?([0-9]+)\\.([0-9]+)(\\.([0-9]+))?(-([0-9]+))?.*$")
203            if(NOT ${CMAKE_MATCH_6} STREQUAL "")
204              set(${prefix}_VERSION_DISTANCE ${CMAKE_MATCH_6})
205            else()
206              set(${prefix}_VERSION_DISTANCE 0)
207            endif()
208          endif()
209        endif()
210
211      elseif(ON_HOTFIX_BRANCH)
212        set(${prefix}_VERSION_FLAG ${VERSION_RC_FLAG})
213          set(RC_VERSION_MAJOR 0)
214          set(RC_VERSION_MINOR 0)
215          set(RC_VERSION_PATCH 0)
216          if(GIT_BRANCH MATCHES "^${RC_BRANCH_PREFIX}.*([0-9]+)\\.([0-9]+)(\\.([0-9]+))?.*$")
217            set(RC_VERSION_MAJOR ${CMAKE_MATCH_1})
218            set(RC_VERSION_MINOR ${CMAKE_MATCH_2})
219            if(NOT ${CMAKE_MATCH_4} STREQUAL "")
220              set(RC_VERSION_PATCH ${CMAKE_MATCH_4})
221            endif()
222          endif()
223
224          if("${RC_VERSION_MAJOR}.${RC_VERSION_MINOR}.${RC_VERSION_PATCH}" VERSION_GREATER
225              "${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR}.${${prefix}_VERSION_PATCH}")
226            set(${prefix}_VERSION_MAJOR ${RC_VERSION_MAJOR})
227            set(${prefix}_VERSION_MINOR ${RC_VERSION_MINOR})
228            set(${prefix}_VERSION_PATCH ${RC_VERSION_PATCH})
229          else()
230            # Auto increment patch number
231            MATH(EXPR ${prefix}_VERSION_PATCH "${${prefix}_VERSION_PATCH}+1")
232          endif()
233      elseif(ON_MASTER)
234       set(${prefix}_VERSION_FLAG "")
235      endif()
236    endif()
237
238    if(NOT ON_MASTER AND NOT ON_RELEASE_BRANCH AND NOT ON_HOTFIX_BRANCH)
239      # Auto increment version number, set alpha flag
240      MATH(EXPR ${prefix}_VERSION_MINOR "${${prefix}_VERSION_MINOR}+1")
241      set(${prefix}_VERSION_PATCH 0)
242      set(${prefix}_VERSION_FLAG ${VERSION_ALPHA_FLAG})
243    endif()
244
245    set(${prefix}_VERSION_FLAG ${${prefix}_VERSION_FLAG} PARENT_SCOPE)
246    set(${prefix}_VERSION_DISTANCE ${${prefix}_VERSION_DISTANCE} PARENT_SCOPE)
247
248    execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
249      RESULT_VARIABLE resultSH
250      OUTPUT_VARIABLE GIT_SHORT_HASH
251      OUTPUT_STRIP_TRAILING_WHITESPACE
252      ERROR_VARIABLE error_out
253      WORKING_DIRECTORY ${directory}
254    )
255    if(resultSH EQUAL 0)
256      set(${prefix}_VERSION_SHORTHASH ${GIT_SHORT_HASH} PARENT_SCOPE)
257    else()
258      message(STATUS "Version-Info: Could not fetch short version hash.")
259      set(${prefix}_VERSION_SHORTHASH "unknown" PARENT_SCOPE)
260    endif()
261
262    execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
263      RESULT_VARIABLE resultFH
264      OUTPUT_VARIABLE GIT_FULL_HASH
265      OUTPUT_STRIP_TRAILING_WHITESPACE
266      ERROR_VARIABLE error_out
267      WORKING_DIRECTORY ${directory}
268    )
269    if(resultFH EQUAL 0)
270      set(${prefix}_VERSION_FULLHASH ${GIT_FULL_HASH} PARENT_SCOPE)
271    else()
272      message(STATUS "Version-Info: Could not fetch full version hash.")
273      set(${prefix}_VERSION_FULLHASH "unknown" PARENT_SCOPE)
274    endif()
275
276    if(resultSH EQUAL 0 AND resultFH EQUAL 0)
277      set(${prefix}_VERSION_SUCCESS 1 PARENT_SCOPE)
278    endif()
279  else() # Git not found ...
280    message(STATUS "Version-Info: Git not found. Possible incomplete version information.")
281  endif()
282
283  if("${${prefix}_VERSION_BRANCH}" STREQUAL "unknown" OR "${${prefix}_VERSION_BRANCH}" STREQUAL "")
284    if("${${prefix}_FALLBACK_VERSION_TYPE}" STREQUAL "release")
285      set(ON_MASTER ON)
286      set(${prefix}_VERSION_FLAG "")
287      set(${prefix}_VERSION_FLAG "" PARENT_SCOPE)
288    endif()
289    set(${prefix}_VERSION_BRANCH "not-within-git-repo" PARENT_SCOPE)
290  endif()
291
292  # Check if overrule version is greater than dynamically created one
293  if("${${prefix}_CUSTOM_VERSION_MAJOR}.${${prefix}_CUSTOM_VERSION_MINOR}.${${prefix}_CUSTOM_VERSION_PATCH}" VERSION_GREATER
294     "${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR}.${${prefix}_VERSION_PATCH}")
295    set(${prefix}_VERSION_MAJOR ${${prefix}_CUSTOM_VERSION_MAJOR})
296    set(${prefix}_VERSION_MINOR ${${prefix}_CUSTOM_VERSION_MINOR})
297    set(${prefix}_VERSION_PATCH ${${prefix}_CUSTOM_VERSION_PATCH})
298  endif()
299
300  set(${prefix}_VERSION_MAJOR ${${prefix}_VERSION_MAJOR} PARENT_SCOPE)
301  set(${prefix}_VERSION_MINOR ${${prefix}_VERSION_MINOR} PARENT_SCOPE)
302  set(${prefix}_VERSION_PATCH ${${prefix}_VERSION_PATCH} PARENT_SCOPE)
303  set(${prefix}_VERSION_DISTANCE ${${prefix}_VERSION_DISTANCE} PARENT_SCOPE)
304
305  # Build version string...
306  set(VERSION_STRING "${${prefix}_VERSION_MAJOR}.${${prefix}_VERSION_MINOR}")
307  if(NOT ${${prefix}_VERSION_PATCH} EQUAL 0)
308    set(VERSION_STRING "${VERSION_STRING}.${${prefix}_VERSION_PATCH}")
309  endif()
310  if(NOT ON_MASTER OR NOT ${${prefix}_VERSION_DISTANCE} EQUAL 0)
311    set(VERSION_STRING "${VERSION_STRING}-${${prefix}_VERSION_FLAG}")
312  endif()
313  if(NOT ${${prefix}_VERSION_FLAG} STREQUAL "")
314    set(VERSION_STRING "${VERSION_STRING}.")
315  endif()
316  if(NOT ON_MASTER OR (NOT ON_MASTER AND NOT ${${prefix}_VERSION_DISTANCE} EQUAL 0))
317    set(VERSION_STRING "${VERSION_STRING}${${prefix}_VERSION_DISTANCE}")
318  endif()
319  set(${prefix}_VERSION_STRING "${VERSION_STRING}" PARENT_SCOPE)
320endfunction()
321
322# --------------------------------------------------------------------------------------------------
323# Add version information to a target, header and source file are configured from templates.
324#  (defaults to GitVersion.h.in and GitVersion.cc.in if no other templates are defined)
325# Variables available to input templates
326# @PREFIX@ = target prefix name given in the function call, must be a valid C-identifier
327# @VERSION_MAJOR@, @VERSION_MINOR@, @VERSION_PATCH@, @VERSION_FLAG@, @VERSION_DISTANCE@
328# @VERSION_SHORTHASH@, @VERSION_FULLHASH@, @VERSION_STRING@, @VERSION_ISDIRTY, @VERSION_BRANCH@
329function(add_version_info)
330  set(oneValueArgs
331    TARGET    # The build target
332    PREFIX    # The prefix/name for templates, must be a valid C identifier
333    DIRECTORY # Directory from which to get the git version info
334  )
335  set(multiValueArgs TEMPLATES) # Templates that are configured and added to the target
336  set(requiredArgs TARGET)
337  cmake_parse_arguments(VI "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
338
339  foreach(arg IN LISTS requiredArgs)
340  if("${VI_${arg}}" STREQUAL "")
341    message(FATAL_ERROR "Required argument '${arg}' is not set.")
342  endif()
343  endforeach()
344
345  if(NOT TARGET ${VI_TARGET})
346    message(FATAL_ERROR "Argument 'TARGET' needs to be a valid target.")
347  endif()
348
349  list(LENGTH VI_TEMPLATES NUM_TEMPLATES)
350  if(NUM_TEMPLATES EQUAL 0)
351    # Add default templates
352    list(APPEND VI_TEMPLATES "${_GitVersion_DIRECTORY}/GitVersion.h.in")
353    list(APPEND VI_TEMPLATES "${_GitVersion_DIRECTORY}/GitVersion.cc.in")
354  endif()
355  string(MAKE_C_IDENTIFIER "${VI_TARGET}" targetid)
356
357  if(NOT VI_PREFIX)
358    string(MAKE_C_IDENTIFIER "${VI_TARGET}" VI_PREFIX)
359  endif()
360
361  if(NOT VI_DIRECTORY)
362    # message(STATUS "add_version_info: defaulting DIRECTORY to '${CMAKE_CURRENT_SOURCE_DIR}'")
363    set(VI_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
364  endif()
365
366  # Set default values, in case sth goes wrong
367  set(VERSION_MAJOR 0)
368  set(VERSION_MINOR 0)
369  set(VERSION_PATCH 0)
370  set(VERSION_FLAG unknown)
371  set(VERSION_DISTANCE 0)
372  set(VERSION_SHORTHASH unknown)
373  set(VERSION_FULLHASH unknown)
374  set(VERSION_STRING "0.0-unknown.0")
375  set(VERSION_ISDIRTY 0)
376  set(VERSION_BRANCH unknown)
377  set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/version/${targetid}")
378
379  get_target_property(TARGET_VMAJOR ${VI_TARGET} VERSION_MAJOR)
380  if(TARGET_VMAJOR)
381    set(${VI_PREFIX}_CUSTOM_VERSION_MAJOR ${TARGET_VMAJOR})
382  endif()
383  get_target_property(TARGET_VMINOR ${VI_TARGET} VERSION_MINOR)
384  if(TARGET_VMINOR)
385    set(${VI_PREFIX}_CUSTOM_VERSION_MINOR ${TARGET_VMINOR})
386    set(VERSION_MINOR ${TARGET_VMINOR})
387  endif()
388  get_target_property(TARGET_VPATCH ${VI_TARGET} VERSION_PATCH)
389  if(TARGET_VPATCH)
390    set(${VI_PREFIX}_CUSTOM_VERSION_PATCH ${TARGET_VPATCH})
391  endif()
392  get_target_property(TARGET_VTYPE ${VI_TARGET} VERSION_TYPE)
393  if(TARGET_VTYPE)
394    set(${VI_PREFIX}_FALLBACK_VERSION_TYPE ${TARGET_VTYPE})
395  endif()
396
397  # Check for ArchiveVersionInfo within same directory and use that info is available ...
398  include(ArchiveVersionInfo_${VI_PREFIX} OPTIONAL RESULT_VARIABLE ARCHIVE_VERSION_PRESENT)
399  if(ARCHIVE_VERSION_PRESENT AND ${VI_PREFIX}_VERSION_SUCCESS)
400    message(STATUS "Info: Version information from archive file.")
401
402  # ... get version info via git otherwise.
403  else()
404    get_version_info(${VI_PREFIX} "${VI_DIRECTORY}")
405
406    # Check if valid version information could be aquired...
407    if("${${VI_PREFIX}_VERSION_FULLHASH}" STREQUAL "unknown"
408       OR "${${VI_PREFIX}_VERSION_SHORTHASH}" STREQUAL "unknown"
409       OR "${${VI_PREFIX}_VERSION_FULLHASH}" STREQUAL ""
410       OR "${${VI_PREFIX}_VERSION_SHORTHASH}" STREQUAL "")
411
412       # ...and check for ArchiveExportInfo as fallback solution..
413       include(ArchiveExportInfo OPTIONAL RESULT_VARIABLE GIT_EXPORT_INFO_FILE_PRESENT)
414       if("${GIT_EXPORT_VERSION_SHORTHASH}" MATCHES "(.?Format:).*")
415         set(HAS_GIT_EXPORT_INFO OFF)
416       endif()
417       if(GIT_EXPORT_INFO_FILE_PRESENT AND HAS_GIT_EXPORT_INFO)
418         message(STATUS "Using ArchiveExportInfo as fallback for version info.")
419         set(${VI_PREFIX}_VERSION_SHORTHASH "${GIT_EXPORT_VERSION_SHORTHASH}")
420         set(${VI_PREFIX}_VERSION_FULLHASH "${GIT_EXPORT_VERSION_FULLHASH}")
421         set(${VI_PREFIX}_VERSION_BRANCH "${GIT_EXPORT_VERSION_BRANCH}")
422         if("${${VI_PREFIX}_VERSION_BRANCH}" MATCHES ".*[ \t]+[->]+[\t ]+(.*)([,]?.*)")
423           set(${VI_PREFIX}_VERSION_BRANCH "${CMAKE_MATCH_1}")
424         elseif("${${VI_PREFIX}_VERSION_BRANCH}" MATCHES ".*,[ \t](.*)")
425           if("${CMAKE_MATCH_1}" STREQUAL "master")
426             set(ON_MASTER ON)
427           endif()
428         endif()
429         # Check for release branch
430         string(LENGTH ${RC_BRANCH_PREFIX} PREFIX_LEN)
431         string(SUBSTRING ${${VI_PREFIX}_VERSION_BRANCH} 0 ${PREFIX_LEN} COMPARE_PREFIX)
432         string(COMPARE EQUAL ${RC_BRANCH_PREFIX} ${COMPARE_PREFIX} ON_RELEASE_BRANCH)
433         # Check for hotfix branch
434         string(LENGTH ${HOTFIX_BRANCH_PREFIX} PREFIX_LEN)
435         string(SUBSTRING ${${VI_PREFIX}_VERSION_BRANCH} 0 ${PREFIX_LEN} COMPARE_PREFIX)
436         string(COMPARE EQUAL ${HOTFIX_BRANCH_PREFIX} ${COMPARE_PREFIX} ON_HOTFIX_BRANCH)
437         # Check for master branch
438         if(NOT ON_MASTER)
439           string(COMPARE EQUAL "master" ${${VI_PREFIX}_VERSION_BRANCH} ON_MASTER)
440         endif()
441         if(ON_MASTER)
442           set(${VI_PREFIX}_VERSION_FLAG "")
443         elseif(ON_RELEASE_BRANCH)
444           set(${VI_PREFIX}_VERSION_FLAG "${VERSION_RC_FLAG}")
445         elseiF(ON_HOTFIX_BRANCH)
446           set(${VI_PREFIX}_VERSION_FLAG "hotfix")
447         else()
448           set(${VI_PREFIX}_VERSION_FLAG "${VERSION_ALPHA_FLAG}")
449         endif()
450         # Build version string...
451         set(VERSION_STRING "${${VI_PREFIX}_VERSION_MAJOR}.${${VI_PREFIX}_VERSION_MINOR}")
452         if(NOT ${${VI_PREFIX}_VERSION_PATCH} EQUAL 0)
453           set(VERSION_STRING "${VERSION_STRING}.${${VI_PREFIX}_VERSION_PATCH}")
454         endif()
455         if(NOT ON_MASTER OR NOT ${${VI_PREFIX}_VERSION_DISTANCE} EQUAL 0)
456           set(VERSION_STRING "${VERSION_STRING}-${${VI_PREFIX}_VERSION_FLAG}")
457         endif()
458         if(NOT ${${VI_PREFIX}_VERSION_FLAG} STREQUAL "")
459           set(VERSION_STRING "${VERSION_STRING}.")
460         endif()
461         if(NOT ON_MASTER OR (NOT ON_MASTER AND NOT ${${VI_PREFIX}_VERSION_DISTANCE} EQUAL 0))
462           set(VERSION_STRING "${VERSION_STRING}${${VI_PREFIX}_VERSION_DISTANCE}")
463         endif()
464         set(${VI_PREFIX}_VERSION_STRING "${VERSION_STRING}")
465      endif()
466    endif()
467  endif()
468
469  if(${${VI_PREFIX}_VERSION_SUCCESS})
470    # All informations gathered via git
471  else()
472    message(STATUS "Version-Info: Failure during version retrieval. Possible incomplete version information!")
473  endif()
474  # Test if we are building from an archive that has generated version information
475  set(VERSION_MAJOR ${${VI_PREFIX}_VERSION_MAJOR})
476  set(VERSION_MINOR ${${VI_PREFIX}_VERSION_MINOR})
477  set(VERSION_PATCH ${${VI_PREFIX}_VERSION_PATCH})
478  set(VERSION_FLAG ${${VI_PREFIX}_VERSION_FLAG})
479  set(VERSION_DISTANCE ${${VI_PREFIX}_VERSION_DISTANCE})
480  set(VERSION_SHORTHASH ${${VI_PREFIX}_VERSION_SHORTHASH})
481  set(VERSION_FULLHASH ${${VI_PREFIX}_VERSION_FULLHASH})
482  set(VERSION_STRING ${${VI_PREFIX}_VERSION_STRING})
483  set(VERSION_ISDIRTY ${${VI_PREFIX}_VERSION_ISDIRTY})
484  set(VERSION_BRANCH ${${VI_PREFIX}_VERSION_BRANCH})
485  set_target_properties(${VI_TARGET} PROPERTIES
486    VERSION_MAJOR "${VERSION_MAJOR}"
487    VERSION_MINOR "${VERSION_MINOR}"
488    VERSION_PATCH "${VERSION_PATCH}"
489    VERSION_FLAG "${VERSION_FLAG}"
490    VERSION_DISTANCE "${VERSION_DISTANCE}"
491    VERSION_SHORTHASH "${VERSION_SHORTHASH}"
492    VERSION_FULLHASH "${VERSION_FULLHASH}"
493    VERSION_STRING "${VERSION_STRING}"
494    VERSION_ISDIRTY "${VERSION_ISDIRTY}"
495    VERSION_BRANCH "${VERSION_BRANCH}"
496  )
497
498  set(TARGET ${VI_PREFIX})
499  set(PREFIX ${VI_PREFIX})
500  foreach(template_file ${VI_TEMPLATES})
501    if(template_file MATCHES "(.*)(\.in)$")
502      get_filename_component(output_basename "${CMAKE_MATCH_1}" NAME)
503    else()
504      get_filename_component(output_basename "${template_file}" NAME)
505    endif()
506    set(output_file "${output_dir}/${VI_PREFIX}-${output_basename}")
507    configure_file("${template_file}" "${output_file}")
508    list(APPEND output_files "${output_file}")
509  endforeach()
510
511  # Generate archive version info. File can be included in source archives to have detailed
512  # version information available without being a git repository.
513  # See https://github.com/jahnf/Projecteur, where it is used for the 'source-archive' build target.
514  configure_file("${_GitVersion_DIRECTORY}/ArchiveVersionInfo.cmake.in"
515                 "archive_append/cmake/modules/ArchiveVersionInfo_${VI_PREFIX}.cmake" @ONLY)
516
517  get_target_property(type ${VI_TARGET} TYPE)
518  if(type STREQUAL "SHARED_LIBRARY")
519    set_target_properties(${VI_TARGET} PROPERTIES SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}")
520    set_property(TARGET ${VI_TARGET} PROPERTY VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
521  endif()
522
523  # If any templates where configured, add them to the project sources
524  list(LENGTH output_files NUM_CONFIGURED_FILES)
525  if(NOT NUM_CONFIGURED_FILES EQUAL 0)
526    set_property(TARGET ${VI_TARGET} APPEND PROPERTY SOURCES ${output_files})
527    target_include_directories(${VI_TARGET} PUBLIC $<BUILD_INTERFACE:${output_dir}>)
528  endif()
529  message(STATUS "Version info for '${VI_TARGET}': ${VERSION_STRING} (prefix=${VI_PREFIX})")
530endfunction()
531
532