1# SPDX-License-Identifier: BSD-3-Clause 2 3# Generates header for which version is taken from (in order of precedence): 4# 1) .tarball-version file 5# 2) git 6# 7# Version is checked during configuration step and for every target 8# that has check_version_h target as dependency 9 10cmake_minimum_required(VERSION 3.10) 11 12set(VERSION_CMAKE_PATH ${CMAKE_CURRENT_LIST_DIR}/version.cmake) 13 14 15# In an ideal world, every CI engine records the most basic and most 16# important information: 17# - current date and time 18# - git version of the pull request 19# - git version of the moving branch it's being merged with 20# 21# In the real world, some CI results use a random timezone without 22# telling which one or don't provide any time at all. 23string(TIMESTAMP build_start_time UTC) 24message(STATUS "version.cmake starting SOF build at ${build_start_time} UTC") 25 26# Most CI engines test a temporary merge of the pull request with a 27# moving target: the latest target branch. In that case the SHA version 28# gathered by git describe is disposable hence useless. Only the 29# --parents SHA are useful. 30message(STATUS "Building git commit with parent(s):") 31# Note execute_process() failures are ignored by default (missing git...) 32execute_process( 33 COMMAND git log --parents --oneline --decorate -n 1 HEAD 34 ) 35 36 37# Don't confuse this manual _input_ file with the other, output file of 38# the same name auto-generated in the top _build_ directory by "make 39# dist", see dist.cmake 40set(TARBALL_VERSION_FILE_NAME ".tarball-version") 41set(TARBALL_VERSION_SOURCE_PATH "${SOF_ROOT_SOURCE_DIRECTORY}/${TARBALL_VERSION_FILE_NAME}") 42 43if(EXISTS ${TARBALL_VERSION_SOURCE_PATH}) 44 file(STRINGS ${TARBALL_VERSION_SOURCE_PATH} lines ENCODING "UTF-8") 45 list(GET lines 0 GIT_TAG) 46 list(GET lines 1 GIT_LOG_HASH) 47 message(STATUS "Found ${TARBALL_VERSION_FILE_NAME}") 48else() 49 # execute_process() errors are not fatal by default! 50 execute_process( 51 COMMAND git describe --tags --abbrev=12 --match v* --dirty 52 WORKING_DIRECTORY ${SOF_ROOT_SOURCE_DIRECTORY} 53 OUTPUT_VARIABLE GIT_TAG 54 OUTPUT_STRIP_TRAILING_WHITESPACE 55 ) 56 57 execute_process(COMMAND git log --pretty=format:%h -1 58 WORKING_DIRECTORY ${SOF_ROOT_SOURCE_DIRECTORY} 59 OUTPUT_VARIABLE GIT_LOG_HASH 60 OUTPUT_STRIP_TRAILING_WHITESPACE 61 ) 62endif() 63 64if(NOT GIT_TAG MATCHES "^v") 65 message(WARNING 66 "git describe found ${GIT_TAG} / nothing starting with 'v'. Shallow clone?") 67 set(GIT_TAG "v0.0-0-g0000") 68endif() 69 70message(STATUS "GIT_TAG / GIT_LOG_HASH : ${GIT_TAG} / ${GIT_LOG_HASH}") 71 72string(REGEX MATCH "^v([0-9]+)[.]([0-9]+)([.]([0-9]+))?" ignored "${GIT_TAG}") 73set(SOF_MAJOR ${CMAKE_MATCH_1}) 74set(SOF_MINOR ${CMAKE_MATCH_2}) 75set(SOF_MICRO ${CMAKE_MATCH_4}) 76 77if(NOT SOF_MICRO MATCHES "^[0-9]+$") 78 set(SOF_MICRO 0) 79endif() 80 81string(SUBSTRING "${GIT_LOG_HASH}" 0 5 SOF_TAG) 82if(NOT SOF_TAG) 83 set(SOF_TAG 0) 84endif() 85 86# Calculate source hash value, used to check ldc file and firmware compatibility 87if(EXISTS ${SOF_ROOT_SOURCE_DIRECTORY}/.git/) 88 set(SOURCE_HASH_DIR "${SOF_ROOT_BINARY_DIRECTORY}/source_hash") 89 file(MAKE_DIRECTORY ${SOURCE_HASH_DIR}) 90 # list tracked files from src directory 91 execute_process(COMMAND git ls-files src 92 WORKING_DIRECTORY ${SOF_ROOT_SOURCE_DIRECTORY} 93 OUTPUT_FILE "${SOURCE_HASH_DIR}/tracked_file_list" 94 ) 95 # calculate hash of each listed files (from file version saved in file system) 96 execute_process(COMMAND git hash-object --stdin-paths 97 WORKING_DIRECTORY ${SOF_ROOT_SOURCE_DIRECTORY} 98 INPUT_FILE "${SOURCE_HASH_DIR}/tracked_file_list" 99 OUTPUT_FILE "${SOURCE_HASH_DIR}/tracked_file_hash_list" 100 ) 101 # then calculate single hash of previously calculated hash list 102 execute_process(COMMAND git hash-object --stdin 103 WORKING_DIRECTORY ${SOF_ROOT_SOURCE_DIRECTORY} 104 OUTPUT_STRIP_TRAILING_WHITESPACE 105 INPUT_FILE "${SOURCE_HASH_DIR}/tracked_file_hash_list" 106 OUTPUT_VARIABLE SOF_SRC_HASH_LONG 107 ) 108 string(SUBSTRING ${SOF_SRC_HASH_LONG} 0 8 SOF_SRC_HASH) 109 message(STATUS "Source content hash: ${SOF_SRC_HASH}") 110else() 111 if("${GIT_LOG_HASH}") 112 string(SUBSTRING "${GIT_LOG_HASH}" 0 8 SOF_SRC_HASH) 113 else() 114 set(SOF_SRC_HASH "0") 115 endif() 116 message(WARNING "Source content hash not computed without git, using GIT_LOG_HASH instead") 117endif() 118 119# for SOF_BUILD 120include(${CMAKE_CURRENT_LIST_DIR}/version-build-counter.cmake) 121 122function(sof_check_version_h) 123 string(CONCAT header_content 124 "#define SOF_MAJOR ${SOF_MAJOR}\n" 125 "#define SOF_MINOR ${SOF_MINOR}\n" 126 "#define SOF_MICRO ${SOF_MICRO}\n" 127 "#define SOF_TAG \"${SOF_TAG}\"\n" 128 "#define SOF_BUILD ${SOF_BUILD}\n" 129 "#define SOF_GIT_TAG \"${GIT_TAG}\"\n" 130 "#define SOF_SRC_HASH 0x${SOF_SRC_HASH}\n" 131 ) 132 133 if(EXISTS "${VERSION_H_PATH}") 134 file(READ "${VERSION_H_PATH}" old_version_content) 135 if("${header_content}" STREQUAL "${old_version_content}") 136 message(STATUS "Up-to-date ${VERSION_H_PATH}") 137 return() 138 endif() 139 endif() 140 141 message(STATUS "Generating ${VERSION_H_PATH}") 142 file(WRITE "${VERSION_H_PATH}" "${header_content}") 143endfunction() 144 145# Run these only if not run as script 146if("${CMAKE_SCRIPT_MODE_FILE}" STREQUAL "") 147 add_custom_target( 148 check_version_h 149 BYPRODUCTS ${VERSION_H_PATH} 150 COMMAND ${CMAKE_COMMAND} 151 -DVERSION_H_PATH=${VERSION_H_PATH} 152 -DSOF_ROOT_SOURCE_DIRECTORY=${SOF_ROOT_SOURCE_DIRECTORY} 153 -DSOF_ROOT_BINARY_DIRECTORY=${SOF_ROOT_BINARY_DIRECTORY} 154 -P ${VERSION_CMAKE_PATH} 155 COMMENT "Checking ${VERSION_H_PATH}" 156 VERBATIM 157 USES_TERMINAL 158 ) 159endif() 160 161sof_check_version_h() 162