aboutsummaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake')
-rw-r--r--cmake/ECMQueryQt.cmake100
-rw-r--r--cmake/GetGitRevisionDescription.cmake246
-rw-r--r--cmake/GetGitRevisionDescription.cmake.in34
-rw-r--r--cmake/MacOSXBundleInfo.plist.in4
-rw-r--r--cmake/QMakeQuery.cmake14
-rw-r--r--cmake/QtVersionOption.cmake38
-rw-r--r--cmake/QtVersionlessBackport.cmake97
7 files changed, 457 insertions, 76 deletions
diff --git a/cmake/ECMQueryQt.cmake b/cmake/ECMQueryQt.cmake
new file mode 100644
index 00000000..98eb5008
--- /dev/null
+++ b/cmake/ECMQueryQt.cmake
@@ -0,0 +1,100 @@
+# SPDX-FileCopyrightText: 2014 Rohan Garg <rohan16garg@gmail.com>
+# SPDX-FileCopyrightText: 2014 Alex Merry <alex.merry@kde.org>
+# SPDX-FileCopyrightText: 2014-2016 Aleix Pol <aleixpol@kde.org>
+# SPDX-FileCopyrightText: 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
+# SPDX-FileCopyrightText: 2022 Ahmad Samir <a.samir78@gmail.com>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#[=======================================================================[.rst:
+ECMQueryQt
+---------------
+This module can be used to query the installation paths used by Qt.
+
+For Qt5 this uses ``qmake``, and for Qt6 this used ``qtpaths`` (the latter has built-in
+support to query the paths of a target platform when cross-compiling).
+
+This module defines the following function:
+::
+
+ ecm_query_qt(<result_variable> <qt_variable> [TRY])
+
+Passing ``TRY`` will result in the method not making the build fail if the executable
+used for querying has not been found, but instead simply print a warning message and
+return an empty string.
+
+Example usage:
+
+.. code-block:: cmake
+
+ include(ECMQueryQt)
+ ecm_query_qt(bin_dir QT_INSTALL_BINS)
+
+If the call succeeds ``${bin_dir}`` will be set to ``<prefix>/path/to/bin/dir`` (e.g.
+``/usr/lib64/qt/bin/``).
+
+Since: 5.93
+#]=======================================================================]
+
+include(${CMAKE_CURRENT_LIST_DIR}/QtVersionOption.cmake)
+include(CheckLanguage)
+check_language(CXX)
+if (CMAKE_CXX_COMPILER)
+ # Enable the CXX language to let CMake look for config files in library dirs.
+ # See: https://gitlab.kitware.com/cmake/cmake/-/issues/23266
+ enable_language(CXX)
+endif()
+
+if (QT_MAJOR_VERSION STREQUAL "5")
+ # QUIET to accommodate the TRY option
+ find_package(Qt${QT_MAJOR_VERSION}Core QUIET)
+ if(TARGET Qt5::qmake)
+ get_target_property(_qmake_executable_default Qt5::qmake LOCATION)
+
+ set(QUERY_EXECUTABLE ${_qmake_executable_default}
+ CACHE FILEPATH "Location of the Qt5 qmake executable")
+ set(_exec_name_text "Qt5 qmake")
+ set(_cli_option "-query")
+ endif()
+elseif(QT_MAJOR_VERSION STREQUAL "6")
+ # QUIET to accommodate the TRY option
+ find_package(Qt6 COMPONENTS CoreTools QUIET CONFIG)
+ if (TARGET Qt6::qtpaths)
+ get_target_property(_qtpaths_executable Qt6::qtpaths LOCATION)
+
+ set(QUERY_EXECUTABLE ${_qtpaths_executable}
+ CACHE FILEPATH "Location of the Qt6 qtpaths executable")
+ set(_exec_name_text "Qt6 qtpaths")
+ set(_cli_option "--query")
+ endif()
+endif()
+
+function(ecm_query_qt result_variable qt_variable)
+ set(options TRY)
+ set(oneValueArgs)
+ set(multiValueArgs)
+
+ cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(NOT QUERY_EXECUTABLE)
+ if(ARGS_TRY)
+ set(${result_variable} "" PARENT_SCOPE)
+ message(STATUS "No ${_exec_name_text} executable found. Can't check ${qt_variable}")
+ return()
+ else()
+ message(FATAL_ERROR "No ${_exec_name_text} executable found. Can't check ${qt_variable} as required")
+ endif()
+ endif()
+ execute_process(
+ COMMAND ${QUERY_EXECUTABLE} ${_cli_option} "${qt_variable}"
+ RESULT_VARIABLE return_code
+ OUTPUT_VARIABLE output
+ )
+ if(return_code EQUAL 0)
+ string(STRIP "${output}" output)
+ file(TO_CMAKE_PATH "${output}" output_path)
+ set(${result_variable} "${output_path}" PARENT_SCOPE)
+ else()
+ message(WARNING "Failed call: ${_command} \"${qt_variable}\"")
+ message(FATAL_ERROR "${_exec_name_text} call failed: ${return_code}")
+ endif()
+endfunction()
diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake
index 39c2707b..4fbd90db 100644
--- a/cmake/GetGitRevisionDescription.cmake
+++ b/cmake/GetGitRevisionDescription.cmake
@@ -3,7 +3,7 @@
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
-# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
+# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
#
# Returns the refspec and sha hash of the current head revision
#
@@ -12,20 +12,33 @@
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
+# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe on the working tree (--dirty option),
+# and adjusting the output so that it tests false if an error occurs.
+#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
+# git_local_changes(<var>)
+#
+# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
+# Uses the return code of "git diff-index --quiet HEAD --".
+# Does not regard untracked files.
+#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
-# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
+# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
# http://academic.cleardefinition.com
-# Iowa State University HCI Graduate Program/VRAC
#
-# Copyright Iowa State University 2009-2010.
+# Copyright 2009-2013, Iowa State University.
+# Copyright 2013-2020, Ryan Pavlik
+# Copyright 2013-2020, Contributors
+# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
@@ -39,45 +52,124 @@ set(__get_git_revision_description YES)
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
-function(get_git_head_revision _refspecvar _hashvar)
- set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
- set(GIT_DIR "${GIT_PARENT_DIR}/.git")
- while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
- set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
- get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
- if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
+# Function _git_find_closest_git_dir finds the next closest .git directory
+# that is part of any directory in the path defined by _start_dir.
+# The result is returned in the parent scope variable whose name is passed
+# as variable _git_dir_var. If no .git directory can be found, the
+# function returns an empty string via _git_dir_var.
+#
+# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
+# neither foo nor bar contain a file/directory .git. This wil return
+# C:/bla/.git
+#
+function(_git_find_closest_git_dir _start_dir _git_dir_var)
+ set(cur_dir "${_start_dir}")
+ set(git_dir "${_start_dir}/.git")
+ while(NOT EXISTS "${git_dir}")
+ # .git dir not found, search parent directories
+ set(git_previous_parent "${cur_dir}")
+ get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
+ if(cur_dir STREQUAL git_previous_parent)
# We have reached the root directory, we are not in git
- set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
- set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
+ set(${_git_dir_var}
+ ""
+ PARENT_SCOPE)
return()
endif()
- set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+ set(git_dir "${cur_dir}/.git")
endwhile()
- # check if this is a submodule
+ set(${_git_dir_var}
+ "${git_dir}"
+ PARENT_SCOPE)
+endfunction()
+
+function(get_git_head_revision _refspecvar _hashvar)
+ _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
+
+ if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
+ set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
+ else()
+ set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
+ endif()
+ if(NOT "${GIT_DIR}" STREQUAL "")
+ file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
+ "${GIT_DIR}")
+ if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
+ # We've gone above the CMake root dir.
+ set(GIT_DIR "")
+ endif()
+ endif()
+ if("${GIT_DIR}" STREQUAL "")
+ set(${_refspecvar}
+ "GITDIR-NOTFOUND"
+ PARENT_SCOPE)
+ set(${_hashvar}
+ "GITDIR-NOTFOUND"
+ PARENT_SCOPE)
+ return()
+ endif()
+
+ # Check if the current source dir is a git submodule or a worktree.
+ # In both cases .git is a file instead of a directory.
+ #
if(NOT IS_DIRECTORY ${GIT_DIR})
- file(READ ${GIT_DIR} submodule)
- string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
- get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
- get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
+ # The following git command will return a non empty string that
+ # points to the super project working tree if the current
+ # source dir is inside a git submodule.
+ # Otherwise the command will return an empty string.
+ #
+ execute_process(
+ COMMAND "${GIT_EXECUTABLE}" rev-parse
+ --show-superproject-working-tree
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ OUTPUT_VARIABLE out
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT "${out}" STREQUAL "")
+ # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
+ file(READ ${GIT_DIR} submodule)
+ string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
+ ${submodule})
+ string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
+ get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
+ get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
+ ABSOLUTE)
+ set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
+ else()
+ # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
+ file(READ ${GIT_DIR} worktree_ref)
+ # The .git directory contains a path to the worktree information directory
+ # inside the parent git repo of the worktree.
+ #
+ string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
+ ${worktree_ref})
+ string(STRIP ${git_worktree_dir} git_worktree_dir)
+ _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
+ set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
+ endif()
+ else()
+ set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
- if(NOT EXISTS "${GIT_DIR}/HEAD")
+ if(NOT EXISTS "${HEAD_SOURCE_FILE}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
- configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
+ configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
- "${GIT_DATA}/grabRef.cmake"
- @ONLY)
+ "${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
- set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
- set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
+ set(${_refspecvar}
+ "${HEAD_REF}"
+ PARENT_SCOPE)
+ set(${_hashvar}
+ "${HEAD_HASH}"
+ PARENT_SCOPE)
endfunction()
function(git_describe _var)
@@ -86,45 +178,107 @@ function(git_describe _var)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
- set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
+ set(${_var}
+ "GIT-NOTFOUND"
+ PARENT_SCOPE)
return()
endif()
if(NOT hash)
- set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
+ set(${_var}
+ "HEAD-HASH-NOTFOUND"
+ PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
- # (ARGN MATCHES "||") OR
- # (ARGN MATCHES "\\;"))
- # message("Please report the following error to the project!")
- # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
+ # (ARGN MATCHES "||") OR
+ # (ARGN MATCHES "\\;"))
+ # message("Please report the following error to the project!")
+ # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
- execute_process(COMMAND
- "${GIT_EXECUTABLE}"
- describe
- ${hash}
- ${ARGN}
- WORKING_DIRECTORY
- "${CMAKE_CURRENT_SOURCE_DIR}"
- RESULT_VARIABLE
- res
- OUTPUT_VARIABLE
- out
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(
+ COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
+ 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 "${out}-${res}-NOTFOUND")
endif()
- set(${_var} "${out}" PARENT_SCOPE)
+ set(${_var}
+ "${out}"
+ PARENT_SCOPE)
+endfunction()
+
+function(git_describe_working_tree _var)
+ 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}" describe --dirty ${ARGN}
+ 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 "${out}-${res}-NOTFOUND")
+ endif()
+
+ set(${_var}
+ "${out}"
+ PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
- set(${_var} "${out}" PARENT_SCOPE)
+ set(${_var}
+ "${out}"
+ PARENT_SCOPE)
+endfunction()
+
+function(git_local_changes _var)
+ if(NOT GIT_FOUND)
+ find_package(Git QUIET)
+ endif()
+ get_git_head_revision(refspec hash)
+ if(NOT GIT_FOUND)
+ set(${_var}
+ "GIT-NOTFOUND"
+ PARENT_SCOPE)
+ return()
+ endif()
+ if(NOT hash)
+ set(${_var}
+ "HEAD-HASH-NOTFOUND"
+ PARENT_SCOPE)
+ return()
+ endif()
+
+ execute_process(
+ COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ RESULT_VARIABLE res
+ OUTPUT_VARIABLE out
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(res EQUAL 0)
+ set(${_var}
+ "CLEAN"
+ PARENT_SCOPE)
+ else()
+ set(${_var}
+ "DIRTY"
+ PARENT_SCOPE)
+ endif()
endfunction()
diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in
index 04db9a8e..116efc4e 100644
--- a/cmake/GetGitRevisionDescription.cmake.in
+++ b/cmake/GetGitRevisionDescription.cmake.in
@@ -8,10 +8,12 @@
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
-# Copyright Iowa State University 2009-2010.
+# Copyright 2009-2012, Iowa State University
+# Copyright 2011-2015, Contributors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
+# SPDX-License-Identifier: BSL-1.0
set(HEAD_HASH)
@@ -19,23 +21,23 @@ file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
- # named branch
- string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
- if(EXISTS "@GIT_DIR@/${HEAD_REF}")
- configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
- else()
- configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
- file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
- if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
- set(HEAD_HASH "${CMAKE_MATCH_1}")
- endif()
- endif()
+ # named branch
+ string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
+ if(EXISTS "@GIT_DIR@/${HEAD_REF}")
+ configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
+ else()
+ configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
+ file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
+ if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
+ set(HEAD_HASH "${CMAKE_MATCH_1}")
+ endif()
+ endif()
else()
- # detached HEAD
- configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
+ # detached HEAD
+ configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
- file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
- string(STRIP "${HEAD_HASH}" HEAD_HASH)
+ file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
+ string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()
diff --git a/cmake/MacOSXBundleInfo.plist.in b/cmake/MacOSXBundleInfo.plist.in
index 9e663d31..1b22e21f 100644
--- a/cmake/MacOSXBundleInfo.plist.in
+++ b/cmake/MacOSXBundleInfo.plist.in
@@ -40,5 +40,9 @@
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>SUPublicEDKey</key>
+ <string>${MACOSX_SPARKLE_UPDATE_PUBLIC_KEY}</string>
+ <key>SUFeedURL</key>
+ <string>${MACOSX_SPARKLE_UPDATE_FEED_URL}</string>
</dict>
</plist>
diff --git a/cmake/QMakeQuery.cmake b/cmake/QMakeQuery.cmake
deleted file mode 100644
index bf0fe967..00000000
--- a/cmake/QMakeQuery.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-if(__QMAKEQUERY_CMAKE__)
- return()
-endif()
-set(__QMAKEQUERY_CMAKE__ TRUE)
-
-get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION)
-
-function(QUERY_QMAKE VAR RESULT)
- exec_program(${QMAKE_EXECUTABLE} ARGS "-query ${VAR}" RETURN_VALUE return_code OUTPUT_VARIABLE output )
- if(NOT return_code)
- file(TO_CMAKE_PATH "${output}" output)
- set(${RESULT} ${output} PARENT_SCOPE)
- endif(NOT return_code)
-endfunction(QUERY_QMAKE)
diff --git a/cmake/QtVersionOption.cmake b/cmake/QtVersionOption.cmake
new file mode 100644
index 00000000..1390f9db
--- /dev/null
+++ b/cmake/QtVersionOption.cmake
@@ -0,0 +1,38 @@
+#.rst:
+# QtVersionOption
+# ---------------
+#
+# Adds a build option to select the major Qt version if necessary,
+# that is, if the major Qt version has not yet been determined otherwise
+# (e.g. by a corresponding find_package() call).
+#
+# This module is typically included by other modules requiring knowledge
+# about the major Qt version.
+#
+# ``QT_MAJOR_VERSION`` is defined to either be "5" or "6".
+#
+#
+# Since 5.82.0.
+
+#=============================================================================
+# SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (DEFINED QT_MAJOR_VERSION)
+ return()
+endif()
+
+if (TARGET Qt5::Core)
+ set(QT_MAJOR_VERSION 5)
+elseif (TARGET Qt6::Core)
+ set(QT_MAJOR_VERSION 6)
+else()
+ option(BUILD_WITH_QT6 "Build against Qt 6" OFF)
+
+ if (BUILD_WITH_QT6)
+ set(QT_MAJOR_VERSION 6)
+ else()
+ set(QT_MAJOR_VERSION 5)
+ endif()
+endif()
diff --git a/cmake/QtVersionlessBackport.cmake b/cmake/QtVersionlessBackport.cmake
new file mode 100644
index 00000000..46792db5
--- /dev/null
+++ b/cmake/QtVersionlessBackport.cmake
@@ -0,0 +1,97 @@
+#=============================================================================
+# Copyright 2005-2011 Kitware, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Kitware, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#=============================================================================
+
+# From Qt5CoreMacros.cmake
+
+function(qt_generate_moc)
+ if(QT_VERSION_MAJOR EQUAL 5)
+ qt5_generate_moc(${ARGV})
+ elseif(QT_VERSION_MAJOR EQUAL 6)
+ qt6_generate_moc(${ARGV})
+ endif()
+endfunction()
+
+function(qt_wrap_cpp outfiles)
+ if(QT_VERSION_MAJOR EQUAL 5)
+ qt5_wrap_cpp("${outfiles}" ${ARGN})
+ elseif(QT_VERSION_MAJOR EQUAL 6)
+ qt6_wrap_cpp("${outfiles}" ${ARGN})
+ endif()
+ set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
+endfunction()
+
+function(qt_add_binary_resources)
+ if(QT_VERSION_MAJOR EQUAL 5)
+ qt5_add_binary_resources(${ARGV})
+ elseif(QT_VERSION_MAJOR EQUAL 6)
+ qt6_add_binary_resources(${ARGV})
+ endif()
+endfunction()
+
+function(qt_add_resources outfiles)
+ if(QT_VERSION_MAJOR EQUAL 5)
+ qt5_add_resources("${outfiles}" ${ARGN})
+ elseif(QT_VERSION_MAJOR EQUAL 6)
+ qt6_add_resources("${outfiles}" ${ARGN})
+ endif()
+ set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
+endfunction()
+
+function(qt_add_big_resources outfiles)
+ if(QT_VERSION_MAJOR EQUAL 5)
+ qt5_add_big_resources(${outfiles} ${ARGN})
+ elseif(QT_VERSION_MAJOR EQUAL 6)
+ qt6_add_big_resources(${outfiles} ${ARGN})
+ endif()
+ set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
+endfunction()
+
+function(qt_import_plugins)
+ if(QT_VERSION_MAJOR EQUAL 5)
+ qt5_import_plugins(${ARGV})
+ elseif(QT_VERSION_MAJOR EQUAL 6)
+ qt6_import_plugins(${ARGV})
+ endif()
+endfunction()
+
+
+# From Qt5WidgetsMacros.cmake
+
+function(qt_wrap_ui outfiles)
+ if(QT_VERSION_MAJOR EQUAL 5)
+ qt5_wrap_ui("${outfiles}" ${ARGN})
+ elseif(QT_VERSION_MAJOR EQUAL 6)
+ qt6_wrap_ui("${outfiles}" ${ARGN})
+ endif()
+ set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
+endfunction()
+