diff options
Diffstat (limited to 'cmake/QtProcessConfigureArgs.cmake')
-rw-r--r-- | cmake/QtProcessConfigureArgs.cmake | 257 |
1 files changed, 224 insertions, 33 deletions
diff --git a/cmake/QtProcessConfigureArgs.cmake b/cmake/QtProcessConfigureArgs.cmake index 6342df93bd..c64403b209 100644 --- a/cmake/QtProcessConfigureArgs.cmake +++ b/cmake/QtProcessConfigureArgs.cmake @@ -1,3 +1,6 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + # This script reads Qt configure arguments from config.opt, # translates the arguments to CMake arguments and calls CMake. # @@ -25,12 +28,37 @@ macro(pop_path_argument) file(TO_CMAKE_PATH "${path}" path) endmacro() +function(is_non_empty_valid_arg arg value) + if(value STREQUAL "") + message(FATAL_ERROR "Value supplied to command line option '${arg}' is empty.") + elseif(value MATCHES "^-.*") + message(FATAL_ERROR + "Value supplied to command line option '${arg}' is invalid: ${value}") + endif() +endfunction() + +function(warn_in_per_repo_build arg) + if(NOT TOP_LEVEL) + message(WARNING "Command line option ${arg} is only effective in top-level builds") + endif() +endfunction() + +function(is_valid_qt_hex_version arg version) + if(NOT version MATCHES "^0x[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$") + message(FATAL_ERROR "Incorrect version ${version} specified for ${arg}") + endif() +endfunction() + if("${MODULE_ROOT}" STREQUAL "") # If MODULE_ROOT is not set, assume that we want to build qtbase or top-level. get_filename_component(MODULE_ROOT ".." ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}") set(qtbase_or_top_level_build TRUE) else() - file(TO_CMAKE_PATH "${MODULE_ROOT}" MODULE_ROOT) + # If MODULE_ROOT is passed without drive letter, we try to add it to the path. + # The check is necessary; otherwise, `get_filename_component` returns an empty string. + if(NOT MODULE_ROOT STREQUAL ".") + get_filename_component(MODULE_ROOT "." REALPATH BASE_DIR "${MODULE_ROOT}") + endif() set(qtbase_or_top_level_build FALSE) endif() set(configure_filename "configure.cmake") @@ -54,15 +82,19 @@ list(TRANSFORM configure_args REPLACE ";" "[[;]]") list(FILTER configure_args EXCLUDE REGEX "^[ \t]*$") list(TRANSFORM configure_args STRIP) -list(TRANSFORM configure_args REPLACE "\\\\" "\\\\\\\\") unset(generator) set(auto_detect_compiler TRUE) set(auto_detect_generator ${qtbase_or_top_level_build}) +set(no_prefix_option FALSE) unset(device_options) unset(options_json_file) set_property(GLOBAL PROPERTY UNHANDLED_ARGS "") while(NOT "${configure_args}" STREQUAL "") - list(POP_FRONT configure_args arg) + list(POP_FRONT configure_args raw_arg) + + # Condense '--foo-bar' arguments into '-foo-bar'. + string(REGEX REPLACE "^--([^-])" "-\\1" arg "${raw_arg}") + if(arg STREQUAL "-cmake-generator") list(POP_FRONT configure_args generator) elseif(arg STREQUAL "-cmake-use-default-generator") @@ -76,8 +108,33 @@ while(NOT "${configure_args}" STREQUAL "") elseif(arg STREQUAL "-write-options-for-conan") list(POP_FRONT configure_args options_json_file) elseif(arg STREQUAL "-skip") - list(POP_FRONT configure_args qtrepo) - push("-DBUILD_${qtrepo}=OFF") + warn_in_per_repo_build("${arg}") + list(POP_FRONT configure_args qtrepos) + is_non_empty_valid_arg("${arg}" "${qtrepos}") + list(TRANSFORM qtrepos REPLACE "," ";") + foreach(qtrepo IN LISTS qtrepos) + push("-DBUILD_${qtrepo}=OFF") + endforeach() + elseif(arg STREQUAL "-skip-tests") + list(POP_FRONT configure_args qtrepos) + is_non_empty_valid_arg("${arg}" "${qtrepos}") + list(TRANSFORM qtrepos REPLACE "," ";") + foreach(qtrepo IN LISTS qtrepos) + push("-DQT_BUILD_TESTS_PROJECT_${qtrepo}=OFF") + endforeach() + elseif(arg STREQUAL "-skip-examples") + list(POP_FRONT configure_args qtrepos) + is_non_empty_valid_arg("${arg}" "${qtrepos}") + list(TRANSFORM qtrepos REPLACE "," ";") + foreach(qtrepo IN LISTS qtrepos) + push("-DQT_BUILD_EXAMPLES_PROJECT_${qtrepo}=OFF") + endforeach() + elseif(arg STREQUAL "-submodules") + warn_in_per_repo_build("${arg}") + list(POP_FRONT configure_args submodules) + is_non_empty_valid_arg("${arg}" "${submodules}") + list(TRANSFORM submodules REPLACE "," "[[;]]") + push("-DQT_BUILD_SUBMODULES=${submodules}") elseif(arg STREQUAL "-qt-host-path") pop_path_argument() push("-DQT_HOST_PATH=${path}") @@ -89,13 +146,21 @@ while(NOT "${configure_args}" STREQUAL "") push("-DINSTALL_MKSPECSDIR=${path}") elseif(arg STREQUAL "-developer-build") set(developer_build TRUE) - # Treat this argument as "unhandled" to process it further. - set_property(GLOBAL APPEND PROPERTY UNHANDLED_ARGS "${arg}") + push("-DFEATURE_developer_build=ON") + elseif(arg STREQUAL "-no-prefix") + set(no_prefix_option TRUE) + push("-DFEATURE_no_prefix=ON") elseif(arg STREQUAL "-cmake-file-api") set(cmake_file_api TRUE) elseif(arg STREQUAL "-no-cmake-file-api") set(cmake_file_api FALSE) - elseif(arg STREQUAL "--") + elseif(arg STREQUAL "-verbose") + list(APPEND cmake_args "--log-level=STATUS") + elseif(arg STREQUAL "-disable-deprecated-up-to") + list(POP_FRONT configure_args version) + is_valid_qt_hex_version("${arg}" "${version}") + push("-DQT_DISABLE_DEPRECATED_UP_TO=${version}") + elseif(raw_arg STREQUAL "--") # Everything after this argument will be passed to CMake verbatim. list(APPEND cmake_args "${configure_args}") break() @@ -104,6 +169,50 @@ while(NOT "${configure_args}" STREQUAL "") endif() endwhile() +# Read the specified manually generator value from CMake command line. +# The '-cmake-generator' argument has higher priority than CMake command line. +if(NOT generator) + set(is_next_arg_generator_name FALSE) + foreach(arg IN LISTS cmake_args) + if(is_next_arg_generator_name) + set(is_next_arg_generator_name FALSE) + if(NOT arg MATCHES "^-.*") + set(generator "${arg}") + set(auto_detect_generator FALSE) + endif() + elseif(arg MATCHES "^-G(.*)") + set(generator "${CMAKE_MATCH_1}") + if(generator) + set(auto_detect_generator FALSE) + else() + set(is_next_arg_generator_name TRUE) + endif() + endif() + endforeach() +endif() + +# Attempt to detect the generator type, either single or multi-config +if("${generator}" STREQUAL "Xcode" + OR "${generator}" STREQUAL "Ninja Multi-Config" + OR "${generator}" MATCHES "^Visual Studio") + set(multi_config ON) +else() + set(multi_config OFF) +endif() + +# Tell the build system we are configuring via the configure script so we can act on that. +# The cache variable is unset at the end of configuration. +push("-DQT_INTERNAL_CALLED_FROM_CONFIGURE:BOOL=TRUE") + +if(FRESH_REQUESTED) + push("-DQT_INTERNAL_FRESH_REQUESTED:BOOL=TRUE") + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24") + push("--fresh") + else() + file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/CMakeCache.txt" + "${CMAKE_BINARY_DIR}/CMakeFiles") + endif() +endif() #################################################################################################### # Define functions/macros that are called in configure.cmake files @@ -151,7 +260,7 @@ defstub(qt_find_package) defstub(set_package_properties) defstub(qt_qml_find_python) defstub(qt_set01) - +defstub(qt_internal_check_if_linker_is_available) #################################################################################################### # Define functions/macros that are called in qt_cmdline.cmake files @@ -170,16 +279,23 @@ macro(qt_commandline_custom handler) endmacro() function(qt_commandline_option name) - set(options) + set(options CONTROLS_FEATURE) set(oneValueArgs TYPE NAME VALUE) set(multiValueArgs VALUES MAPPING) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(commandline_known_options "${commandline_known_options};${name}" PARENT_SCOPE) set(commandline_option_${name} "${arg_TYPE}" PARENT_SCOPE) + set(input_name ${name}) if(NOT "${arg_NAME}" STREQUAL "") + set(input_name ${arg_NAME}) set(commandline_option_${name}_variable "${arg_NAME}" PARENT_SCOPE) endif() + set(mapping_type "${arg_TYPE}") + if(arg_CONTROLS_FEATURE) + set(mapping_type "boolean") + endif() + set_property(GLOBAL PROPERTY INPUTTYPE_${input_name} "${mapping_type}") if(NOT "${arg_VALUE}" STREQUAL "") set(commandline_option_${name}_value "${arg_VALUE}" PARENT_SCOPE) endif() @@ -190,6 +306,11 @@ function(qt_commandline_option name) endif() endfunction() +# Add the common command line options for every qt repo. +macro(qt_add_common_commandline_options) + qt_commandline_option(headersclean TYPE boolean) +endmacro() + function(qt_commandline_prefix arg var) set(idx ${commandline_nr_of_prefixes}) set(commandline_prefix_${idx} "${arg}" "${var}" PARENT_SCOPE) @@ -206,6 +327,8 @@ set(QT_CONFIGURE_RUNNING ON) # Load qt_cmdline.cmake files #################################################################################################### +qt_add_common_commandline_options() + while(commandline_files) list(POP_FRONT commandline_files commandline_file) get_filename_component(commandline_file_directory "${commandline_file}" DIRECTORY) @@ -270,6 +393,23 @@ function(qtConfCommandlineAppendInput name val) qtConfCommandlineSetInput(${name} "${val}") endfunction() +function(qtConfCommandlineSetInputType input_name type_name) + set_property(GLOBAL PROPERTY INPUTTYPE_${input_name} "${type_name}") +endfunction() + +function(qtConfCommandlineSetBooleanInput name val) + qtConfCommandlineSetInput(${name} ${val}) + qtConfCommandlineSetInputType(${name} boolean) +endfunction() + +function(qtConfCommandlineEnableFeature name) + qtConfCommandlineSetBooleanInput(${name} yes) +endfunction() + +function(qtConfCommandlineDisableFeature name) + qtConfCommandlineSetBooleanInput(${name} no) +endfunction() + function(qtConfValidateValue opt val out_var) set(${out_var} TRUE PARENT_SCOPE) @@ -286,7 +426,9 @@ function(qtConfValidateValue opt val out_var) endforeach() set(${out_var} FALSE PARENT_SCOPE) - qtConfAddError("Invalid value '${val}' supplied to command line option '${opt}'.") + list(JOIN valid_values " " valid_values_str) + qtConfAddError("Invalid value '${val}' supplied to command line option '${opt}'." + "\nAllowed values: ${valid_values_str}\n") endfunction() function(qt_commandline_mapped_enum_value opt key out_var) @@ -574,6 +716,20 @@ while(1) if(arg MATCHES "^--?enable-(.*)") set(opt "${CMAKE_MATCH_1}") set(val "yes") + # Handle builtin [-no]-feature-xxx + elseif(arg MATCHES "^--?(no-)?feature-(.*)") + set(opt "${CMAKE_MATCH_2}") + if(NOT opt IN_LIST commandline_known_features) + qtConfAddError("Enabling/Disabling unknown feature '${opt}'.") + endif() + if("${CMAKE_MATCH_1}" STREQUAL "") + set(val "ON") + else() + set(val "OFF") + endif() + qt_feature_normalize_name("${opt}" normalized_feature_name) + push(-DFEATURE_${normalized_feature_name}=${val}) + continue() elseif(arg MATCHES "^--?(disable|no)-(.*)") set(opt "${CMAKE_MATCH_2}") set(val "no") @@ -590,7 +746,6 @@ while(1) if(NOT DEFINED commandline_option_${opt} AND opt MATCHES "(qt|system)-(.*)") set(opt "${CMAKE_MATCH_2}") set(val "${CMAKE_MATCH_1}") - message("opt: ${opt} val: ${val}") endif() else() qtConfAddError("Invalid command line parameter '${arg}'.") @@ -611,15 +766,6 @@ while(1) endforeach() endif() - # Handle builtin [-no]-feature-xxx - if("${type}" STREQUAL "" AND opt MATCHES "^feature-(.*)") - set(opt "${CMAKE_MATCH_1}") - if(NOT opt IN_LIST commandline_known_features) - qtConfAddError("Enabling/Disabling unknown feature '${opt}'.") - endif() - set(type boolean) - endif() - if("${type}" STREQUAL "") qtConfAddError("Unknown command line option '${arg}'.") endif() @@ -639,6 +785,9 @@ get_property(config_inputs GLOBAL PROPERTY CONFIG_INPUTS) list(REMOVE_DUPLICATES config_inputs) foreach(var ${config_inputs}) get_property(INPUT_${var} GLOBAL PROPERTY INPUT_${var}) + if("${commandline_input_type}" STREQUAL "") + get_property(commandline_input_${var}_type GLOBAL PROPERTY INPUTTYPE_${var}) + endif() endforeach() macro(drop_input name) @@ -734,7 +883,7 @@ function(guess_compiler_from_mkspec) push("-DCMAKE_CXX_COMPILER=${cxx_compiler}") endif() if(mkspec MATCHES "-libc\\+\\+$") - push("-DINPUT_stdlib_libcpp=ON") + push("-DFEATURE_stdlib_libcpp=ON") endif() set(cmake_args "${cmake_args}" PARENT_SCOPE) endfunction() @@ -766,9 +915,13 @@ endfunction() drop_input(commercial) drop_input(confirm-license) translate_boolean_input(precompile_header BUILD_WITH_PCH) +translate_boolean_input(unity_build QT_UNITY_BUILD) +translate_string_input(unity_build_batch_size QT_UNITY_BUILD_BATCH_SIZE) translate_boolean_input(ccache QT_USE_CCACHE) +translate_boolean_input(vcpkg QT_USE_VCPKG) translate_boolean_input(shared BUILD_SHARED_LIBS) translate_boolean_input(warnings_are_errors WARNINGS_ARE_ERRORS) +translate_boolean_input(qtinlinenamespace QT_INLINE_NAMESPACE) translate_string_input(qt_namespace QT_NAMESPACE) translate_string_input(qt_libinfix QT_LIBINFIX) translate_string_input(qreal QT_COORD_TYPE) @@ -795,8 +948,7 @@ translate_path_input(android-sdk ANDROID_SDK_ROOT) translate_path_input(android-ndk ANDROID_NDK_ROOT) if(DEFINED INPUT_android-ndk-platform) drop_input(android-ndk-platform) - string(REGEX REPLACE "^android-" "" INPUT_android-ndk-platform "${INPUT_android-ndk-platform}") - push("-DANDROID_NATIVE_API_LEVEL=${INPUT_android-ndk-platform}") + push("-DANDROID_PLATFORM=${INPUT_android-ndk-platform}") endif() if(DEFINED INPUT_android-abis) if(INPUT_android-abis MATCHES ",") @@ -808,15 +960,11 @@ endif() translate_string_input(android-javac-source QT_ANDROID_JAVAC_SOURCE) translate_string_input(android-javac-target QT_ANDROID_JAVAC_TARGET) -# FIXME: config_help.txt says -sdk should apply to macOS as well. -translate_string_input(sdk QT_UIKIT_SDK) -if(DEFINED INPUT_sdk OR (DEFINED INPUT_xplatform AND INPUT_xplatform STREQUAL "macx-ios-clang") - OR (DEFINED INPUT_platform AND INPUT_platform STREQUAL "macx-ios-clang")) - push("-DCMAKE_SYSTEM_NAME=iOS") -endif() +translate_string_input(sdk QT_APPLE_SDK) drop_input(make) drop_input(nomake) +translate_boolean_input(install-examples-sources QT_INSTALL_EXAMPLES_SOURCES) check_qt_build_parts(nomake) check_qt_build_parts(make) @@ -837,10 +985,33 @@ if(INPUT_force_debug_info) list(TRANSFORM build_configs REPLACE "^Release$" "RelWithDebInfo") endif() +# Code coverage handling +drop_input(gcov) +if(INPUT_gcov) + if(NOT "${INPUT_coverage}" STREQUAL "") + if(NOT "${INPUT_coverage}" STREQUAL "gcov") + qtConfAddError("The -gcov argument is provided, but -coverage is set" + " to ${INPUT_coverage}") + endif() + else() + set(INPUT_coverage "gcov") + list(APPEND config_inputs coverage) + endif() +endif() +if(NOT "${INPUT_coverage}" STREQUAL "") + if(build_configs) + if(NOT "Debug" IN_LIST build_configs) + qtConfAddError("The -coverage argument requires Qt configured with 'Debug' config.") + endif() + else() + set(build_configs "Debug") + endif() +endif() + list(LENGTH build_configs nr_of_build_configs) -if(nr_of_build_configs EQUAL 1) +if(nr_of_build_configs EQUAL 1 AND NOT multi_config) push("-DCMAKE_BUILD_TYPE=${build_configs}") -elseif(nr_of_build_configs GREATER 1) +elseif(nr_of_build_configs GREATER 1 OR multi_config) set(multi_config ON) string(REPLACE ";" "[[;]]" escaped_build_configs "${build_configs}") # We must not use the push macro here to avoid variable expansion. @@ -871,11 +1042,23 @@ if(cmake_file_api OR (developer_build AND NOT DEFINED cmake_file_api)) endforeach() endif() +# Translate unhandled input variables to either -DINPUT_foo=value or -DFEATURE_foo=ON/OFF. If the +# input's name matches a feature name and the corresponding command-line option's type is boolean +# then we assume it's controlling a feature. foreach(input ${config_inputs}) qt_feature_normalize_name("${input}" cmake_input) - push("-DINPUT_${cmake_input}=${INPUT_${input}}") + if("${commandline_input_${input}_type}" STREQUAL "boolean" + AND input IN_LIST commandline_known_features) + translate_boolean_input("${input}" "FEATURE_${cmake_input}") + else() + push("-DINPUT_${cmake_input}=${INPUT_${input}}") + endif() endforeach() +if(no_prefix_option AND DEFINED INPUT_prefix) + qtConfAddError("Can't specify both -prefix and -no-prefix options at the same time.") +endif() + if(NOT generator AND auto_detect_generator) find_program(ninja ninja) if(ninja) @@ -921,6 +1104,14 @@ endforeach() push("${MODULE_ROOT}") +if(INPUT_sysroot) + qtConfAddWarning("The -sysroot option is deprecated and no longer has any effect. " + "It is recommended to use a toolchain file instead, i.e., " + "-DCMAKE_TOOLCHAIN_FILE=<filename>. " + "Alternatively, you may use -DCMAKE_SYSROOT option " + "to pass the sysroot to CMake.\n") +endif() + # Restore the escaped semicolons in arguments that are lists list(TRANSFORM cmake_args REPLACE "\\[\\[;\\]\\]" "\\\\;") |