cmake: Simplify version handling based on git tags

- Use the HEAD commit hash as the default suffix
- Use the output of "describe" as the full version string
- Use the HEAD commit time as SOURCE_DATE_EPOCH
This commit is contained in:
Yuri D'Elia 2022-10-06 12:48:07 +02:00 committed by VintagePC
parent 2e1eb4f84a
commit 80594880cd
3 changed files with 84 additions and 93 deletions

View File

@ -2,60 +2,33 @@ cmake_minimum_required(VERSION 3.19)
include(cmake/Utilities.cmake)
include(cmake/GetGitRevisionDescription.cmake)
include(cmake/ReproducibleBuild.cmake)
include(cmake/ProjectVersion.cmake)
resolve_version_variables()
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>'."
"Version suffix to be appended to the final filename (<ver+PROJECT_VERSION_SUFFIX>). Overrides git hash if set."
)
set(PROJECT_VERSION_SUFFIX_SHORT
if(PROJECT_VERSION_SUFFIX STREQUAL "<auto>")
set(PROJECT_VERSION_SUFFIX "${FW_COMMIT_HASH}")
endif()
set(PROJECT_VERSION_FULL
"<auto>"
CACHE
STRING
"Short version suffix to be shown on splash screen. Defaults to '+<BUILD_NUMBER>' if set to '<auto>'."
"Full version string to be shown on the info screen in settings. Overrides git version if set."
)
set(BUILD_NUMBER
""
CACHE STRING "Build number of the firmware. Resolved automatically if not specified."
)
set(PROJECT_VERSION_TIMESTAMP
""
CACHE STRING "Timestamp for the build. Resolved automatically if not specified."
)
set(CUSTOM_COMPILE_OPTIONS
""
CACHE STRING "Allows adding custom C/C++ flags"
)
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()
if(PROJECT_VERSION_FULL STREQUAL "<auto>")
set(PROJECT_VERSION_FULL "${FW_COMMIT_DSC}")
endif()
set(FN_PREFIX "FW${PROJECT_VERSION}+${PROJECT_VERSION_SUFFIX}")
# 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(STATUS "Project version ...........: ${PROJECT_VERSION}")
message(STATUS "Project version suffix ....: ${PROJECT_VERSION_SUFFIX}")
message(STATUS "Project version description: ${PROJECT_VERSION_FULL}")
# Language configuration
set(MAIN_LANGUAGES
@ -237,8 +210,7 @@ list(TRANSFORM AVR_SOURCES PREPEND ${PRUSA_BOARDS_DIR}/cores/prusa_einsy_rambo/)
# Target configuration
#
if(CMAKE_CROSSCOMPILING)
# set source epoch
set_source_epoch(${PROJECT_VERSION_TIMESTAMP})
set_source_epoch(${FW_COMMIT_DATE})
# default optimization flags
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g")

View File

@ -334,3 +334,27 @@ function(git_head_commit_timestamp _var)
PARENT_SCOPE
)
endfunction()
function(git_head_commit_data _var _format)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" show -s --quiet --format=format:${_format} HEAD
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 "HEAD-FORMAT-NOTFOUND")
endif()
set(${_var}
${out}
PARENT_SCOPE)
endfunction()

View File

@ -1,71 +1,66 @@
#
#[[
# This file is responsible for setting the following variables:
#
# ~~~
# BUILD_NUMBER (1035)
# PROJECT_VERSION_MAJOR (4)
# PROJECT_VERSION_MINOR (0)
# PROJECT_VERSION_REV (3)
# 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)
# PROJECT_VERSION_TIMESTAMP (unix timestamp)
# FW_COMMIT_DSC ("v4.0.3-deadbeef")
# FW_COMMIT_HASH (deadbeef)
# FW_COMMIT_DATE (1665051856)
#
# 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}")
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_MINOR ([0-9]+)" PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
SET(PROJECT_VERSION_MINOR ${CMAKE_MATCH_1})
string(REGEX MATCH "FW_MAJOR ([0-9]+)" PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
set(PROJECT_VERSION_MAJOR "${CMAKE_MATCH_1}")
STRING(REGEX MATCH "FW_REVISION +([0-9]+)" PROJECT_VERSION_REV "${PROJECT_VERSION_REV}")
SET(PROJECT_VERSION_REV ${CMAKE_MATCH_1})
string(REGEX MATCH "FW_MINOR ([0-9]+)" PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_1})
SET(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_REV}")
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}")
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")
if(FW_COMMIT_DSC)
return()
endif()
set(BUILD_NUMBER
${BUILD_NUMBER}
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
git_head_commit_data(FW_COMMIT_HASH "%h")
set(ERRORS "GIT-NOTFOUND" "HEAD-FORMAT-NOTFOUND")
if(FW_COMMIT_HASH IN_LIST ERRORS)
# git not available, set fallback values
set(FW_COMMIT_HASH "UNKNOWN")
set(FW_COMMIT_DSC "v${PROJECT_VERSION}-${FW_COMMIT_HASH}")
string(TIMESTAMP FW_COMMIT_DATE "%s")
else()
git_describe_working_tree(FW_COMMIT_DSC)
git_head_commit_data(FW_COMMIT_DATE "%ct")
endif()
set(FW_COMMIT_DSC
"${FW_COMMIT_DSC}"
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"
set(FW_COMMIT_HASH
"${FW_COMMIT_HASH}"
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}"
set(FW_COMMIT_DATE
"${FW_COMMIT_DATE}"
PARENT_SCOPE
)