eb22826057
CMake master / 3.22 introduced a behavior change in how conditions are evaluated in the while command. It is now consistent with how if() evaluates conditions. This caused an issue in Qt code where a "(" opening parenthesis was evaluated as part of the condition rather than as a string. Fix this by wrapping the evaluation of the variable in quotes. Pick-to: 6.1 6.2 Change-Id: I70c26dc91394f4a14f7a26419df264a069dc7dc5 Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Craig Scott <craig.scott@qt.io>
187 lines
6.7 KiB
CMake
187 lines
6.7 KiB
CMake
# 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})
|
|
|
|
if(NOT arg_OUTPUT)
|
|
message(FATAL_ERROR "No output file provided to qt_configure_file.")
|
|
endif()
|
|
|
|
if(arg_CONTENT)
|
|
set(template_name "QtFileConfigure.txt.in")
|
|
# When building qtbase, use the source template file.
|
|
# Otherwise use the installed file.
|
|
# 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}")
|
|
endif()
|
|
set(__qt_file_configure_content "${arg_CONTENT}")
|
|
elseif(arg_INPUT)
|
|
set(input_file "${arg_INPUT}")
|
|
else()
|
|
message(FATAL_ERROR "No input value provided to qt_configure_file.")
|
|
endif()
|
|
|
|
configure_file("${input_file}" "${arg_OUTPUT}" @ONLY)
|
|
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.
|
|
macro(qt_parse_all_arguments result type flags options multiopts)
|
|
cmake_parse_arguments(${result} "${flags}" "${options}" "${multiopts}" ${ARGN})
|
|
if(DEFINED ${result}_UNPARSED_ARGUMENTS)
|
|
message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${result}_UNPARSED_ARGUMENTS}).")
|
|
endif()
|
|
endmacro()
|
|
|
|
# Print all variables defined in the current scope.
|
|
macro(qt_debug_print_variables)
|
|
cmake_parse_arguments(__arg "DEDUP" "" "MATCH;IGNORE" ${ARGN})
|
|
message("Known Variables:")
|
|
get_cmake_property(__variableNames VARIABLES)
|
|
list (SORT __variableNames)
|
|
if (__arg_DEDUP)
|
|
list(REMOVE_DUPLICATES __variableNames)
|
|
endif()
|
|
|
|
foreach(__var ${__variableNames})
|
|
set(__ignore OFF)
|
|
foreach(__i ${__arg_IGNORE})
|
|
if(__var MATCHES "${__i}")
|
|
set(__ignore ON)
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
|
|
if (__ignore)
|
|
continue()
|
|
endif()
|
|
|
|
set(__show OFF)
|
|
foreach(__i ${__arg_MATCH})
|
|
if(__var MATCHES "${__i}")
|
|
set(__show ON)
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
|
|
if (__show)
|
|
message(" ${__var}=${${__var}}.")
|
|
endif()
|
|
endforeach()
|
|
endmacro()
|
|
|
|
macro(assert)
|
|
if (${ARGN})
|
|
else()
|
|
message(FATAL_ERROR "ASSERT: ${ARGN}.")
|
|
endif()
|
|
endmacro()
|
|
|
|
# Takes a list of path components and joins them into one path separated by forward slashes "/",
|
|
# and saves the path in out_var.
|
|
function(qt_path_join out_var)
|
|
string(JOIN "/" path ${ARGN})
|
|
set(${out_var} ${path} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# qt_remove_args can remove arguments from an existing list of function
|
|
# arguments in order to pass a filtered list of arguments to a different function.
|
|
# 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
|
|
# 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.
|
|
# ARGS: Arguments passed into the function, usually ${ARGV}
|
|
#
|
|
# E.g.:
|
|
# We want to forward all arguments from foo to bar, execpt ZZZ since it will
|
|
# trigger an error in bar.
|
|
#
|
|
# foo(target BAR .... ZZZ .... WWW ...)
|
|
# bar(target BAR.... WWW...)
|
|
#
|
|
# function(foo target)
|
|
# qt_parse_all_arguments(arg "" "" "BAR;ZZZ;WWW ${ARGV})
|
|
# qt_remove_args(forward_args
|
|
# ARGS_TO_REMOVE ${target} ZZZ
|
|
# ALL_ARGS ${target} BAR ZZZ WWW
|
|
# ARGS ${ARGV}
|
|
# )
|
|
# bar(${target} ${forward_args})
|
|
# endfunction()
|
|
#
|
|
function(qt_remove_args out_var)
|
|
cmake_parse_arguments(arg "" "" "ARGS_TO_REMOVE;ALL_ARGS;ARGS" ${ARGN})
|
|
set(result ${arg_ARGS})
|
|
foreach(arg IN LISTS arg_ARGS_TO_REMOVE)
|
|
# find arg
|
|
list(FIND result ${arg} find_result)
|
|
if (NOT find_result EQUAL -1)
|
|
# 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 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(LENGTH result result_len)
|
|
if (NOT find_result EQUAL result_len)
|
|
list(GET result ${find_result} arg_current)
|
|
endif()
|
|
endwhile()
|
|
endif()
|
|
endforeach()
|
|
set(${out_var} "${result}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Creates a regular expression that exactly matches the given string
|
|
# Found in https://gitlab.kitware.com/cmake/cmake/issues/18580
|
|
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()
|