Преглед изворни кода

Add version info to filenames

VintagePC пре 1 година
родитељ
комит
ea920536cb

+ 49 - 6
CMakeLists.txt

@@ -1,7 +1,51 @@
 cmake_minimum_required(VERSION 3.15)
 include(cmake/Utilities.cmake)
+include(cmake/GetGitRevisionDescription.cmake)
 
-set (CMAKE_CXX_STANDARD 17)
+#set (CMAKE_CXX_STANDARD 17)
+
+SET(PROJECT_VERSION_SUFFIX
+    "<auto>"
+    CACHE
+      STRING
+      "Full version suffix to be shown on the info screen in settings (e.g. full_version=4.0.3-BETA+1035.PR111.B4, suffix=-BETA+1035.PR111.B4). Defaults to '+<commit sha>.<dirty?>.<debug?>' if set to '<auto>'."
+    )
+SET(PROJECT_VERSION_SUFFIX_SHORT
+    "<auto>"
+    CACHE
+      STRING
+      "Short version suffix to be shown on splash screen. Defaults to '+<BUILD_NUMBER>' if set to '<auto>'."
+    )
+SET(BUILD_NUMBER
+    ""
+    CACHE STRING "Build number of the firmware. Resolved automatically if not specified."
+    )
+
+
+INCLUDE(cmake/ProjectVersion.cmake)
+resolve_version_variables()
+
+
+SET(PROJECT_VERSION_FLAVOUR "" CACHE STRING "Firmware flavour to build - DEBUG, DEVEL, APLHA, BETA or RC")
+SET(PROJECT_VERSION_FLAVOUR_REVISION "" CACHE STRING "Firmware flavour version, e.g. 1 for RC1, etc")
+
+
+IF( NOT PROJECT_VERSION_FLAVOUR STREQUAL "")
+    SET(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_FLAVOUR}")
+    add_compile_definitions(FW_FLAVOR=${PROJECT_VERSION_FLAVOUR})
+    IF( NOT PROJECT_VERSION_FLAVOUR_REVISION STREQUAL "")
+        SET(PROJECT_VERSION "${PROJECT_VERSION}${PROJECT_VERSION_FLAVOUR_REVISION}")
+        add_compile_definitions(FW_FLAVERSION=${PROJECT_VERSION_FLAVOUR_REVISION})
+    ENDIF()
+ENDIF()
+
+# Inform user about the resolved settings
+MESSAGE(STATUS "Project version: ${PROJECT_VERSION}")
+MESSAGE(
+  STATUS "Project version with short suffix: ${PROJECT_VERSION}${PROJECT_VERSION_SUFFIX_SHORT}"
+  )
+
+SET(FN_PREFIX "FW${PROJECT_VERSION}${PROJECT_VERSION_SUFFIX_SHORT}")
 
 MESSAGE(WARNING     "
 ***************** YOUR ATTENTION PLEASE *****************
@@ -113,7 +157,6 @@ endif()
 
 # enable all warnings (well, not all, but some)
 add_compile_options(-Wsign-compare)
-add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-std=gnu++17>)
 add_compile_options($<$<COMPILE_LANGUAGE:C>:-std=gnu11>)
 
 # support _DEBUG macro (some code uses to recognize debug builds)
@@ -197,7 +240,7 @@ function(fw_add_variant variant_name)
         add_custom_command(
             TARGET ${variant_name}
             POST_BUILD
-            COMMAND ${CMAKE_OBJCOPY} -O ihex ${CMAKE_BINARY_DIR}/${variant_name} ${CMAKE_BINARY_DIR}/${variant_name}-EN_ONLY.hex
+            COMMAND ${CMAKE_OBJCOPY} -O ihex ${CMAKE_BINARY_DIR}/${variant_name} ${CMAKE_BINARY_DIR}/${FN_PREFIX}-${variant_name}-EN_ONLY.hex
             COMMENT "Generating ${variant_name} hex"
         )
 		add_dependencies(ALL_FIRMWARE "${variant_name}")
@@ -258,7 +301,7 @@ function(fw_add_variant variant_name)
 			DEPENDS ${LANG_FINAL_BIN}
 			COMMENT "Generating Hex for language data"
 		)
-		set(LANG_HEX ${CMAKE_BINARY_DIR}/${variant_name}-lang.hex)
+		set(LANG_HEX ${CMAKE_BINARY_DIR}/${FN_PREFIX}-${variant_name}-lang.hex)
 
 		add_custom_target(${variant_name}-languages
 			COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/${variant_name}.hex ${LANG_HEX}
@@ -273,7 +316,7 @@ function(fw_add_variant variant_name)
 		# Non-xflash, e.g. MK2.5
 		foreach(LANG IN LISTS SELECTED_LANGUAGES)
 			SET(LANG_HEX_FN ${variant_name}-en_${LANG})
-			SET(LANG_HEX ${CMAKE_BINARY_DIR}/${LANG_HEX_FN}.hex)
+			SET(LANG_HEX ${CMAKE_BINARY_DIR}/${FN_PREFIX}-${LANG_HEX_FN}.hex)
 			SET(LANG_BIN ${LANG_TMP_DIR}/${variant_name}_${LANG}.bin)
 			SET(LANG_FWBIN_TMP ${LANG_TMP_DIR}/${variant_name}-en_${LANG}.bin)
 
@@ -292,7 +335,7 @@ function(fw_add_variant variant_name)
 				DEPENDS ${LANG_FWBIN_TMP}
 				COMMENT "Creating ${LANG_HEX_FN}.hex"
 			)
-			LIST(APPEND ALL_VARIANT_HEXES ${LANG_HEX})
+			LIST(APPEND ALL_VARIANT_HEXES ${LANG_HEX_FN})
 		endforeach()
 		add_custom_target("${variant_name}-All-Languages"
 			DEPENDS ${ALL_VARIANT_HEXES}

+ 232 - 0
cmake/GetGitRevisionDescription.cmake

@@ -0,0 +1,232 @@
+# * Returns a version string from Git
+#
+# These functions force a re-configure on each git commit so that you can trust the values of the
+# variables in your build system.
+#
+# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
+#
+# Returns the refspec and sha hash of the current head revision
+#
+# git_describe(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe on the source tree, and adjusting the output so that it tests
+# false if an error occurs.
+#
+# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe --exact-match on the source tree, and adjusting the output so
+# that it tests false if there was no exact matching tag.
+#
+# git_local_changes(<var>)
+#
+# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. Uses the return code of
+# "git diff-index --quiet HEAD --". Does not regard untracked files.
+#
+# git_count_parent_commits(<var>)
+#
+# Returns number of commits preceeding current commit -1 if git rev-list --count HEAD failed or
+# "GIT-NOTFOUND" if git executable was not found or "HEAD-HASH-NOTFOUND" if head hash was not found.
+# I don't know if get_git_head_revision() must be called internally or not, as reason of calling it
+# is not clear for me also in git_local_changes().
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author: 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
+# http://academic.cleardefinition.com Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010. Distributed under the Boost Software License, Version
+# 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+if(__get_git_revision_description)
+  return()
+endif()
+set(__get_git_revision_description YES)
+
+# We must run the following at "include" time, not at function call time, to find the path to this
+# module rather than the path to a calling list file
+get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
+
+function(get_git_head_revision _refspecvar _hashvar)
+  set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+  set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+  while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
+    set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
+    get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
+    if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
+      # We have reached the root directory, we are not in git
+      set(${_refspecvar}
+          "GITDIR-NOTFOUND"
+          PARENT_SCOPE
+          )
+      set(${_hashvar}
+          "GITDIR-NOTFOUND"
+          PARENT_SCOPE
+          )
+      return()
+    endif()
+    set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+  endwhile()
+  # check if this is a submodule
+  if(NOT IS_DIRECTORY ${GIT_DIR})
+    file(READ ${GIT_DIR} submodule)
+    string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
+    get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
+    get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
+  endif()
+  set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
+  if(NOT EXISTS "${GIT_DATA}")
+    file(MAKE_DIRECTORY "${GIT_DATA}")
+  endif()
+
+  if(NOT EXISTS "${GIT_DIR}/HEAD")
+    return()
+  endif()
+  set(HEAD_FILE "${GIT_DATA}/HEAD")
+  configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
+
+  configure_file(
+    "${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" "${GIT_DATA}/grabRef.cmake" @ONLY
+    )
+  include("${GIT_DATA}/grabRef.cmake")
+
+  set(${_refspecvar}
+      "${HEAD_REF}"
+      PARENT_SCOPE
+      )
+  set(${_hashvar}
+      "${HEAD_HASH}"
+      PARENT_SCOPE
+      )
+endfunction()
+
+function(git_describe _var)
+  if(NOT GIT_FOUND)
+    find_package(Git QUIET)
+  endif()
+  get_git_head_revision(refspec hash)
+  if(NOT GIT_FOUND)
+    set(${_var}
+        "GIT-NOTFOUND"
+        PARENT_SCOPE
+        )
+    return()
+  endif()
+  if(NOT hash)
+    set(${_var}
+        "HEAD-HASH-NOTFOUND"
+        PARENT_SCOPE
+        )
+    return()
+  endif()
+
+  # TODO sanitize if((${ARGN}" MATCHES "&&") OR (ARGN MATCHES "||") OR (ARGN MATCHES "\\;"))
+  # message("Please report the following error to the project!") message(FATAL_ERROR "Looks like
+  # someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") endif()
+
+  # message(STATUS "Arguments to execute_process: ${ARGN}")
+
+  execute_process(
+    COMMAND "${GIT_EXECUTABLE}" describe ${hash} ${ARGN}
+    WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+    RESULT_VARIABLE res
+    OUTPUT_VARIABLE out
+    ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  if(NOT res EQUAL 0)
+    set(out "${out}-${res}-NOTFOUND")
+  endif()
+
+  set(${_var}
+      "${out}"
+      PARENT_SCOPE
+      )
+endfunction()
+
+function(git_get_exact_tag _var)
+  git_describe(out --exact-match ${ARGN})
+  set(${_var}
+      "${out}"
+      PARENT_SCOPE
+      )
+endfunction()
+
+function(git_local_changes _var)
+  if(NOT GIT_FOUND)
+    find_package(Git QUIET)
+  endif()
+  get_git_head_revision(refspec hash)
+  if(NOT GIT_FOUND)
+    set(${_var}
+        "GIT-NOTFOUND"
+        PARENT_SCOPE
+        )
+    return()
+  endif()
+  if(NOT hash)
+    set(${_var}
+        "HEAD-HASH-NOTFOUND"
+        PARENT_SCOPE
+        )
+    return()
+  endif()
+
+  execute_process(
+    COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
+    WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+    RESULT_VARIABLE res
+    OUTPUT_VARIABLE out
+    ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  if(res EQUAL 0)
+    set(${_var}
+        "CLEAN"
+        PARENT_SCOPE
+        )
+  else()
+    set(${_var}
+        "DIRTY"
+        PARENT_SCOPE
+        )
+  endif()
+endfunction()
+
+function(git_count_parent_commits _var)
+  if(NOT GIT_FOUND)
+    find_package(Git QUIET)
+  endif()
+  get_git_head_revision(refspec hash)
+  if(NOT GIT_FOUND)
+    set(${_var}
+        "GIT-NOTFOUND"
+        PARENT_SCOPE
+        )
+    return()
+  endif()
+  if(NOT hash)
+    set(${_var}
+        "HEAD-HASH-NOTFOUND"
+        PARENT_SCOPE
+        )
+    return()
+  endif()
+
+  execute_process(
+    COMMAND "${GIT_EXECUTABLE}" rev-list --count HEAD
+    WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+    RESULT_VARIABLE res
+    OUTPUT_VARIABLE out
+    ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  if(res EQUAL 0)
+    set(${_var}
+        "${out}"
+        PARENT_SCOPE
+        )
+  else()
+    set(${_var}
+        "-1"
+        PARENT_SCOPE
+        )
+  endif()
+
+endfunction()

+ 37 - 0
cmake/GetGitRevisionDescription.cmake.in

@@ -0,0 +1,37 @@
+#
+# Internal file for GetGitRevisionDescription.cmake
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author: 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
+# http://academic.cleardefinition.com Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010. Distributed under the Boost Software License, Version
+# 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+set(HEAD_HASH)
+
+file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
+
+string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
+if(HEAD_CONTENTS MATCHES "ref")
+  # named branch
+  string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
+  if(EXISTS "@GIT_DIR@/${HEAD_REF}")
+    configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
+  else()
+    configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
+    file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
+    if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
+      set(HEAD_HASH "${CMAKE_MATCH_1}")
+    endif()
+  endif()
+else()
+  # detached HEAD
+  configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
+endif()
+
+if(NOT HEAD_HASH)
+  file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
+  string(STRIP "${HEAD_HASH}" HEAD_HASH)
+endif()

+ 71 - 0
cmake/ProjectVersion.cmake

@@ -0,0 +1,71 @@
+#
+# This file is responsible for setting the following variables:
+#
+# ~~~
+# BUILD_NUMBER (1035)
+# PROJECT_VERSION (4.0.3)
+# PROJECT_VERSION_FULL (4.0.3-BETA+1035.PR111.B4)
+# PROJECT_VERSION_SUFFIX (-BETA+1035.PR111.B4)
+# PROJECT_VERSION_SUFFIX_SHORT (+1035)
+#
+# The `PROJECT_VERSION` variable is set as soon as the file is included.
+# To set the rest, the function `resolve_version_variables` has to be called.
+#
+# ~~~
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/Firmware/Configuration.h CFG_VER_DATA REGEX "#define FW_[A-Z]+ ([0-9]+)" )
+LIST(GET CFG_VER_DATA 0 PROJECT_VERSION_MAJOR)
+LIST(GET CFG_VER_DATA 1 PROJECT_VERSION_MINOR)
+LIST(GET CFG_VER_DATA 2 PROJECT_VERSION_REV)
+STRING(REGEX MATCH "FW_MAJOR ([0-9]+)" PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
+SET(PROJECT_VERSION_MAJOR  "${CMAKE_MATCH_1}")
+
+STRING(REGEX MATCH "FW_MINOR ([0-9]+)" PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
+SET(PROJECT_VERSION_MINOR  ${CMAKE_MATCH_1})
+
+STRING(REGEX MATCH "FW_REVISION +([0-9]+)" PROJECT_VERSION_REV "${PROJECT_VERSION_REV}")
+SET(PROJECT_VERSION_REV  ${CMAKE_MATCH_1})
+
+SET(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_REV}")
+SET(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_REV}" PARENT_SCOPE)
+
+
+function(resolve_version_variables)
+  # BUILD_NUMBER
+  if(NOT BUILD_NUMBER)
+    git_count_parent_commits(BUILD_NUMBER)
+    set(ERRORS "GIT-NOTFOUND" "HEAD-HASH-NOTFOUND")
+    if(BUILD_NUMBER IN_LIST ERRORS)
+      message(WARNING "Failed to resolve build number: ${BUILD_NUMBER}. Setting to zero.")
+      set(BUILD_NUMBER "0")
+    endif()
+    set(BUILD_NUMBER
+        ${BUILD_NUMBER}
+        PARENT_SCOPE
+        )
+  endif()
+
+  # PROJECT_VERSION_SUFFIX
+  if(PROJECT_VERSION_SUFFIX STREQUAL "<auto>")
+    # TODO: set to +<sha>.dirty?.debug?
+    set(PROJECT_VERSION_SUFFIX "+${BUILD_NUMBER}.LOCAL")
+    set(PROJECT_VERSION_SUFFIX
+        "+${BUILD_NUMBER}.LOCAL"
+        PARENT_SCOPE
+        )
+  endif()
+
+  # PROJECT_VERSION_SUFFIX_SHORT
+  if(PROJECT_VERSION_SUFFIX_SHORT STREQUAL "<auto>")
+    set(PROJECT_VERSION_SUFFIX_SHORT
+        "+${BUILD_NUMBER}"
+        PARENT_SCOPE
+        )
+  endif()
+
+  # PROJECT_VERSION_FULL
+  set(PROJECT_VERSION_FULL
+      "${PROJECT_VERSION}${PROJECT_VERSION_SUFFIX}"
+      PARENT_SCOPE
+      )
+endfunction()