Revision control

++ # Copyright (C) 2026 The Qt Company Ltd.
++ # SPDX-License-Identifier: BSD-3-Clause
++
++ # Manual block to opt out of the include guard.
++ if(NOT QT_NO_CMAKE_INCLUDE_GUARD)
++ include_guard(GLOBAL)
++ endif()
++
++ # An improved re-implementation of `include_guard()`
++ #
++ # Aside from the options that `include_guard` supports, which roughly map to `#pragma once` in C++
++ # (because it operates based on CMAKE_CURRENT_LIST_FILE), the function also supports a string-based
++ # GUARD_KEY option to implement an include guard similar to a C++ `#ifndef` include guard. This
++ # prevents including copies stored at different paths.
++ #
++ # The include guard can be opted out of, by setting QT_NO_CMAKE_INCLUDE_GUARD to ON. Then the macro
++ # is a no-op.
++ #
++ # Synopsis
++ #
++ # __qt_internal_cmake_include_guard(
++ # [GUARD_KEY <key>]
++ # [LOCAL|DIRECTORY|GLOBAL]
++ # )
++ #
++ # Arguments
++ #
++ # `GUARD_KEY`
++ # A string key to identify the include guard. If specified, the include guard is implemented by
++ # setting a global property with a name based on the key, and checking for its existence at the
++ # call site. Currently only works when used in conjunction with `GLOBAL`.
++ # Recommended, because it's more robust than path based checks.
++ #
++ # `LOCAL`
++ # Equivalent to `include_guard()`.
++ #
++ # `DIRECTORY`
++ # Equivalent to `include_guard(DIRECTORY)`.
++ #
++ # `GLOBAL`
++ # Equivalent to `include_guard(GLOBAL)`.
++ #
++ # Notes
++ # The file providing the macro needs to be included early enough, to be available for use in
++ # files that use it.
++ macro(__qt_internal_cmake_include_guard)
++ # Only parse and handle the arguments if the opt is not set.
++ if(NOT QT_NO_CMAKE_INCLUDE_GUARD)
++ set(_qt_cig_opt_args
++ LOCAL
++ DIRECTORY
++ GLOBAL
++ )
++ set(_qt_cig_single_args
++ GUARD_KEY
++ )
++ cmake_parse_arguments(_qt_cig_arg "${_qt_cig_opt_args}" "${_qt_cig_single_args}" "" ${ARGN})
++ if(DEFINED _qt_cig_arg_UNPARSED_ARGUMENTS)
++ message(FATAL_ERROR "__qt_internal_cmake_include_guard "
++ "unknown arguments: '${_qt_cig_arg_UNPARSED_ARGUMENTS}'")
++ endif()
++
++ if(_qt_cig_arg_GUARD_KEY)
++ if(_qt_cig_arg_GLOBAL)
++ # Use a global property to track when to exit early.
++ set(_qt_cig_prop_name "_qt_cmake_include_guard_${_qt_cig_arg_GUARD_KEY}")
++ get_property(_qt_cig_already_included GLOBAL PROPERTY "${_qt_cig_prop_name}")
++ if(_qt_cig_already_included)
++ unset(_qt_cig_prop_name)
++ unset(_qt_cig_already_included)
++
++ # Returns out of the file where the macro was called.
++ return()
++ endif()
++ set_property(GLOBAL PROPERTY "${_qt_cig_prop_name}" "ON")
++ unset(_qt_cig_prop_name)
++ unset(_qt_cig_already_included)
++ else()
++ message(FATAL_ERROR "GUARD_KEY is currently only supported with the GLOBAL option.")
++ endif()
++ else()
++ # For non GUARD_KEY guards, use the default cmake implementation which is based on the
++ # file path / CMAKE_CURRENT_LIST_FILE.
++ if(_qt_cig_arg_GLOBAL)
++ include_guard(GLOBAL)
++ elseif(_qt_cig_arg_DIRECTORY)
++ include_guard(DIRECTORY)
++ elseif(_qt_cig_arg_LOCAL)
++ include_guard()
++ else()
++ message(FATAL_ERROR "One of LOCAL, DIRECTORY or GLOBAL option must be specified.")
++ endif()
++ endif()
++ endif()
++ endmacro()