From 91709778a4878c80e96e1435a047964725ee3517 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 4 Feb 2022 10:27:13 +0100 Subject: [PATCH] cmake: version.h generation performed at build time Fixes: #39503 Fixes: #40167 This commit moves `BUILD_VERSION` CMake variable from a compile definition to be a define inside version.h. Besides the benefit of having related settings grouped in a common header, it also means that an updated `BUILD_VERSION` value does not need to trigger re-compilation of all source files. When using compile definitions, CMake cannot tell whether a given source files uses the definition or not, and hence all sources must be recompiled to be sure they are up-to-date. Placing `BUILD_VERSION` in version.h, the source dependencies ensures that only source files including `version.h` gets recompiled. As part of this, version.h generation is moved so that it is now done at build time. This means that re-generation of version.h is no longer depending on a CMake re-run but can have it's own dependency in `.git/index` when git described is used to obtain `BUILD_VERSION` information. Generation of logging dictionary database has been updated to support BUILD_VERSION from header file instead of CMake configure time variable. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 28 ++++++++++++------- cmake/app/boilerplate.cmake | 1 - cmake/gen_version_h.cmake | 26 ++++++++++++++++++ cmake/git.cmake | 31 ---------------------- scripts/logging/dictionary/database_gen.py | 11 ++++++++ version.h.in | 6 ++++- 6 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 cmake/gen_version_h.cmake delete mode 100644 cmake/git.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e2dec1e22b..017f27289e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,12 +145,6 @@ if(CONFIG_STACK_CANARIES) zephyr_compile_options($) endif() -if(BUILD_VERSION) - zephyr_compile_definitions( - BUILD_VERSION=${BUILD_VERSION} - ) -endif() - # @Intent: Obtain compiler optimizations flags and store in variables # @details: # Kconfig.zephyr "Optimization level" is a kconfig choice, ensuring @@ -435,7 +429,23 @@ if(NOT EXISTS ${LINKER_SCRIPT}) message(FATAL_ERROR "Could not find linker script: '${LINKER_SCRIPT}'. Corrupted configuration?") endif() -configure_file(version.h.in ${PROJECT_BINARY_DIR}/include/generated/version.h) +if(DEFINED BUILD_VERSION) + set(build_version_argument "-DBUILD_VERSION=${BUILD_VERSION}") +elseif(EXISTS ${ZEPHYR_BASE}/.git/index) + set(git_dependency ${ZEPHYR_BASE}/.git/index) +else() + message(WARNING "ZEPHYR_BASE=${ZEPHYR_BASE} doesn't appear to be a git " + "repository, please specify '-DBUILD_VERSION='") +endif() +add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/include/generated/version.h + COMMAND ${CMAKE_COMMAND} -DZEPHYR_BASE=${ZEPHYR_BASE} + -DOUT_FILE=${PROJECT_BINARY_DIR}/include/generated/version.h + ${build_version_argument} + -P ${ZEPHYR_BASE}/cmake/gen_version_h.cmake + DEPENDS ${ZEPHYR_BASE}/VERSION ${git_dependency} +) +add_custom_target(version_h DEPENDS ${PROJECT_BINARY_DIR}/include/generated/version.h) # Error-out when the deprecated naming convention is found (until # after 1.14.0 has been released) @@ -705,7 +715,7 @@ gen_kobj(KOBJ_INCLUDE_PATH) add_custom_target(zephyr_generated_headers) add_dependencies(zephyr_generated_headers - offsets_h + offsets_h version_h ) # Generate offsets.c.obj from offsets.c @@ -1652,7 +1662,7 @@ if(CONFIG_LOG_DICTIONARY_SUPPORT) ${ZEPHYR_BASE}/scripts/logging/dictionary/database_gen.py ${KERNEL_ELF_NAME} ${LOG_DICT_DB_NAME} - --build ${BUILD_VERSION} + --build-header ${PROJECT_BINARY_DIR}/include/generated/version.h ) list(APPEND post_build_byproducts diff --git a/cmake/app/boilerplate.cmake b/cmake/app/boilerplate.cmake index 8452dd27652..ba8e0ca7b4b 100644 --- a/cmake/app/boilerplate.cmake +++ b/cmake/app/boilerplate.cmake @@ -139,7 +139,6 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${AUTOCONF_H}) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(${ZEPHYR_BASE}/cmake/extensions.cmake) -include(${ZEPHYR_BASE}/cmake/git.cmake) include(${ZEPHYR_BASE}/cmake/version.cmake) # depends on hex.cmake # diff --git a/cmake/gen_version_h.cmake b/cmake/gen_version_h.cmake new file mode 100644 index 00000000000..f27431f05e3 --- /dev/null +++ b/cmake/gen_version_h.cmake @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +if(NOT DEFINED BUILD_VERSION) + find_package(Git QUIET) + if(GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --abbrev=12 --always + WORKING_DIRECTORY ${ZEPHYR_BASE} + OUTPUT_VARIABLE BUILD_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ERROR_VARIABLE stderr + RESULT_VARIABLE return_code + ) + if(return_code) + message(STATUS "git describe failed: ${stderr}") + elseif(NOT "${stderr}" STREQUAL "") + message(STATUS "git describe warned: ${stderr}") + endif() + endif() +endif() + +include(${ZEPHYR_BASE}/cmake/version.cmake) +configure_file(${ZEPHYR_BASE}/version.h.in ${OUT_FILE}) diff --git a/cmake/git.cmake b/cmake/git.cmake deleted file mode 100644 index fa79e30a54a..00000000000 --- a/cmake/git.cmake +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -#.rst: -# git.cmake -# --------- -# If the user didn't already define BUILD_VERSION then try to initialize -# it with the output of "git describe". Warn but don't error if -# everything fails and leave BUILD_VERSION undefined. -# -# See also: independent and more static ``KERNEL_VERSION_*`` in -# ``version.cmake`` and ``kernel_version.h`` - - -# https://cmake.org/cmake/help/latest/module/FindGit.html -find_package(Git QUIET) -if(NOT DEFINED BUILD_VERSION AND GIT_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} describe --abbrev=12 --always - WORKING_DIRECTORY ${ZEPHYR_BASE} - OUTPUT_VARIABLE BUILD_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE stderr - RESULT_VARIABLE return_code - ) - if(return_code) - message(STATUS "git describe failed: ${stderr}") - elseif(NOT "${stderr}" STREQUAL "") - message(STATUS "git describe warned: ${stderr}") - endif() -endif() diff --git a/scripts/logging/dictionary/database_gen.py b/scripts/logging/dictionary/database_gen.py index ba1f73cb5c2..b4c7f0cfefa 100755 --- a/scripts/logging/dictionary/database_gen.py +++ b/scripts/logging/dictionary/database_gen.py @@ -15,6 +15,7 @@ with the parser to decode binary log messages. import argparse import logging import os +import re import struct import sys @@ -47,6 +48,8 @@ def parse_args(): argparser.add_argument("elffile", help="Zephyr ELF binary") argparser.add_argument("dbfile", help="Dictionary Logging Database file") argparser.add_argument("--build", help="Build ID") + argparser.add_argument("--build-header", + help="Header file containing BUILD_VERSION define") argparser.add_argument("--debug", action="store_true", help="Print extra debugging information") argparser.add_argument("-v", "--verbose", action="store_true", @@ -264,6 +267,14 @@ def main(): database = LogDatabase() + if args.build_header: + with open(args.build_header) as f: + for l in f: + match = re.match(r'\s*#define\s+BUILD_VERSION\s+(.*)', l) + if match: + database.set_build_id(match.group(1)) + break + if args.build: database.set_build_id(args.build) logger.info("Build ID: %s", args.build) diff --git a/version.h.in b/version.h.in index 4cb43adcb44..2099c57a0c9 100644 --- a/version.h.in +++ b/version.h.in @@ -1,7 +1,9 @@ #ifndef _KERNEL_VERSION_H_ #define _KERNEL_VERSION_H_ -/* @templates@ values come from cmake/version.cmake */ +/* KERNEL and ZEPHYR_VERSION @templates@ values come from cmake/version.cmake + * BUILD_VERSION @template@ will be 'git describe', alternatively user defined BUILD_VERSION. + */ #cmakedefine ZEPHYR_VERSION_CODE @ZEPHYR_VERSION_CODE@ #define ZEPHYR_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) @@ -13,4 +15,6 @@ #define KERNEL_PATCHLEVEL @KERNEL_PATCHLEVEL@ #define KERNEL_VERSION_STRING @KERNEL_VERSION_STRING@ +#define BUILD_VERSION @BUILD_VERSION@ + #endif /* _KERNEL_VERSION_H_ */