# Copyright (C) 2024 The Qt Company Ltd. # Copyright (C) 2023-2024 Jochem Rutgers # SPDX-License-Identifier: BSD-3-Clause AND MIT macro(_qt_internal_find_git_package) find_package(Git) endmacro() # Helper to set the various git version variables in the parent scope across multiple return points. macro(_qt_internal_set_git_query_variables) set("${arg_OUT_VAR_PREFIX}git_hash" "${version_git_hash}" PARENT_SCOPE) set("${arg_OUT_VAR_PREFIX}git_hash_short" "${version_git_head}" PARENT_SCOPE) set("${arg_OUT_VAR_PREFIX}git_version" "${git_version}" PARENT_SCOPE) # git version sanitized for file paths. string(REGEX REPLACE "[^-a-zA-Z0-9_.]+" "+" git_version_path "${git_version}") set("${arg_OUT_VAR_PREFIX}git_version_path" "${git_version_path}" PARENT_SCOPE) endmacro() # Caches the results per working-directory in global cmake properties. # Sets the following variables in the outer scope: # - git_hash: Full git hash. # - git_hash_short: Short git hash. # - git_version: Git version string. # - git_version_path: Git version string sanitized for file paths. function(_qt_internal_query_git_version) set(opt_args EMPTY_VALUE_WHEN_NOT_GIT_REPO ) set(single_args WORKING_DIRECTORY OUT_VAR_PREFIX ) set(multi_args "") cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}") _qt_internal_validate_all_args_are_parsed(arg) if(arg_EMPTY_VALUE_WHEN_NOT_GIT_REPO) set(version_git_head "") set(version_git_hash "") set(version_git_branch "") set(version_git_tag "") set(git_version "") else() set(version_git_head "unknown") set(version_git_hash "") set(version_git_branch "dev") set(version_git_tag "") set(git_version "${version_git_head}+${version_git_branch}") endif() if(QT_SBOM_FAKE_GIT_VERSION) set(version_git_head "fakegithead") set(version_git_hash "fakegithash") set(version_git_branch "fakegitbranch") set(version_git_tag "fakegittag") set(git_version "${version_git_head}+${version_git_branch}") _qt_internal_set_git_query_variables() return() endif() if(NOT Git_FOUND) message(STATUS "Git not found, skipping querying git version.") _qt_internal_set_git_query_variables() return() endif() if(arg_WORKING_DIRECTORY) set(working_directory "${arg_WORKING_DIRECTORY}") else() set(working_directory "${PROJECT_SOURCE_DIR}") endif() execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree WORKING_DIRECTORY "${working_directory}" OUTPUT_VARIABLE is_inside_work_tree_output RESULT_VARIABLE is_inside_work_tree_result ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) if((NOT is_inside_work_tree_result EQUAL 0) OR (NOT is_inside_work_tree_output STREQUAL "true")) message(STATUS "Git repo not found, skipping querying git version.") _qt_internal_set_git_query_variables() return() endif() get_cmake_property(git_hash_cache _qt_git_hash_cache_${working_directory}) get_cmake_property(git_hash_short_cache _qt_git_hash_short_cache_${working_directory}) get_cmake_property(git_version_cache _qt_git_version_cache_${working_directory}) get_cmake_property(git_version_path_cache _qt_git_version_path_cache_${working_directory}) if(git_hash_cache) set(git_hash "${git_hash_cache}") set(git_hash_short "${git_hash_short_cache}") set(git_version "${git_version_cache}") set(git_version_path "${git_version_path_cache}") _qt_internal_set_git_query_variables() return() endif() execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD WORKING_DIRECTORY "${working_directory}" OUTPUT_VARIABLE version_git_head ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse HEAD WORKING_DIRECTORY "${working_directory}" OUTPUT_VARIABLE version_git_hash ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD WORKING_DIRECTORY "${working_directory}" OUTPUT_VARIABLE version_git_branch ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND ${GIT_EXECUTABLE} tag --points-at HEAD WORKING_DIRECTORY "${working_directory}" OUTPUT_VARIABLE version_git_tag ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REGEX REPLACE "[ \t\r\n].*$" "" version_git_tag "${version_git_tag}") execute_process( COMMAND ${GIT_EXECUTABLE} status -s WORKING_DIRECTORY "${working_directory}" OUTPUT_VARIABLE version_git_dirty ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT "${version_git_dirty}" STREQUAL "") set(version_git_dirty "+dirty") endif() if(NOT "${version_git_tag}" STREQUAL "") set(git_version "${version_git_tag}") if("${git_version}" MATCHES "^v[0-9]+\.") string(REGEX REPLACE "^v" "" git_version "${git_version}") endif() set(git_version "${git_version}${version_git_dirty}") else() set(git_version "${version_git_head}+${version_git_branch}${version_git_dirty}" ) endif() set_property(GLOBAL PROPERTY _qt_git_hash_cache_${working_directory} "${git_hash}") set_property(GLOBAL PROPERTY _qt_git_hash_short_cache_${working_directory} "${git_hash_short}") set_property(GLOBAL PROPERTY _qt_git_version_cache_${working_directory} "${git_version}") set_property(GLOBAL PROPERTY _qt_git_version_path_cache_${working_directory} "${git_version_path}") _qt_internal_set_git_query_variables() endfunction()