summaryrefslogtreecommitdiffstats
path: root/cmake/QtCMakeHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtCMakeHelpers.cmake')
-rw-r--r--cmake/QtCMakeHelpers.cmake120
1 files changed, 102 insertions, 18 deletions
diff --git a/cmake/QtCMakeHelpers.cmake b/cmake/QtCMakeHelpers.cmake
index 261e9cc457..142a003cbc 100644
--- a/cmake/QtCMakeHelpers.cmake
+++ b/cmake/QtCMakeHelpers.cmake
@@ -1,26 +1,27 @@
-# qt_configure_file(OUTPUT output-file <INPUT input-file | CONTENT content>)
-# input-file is relative to ${CMAKE_CURRENT_SOURCE_DIR}
-# output-file is relative to ${CMAKE_CURRENT_BINARY_DIR}
-#
-# This function is similar to file(GENERATE OUTPUT) except it writes the content
-# to the file at configure time, rather than at generate time. Once CMake 3.18 is released, it can use file(CONFIGURE) in its implmenetation. Until then, it
-# uses configure_file() with a generic input file as source, when used with the CONTENT signature.
-function(qt_configure_file)
- qt_parse_all_arguments(arg "qt_configure_file" "" "OUTPUT;INPUT;CONTENT" "" ${ARGN})
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+# The common implementation of qt_configure_file functionality.
+macro(qt_configure_file_impl)
if(NOT arg_OUTPUT)
message(FATAL_ERROR "No output file provided to qt_configure_file.")
endif()
- if(arg_CONTENT)
+ # We use this check for the cases when the specified CONTENT is empty. The value of arg_CONTENT
+ # is undefined, but we still want to create a file with empty content.
+ if(NOT "CONTENT" IN_LIST arg_KEYWORDS_MISSING_VALUES)
+ if(arg_INPUT)
+ message(WARNING "Both CONTENT and INPUT are specified. CONTENT will be used to generate"
+ " output")
+ endif()
set(template_name "QtFileConfigure.txt.in")
# When building qtbase, use the source template file.
- # Otherwise use the installed file.
+ # Otherwise use the installed file (basically wherever Qt6 package is found).
# This should work for non-prefix and superbuilds as well.
if(QtBase_SOURCE_DIR)
set(input_file "${QtBase_SOURCE_DIR}/cmake/${template_name}")
else()
- set(input_file "${Qt6_DIR}/${template_name}")
+ set(input_file "${_qt_6_config_cmake_dir}/${template_name}")
endif()
set(__qt_file_configure_content "${arg_CONTENT}")
elseif(arg_INPUT)
@@ -30,10 +31,29 @@ function(qt_configure_file)
endif()
configure_file("${input_file}" "${arg_OUTPUT}" @ONLY)
+endmacro()
+
+# qt_configure_file(OUTPUT output-file <INPUT input-file | CONTENT content>)
+# input-file is relative to ${CMAKE_CURRENT_SOURCE_DIR}
+# output-file is relative to ${CMAKE_CURRENT_BINARY_DIR}
+#
+# This function is similar to file(GENERATE OUTPUT) except it writes the content
+# to the file at configure time, rather than at generate time.
+#
+# TODO: Once we require 3.18+, this can use file(CONFIGURE) in its implementation,
+# or maybe its usage can be replaced by file(CONFIGURE). Until then, it uses
+# configure_file() with a generic input file as source, when used with the CONTENT
+# signature.
+function(qt_configure_file)
+ cmake_parse_arguments(PARSE_ARGV 0 arg "" "OUTPUT;INPUT;CONTENT" "")
+ qt_configure_file_impl()
endfunction()
# A version of cmake_parse_arguments that makes sure all arguments are processed and errors out
# with a message about ${type} having received unknown arguments.
+#
+# TODO: Remove when all usage of qt_parse_all_arguments were replaced by
+# cmake_parse_all_arguments(PARSEARGV) instances
macro(qt_parse_all_arguments result type flags options multiopts)
cmake_parse_arguments(${result} "${flags}" "${options}" "${multiopts}" ${ARGN})
if(DEFINED ${result}_UNPARSED_ARGUMENTS)
@@ -41,6 +61,14 @@ macro(qt_parse_all_arguments result type flags options multiopts)
endif()
endmacro()
+# Checks whether any unparsed arguments have been passed to the function at the call site.
+# Use this right after `cmake_parse_arguments`.
+function(_qt_internal_validate_all_args_are_parsed prefix)
+ if(DEFINED ${prefix}_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown arguments: (${${prefix}_UNPARSED_ARGUMENTS})")
+ endif()
+endfunction()
+
# Print all variables defined in the current scope.
macro(qt_debug_print_variables)
cmake_parse_arguments(__arg "DEDUP" "" "MATCH;IGNORE" ${ARGN})
@@ -97,8 +125,7 @@ endfunction()
# Parameters:
# out_var: result of remove all arguments specified by ARGS_TO_REMOVE from ALL_ARGS
# ARGS_TO_REMOVE: Arguments to remove.
-# ALL_ARGS: All arguments supplied to cmake_parse_arguments or
-# qt_parse_all_arguments
+# ALL_ARGS: All arguments supplied to cmake_parse_arguments
# from which ARGS_TO_REMOVE should be removed from. We require all the
# arguments or we can't properly identify the range of the arguments detailed
# in ARGS_TO_REMOVE.
@@ -112,7 +139,7 @@ endfunction()
# bar(target BAR.... WWW...)
#
# function(foo target)
-# qt_parse_all_arguments(arg "" "" "BAR;ZZZ;WWW ${ARGV})
+# cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "BAR;ZZZ;WWW")
# qt_remove_args(forward_args
# ARGS_TO_REMOVE ${target} ZZZ
# ALL_ARGS ${target} BAR ZZZ WWW
@@ -131,12 +158,18 @@ function(qt_remove_args out_var)
# remove arg
list(REMOVE_AT result ${find_result})
list(LENGTH result result_len)
+ if(find_result EQUAL result_len)
+ # We removed the last argument, could have been an option keyword
+ continue()
+ endif()
list(GET result ${find_result} arg_current)
- # remove values until we hit another arg
- while(NOT ${arg_current} IN_LIST arg_ALL_ARGS AND find_result LESS result_len)
+ # remove values until we hit another arg or the end of the list
+ while(NOT "${arg_current}" IN_LIST arg_ALL_ARGS AND find_result LESS result_len)
list(REMOVE_AT result ${find_result})
- list(GET result ${find_result} arg_current)
list(LENGTH result result_len)
+ if (NOT find_result EQUAL result_len)
+ list(GET result ${find_result} arg_current)
+ endif()
endwhile()
endif()
endforeach()
@@ -149,3 +182,54 @@ function(qt_re_escape out_var str)
string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" regex "${str}")
set(${out_var} ${regex} PARENT_SCOPE)
endfunction()
+
+# Input: string
+# Output: regex string to match the string case insensitively
+# Example: "Release" -> "^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$"
+#
+# Regular expressions like this are used in cmake_install.cmake files for case-insensitive string
+# comparison.
+function(qt_create_case_insensitive_regex out_var input)
+ set(result "^(")
+ string(LENGTH "${input}" n)
+ math(EXPR n "${n} - 1")
+ foreach(i RANGE 0 ${n})
+ string(SUBSTRING "${input}" ${i} 1 c)
+ string(TOUPPER "${c}" uc)
+ string(TOLOWER "${c}" lc)
+ string(APPEND result "[${uc}${lc}]")
+ endforeach()
+ string(APPEND result ")$")
+ set(${out_var} "${result}" PARENT_SCOPE)
+endfunction()
+
+# Gets a target property, and returns "" if the property was not found
+function(qt_internal_get_target_property out_var target property)
+ get_target_property(result "${target}" "${property}")
+ if("${result}" STREQUAL "result-NOTFOUND")
+ set(result "")
+ endif()
+ set(${out_var} "${result}" PARENT_SCOPE)
+endfunction()
+
+# Creates a wrapper ConfigVersion.cmake file to be loaded by find_package when checking for
+# compatible versions. It expects a ConfigVersionImpl.cmake file in the same directory which will
+# be included to do the regular version checks.
+# The version check result might be overridden by the wrapper.
+# package_name is used by the content of the wrapper file to include the basic package version file.
+# example: Qt6Gui
+# out_path should be the build path where the write the file.
+function(qt_internal_write_qt_package_version_file package_name out_path)
+ set(extra_code "")
+
+ # Need to check for FEATURE_developer_build as well, because QT_FEATURE_developer_build is not
+ # yet available when configuring the file for the BuildInternals package.
+ if(FEATURE_developer_build OR QT_FEATURE_developer_build)
+ string(APPEND extra_code "
+# Disabling version check because Qt was configured with -developer-build.
+set(__qt_disable_package_version_check TRUE)
+set(__qt_disable_package_version_check_due_to_developer_build TRUE)")
+ endif()
+
+ configure_file("${QT_CMAKE_DIR}/QtCMakePackageVersionFile.cmake.in" "${out_path}" @ONLY)
+endfunction()