diff options
49 files changed, 1515 insertions, 184 deletions
diff --git a/bin/qt-configure-module.bat.in b/bin/qt-configure-module.bat.in index aacb4e6aa32..4c2798c0fbd 100644 --- a/bin/qt-configure-module.bat.in +++ b/bin/qt-configure-module.bat.in @@ -53,12 +53,15 @@ set REDO_FILE_PATH=%TOPQTDIR%\config.redo.last set REDO_TMP_FILE_PATH=%TOPQTDIR%\config.redo.in set FRESH_REQUESTED_ARG= if not defined redoing ( + copy "%script_dir_path%\@__GlobalConfig_relative_path_from_bin_dir_to_cmake_config_dir@\@side_car_file_name@" "%OPT_TMP_FILE_PATH%" + rem "The '.' in 'echo.%*' ensures we don't print "echo is off" when no arguments are passed" rem "https://devblogs.microsoft.com/oldnewthing/20170802-00/?p=96735" rem "The space before the '>' makes sure that when we have a digit at the end of the args, we" rem "don't accidentally concatenate it with the '>' resulting in '0>' or '2>' which redirects" rem "into the file from a stream different than stdout, leading to broken or empty content." - echo.%* >"%OPT_TMP_FILE_PATH%" + echo.%* >>"%OPT_TMP_FILE_PATH%" + echo.@__extra_configure_args@ >>"%OPT_TMP_FILE_PATH%" rem "The SKIP_ARGS option makes sure not to write the repo path into the config.opt file" call "%script_dir_path%\qt-cmake-private.bat" -DSKIP_ARGS=1 -DIN_FILE="%OPT_TMP_FILE_PATH%" ^ diff --git a/bin/qt-configure-module.in b/bin/qt-configure-module.in index 690fc014782..0c4e4f77a67 100755 --- a/bin/qt-configure-module.in +++ b/bin/qt-configure-module.in @@ -73,7 +73,7 @@ qt_cmake_private_path="$script_dir_path/../@INSTALL_LIBEXECDIR@" fresh_requested_arg= if [ -z "$optfile" ]; then # only write optfile if not currently redoing - > "$opttmpfilepath" + cp "$script_dir_path/@__GlobalConfig_relative_path_from_bin_dir_to_cmake_config_dir@/@side_car_file_name@" "$opttmpfilepath" > "$redotmpfilepath" for arg in "$@"; do echo \"$arg\" >> "$opttmpfilepath"; done diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake index 7205bad5253..91983636712 100644 --- a/cmake/QtBuildHelpers.cmake +++ b/cmake/QtBuildHelpers.cmake @@ -96,6 +96,7 @@ macro(qt_internal_reset_global_state) qt_internal_set_qt_known_plugins("") set(QT_KNOWN_MODULES_WITH_TOOLS "" CACHE INTERNAL "Known Qt modules with tools" FORCE) + set_property(GLOBAL PROPERTY _qt_standalone_tool_packages "") endmacro() macro(qt_internal_set_qt_path_separator) @@ -263,6 +264,7 @@ function(qt_internal_get_qt_build_private_files_to_install out_var) QtSeparateDebugInfo.Info.plist.in QtSetup.cmake QtStandaloneTestsConfig.cmake.in + QtVcpkgManifestHelpers.cmake QtVersionlessAliasTargets.cmake.in QtVersionlessTargets.cmake.in QtWriteArgsFile.cmake diff --git a/cmake/QtBuildRepoHelpers.cmake b/cmake/QtBuildRepoHelpers.cmake index 5961424c38b..05876c1ad6d 100644 --- a/cmake/QtBuildRepoHelpers.cmake +++ b/cmake/QtBuildRepoHelpers.cmake @@ -732,6 +732,7 @@ macro(qt_internal_find_standalone_parts_qt_packages standalone_parts_args_var_na set(__standalone_parts_single_args "") set(__standalone_parts_multi_args QT_MODULE_PACKAGES + QT_TOOL_PACKAGES ) cmake_parse_arguments(__standalone_parts "${__standalone_parts_opt_args}" @@ -743,6 +744,32 @@ macro(qt_internal_find_standalone_parts_qt_packages standalone_parts_args_var_na # the one recorded on the Platform target. qt_internal_get_package_version_of_target(Platform __standalone_parts_main_qt_package_version) + if(__standalone_parts_QT_TOOL_PACKAGES) + # Set up QT_HOST_PATH as an extra root path to look for the Tools packages when + # cross-compiling. + if(NOT "${QT_HOST_PATH}" STREQUAL "") + set(__standalone_parts_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}) + set(__standalone_parts_CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH}) + list(PREPEND CMAKE_PREFIX_PATH "${QT_HOST_PATH_CMAKE_DIR}") + list(PREPEND CMAKE_FIND_ROOT_PATH "${QT_HOST_PATH}") + endif() + + foreach(__standalone_parts_package_name IN LISTS __standalone_parts_QT_TOOL_PACKAGES) + find_package(${QT_CMAKE_EXPORT_NAMESPACE}${__standalone_parts_package_name} + "${__standalone_parts_main_qt_package_version}" + PATHS + # These come from Qt6Config.cmake + ${_qt_additional_packages_prefix_path} + ${_qt_additional_packages_prefix_path_env} + ) + endforeach() + + if(NOT "${QT_HOST_PATH}" STREQUAL "") + set(CMAKE_PREFIX_PATH ${__standalone_parts_CMAKE_PREFIX_PATH}) + set(CMAKE_FIND_ROOT_PATH ${__standalone_parts_CMAKE_FIND_ROOT_PATH}) + endif() + endif() + if(__standalone_parts_QT_MODULE_PACKAGES) foreach(__standalone_parts_package_name IN LISTS __standalone_parts_QT_MODULE_PACKAGES) find_package(${QT_CMAKE_EXPORT_NAMESPACE} @@ -755,8 +782,11 @@ macro(qt_internal_find_standalone_parts_qt_packages standalone_parts_args_var_na unset(__standalone_parts_single_args) unset(__standalone_parts_multi_args) unset(__standalone_parts_QT_MODULE_PACKAGES) + unset(__standalone_parts_QT_TOOL_PACKAGES) unset(__standalone_parts_main_qt_package_version) unset(__standalone_parts_package_name) + unset(__standalone_parts_CMAKE_PREFIX_PATH) + unset(__standalone_parts_CMAKE_FIND_ROOT_PATH) endmacro() # Used by standalone tests and standalone non-ExternalProject examples to find all installed qt diff --git a/cmake/QtFeature.cmake b/cmake/QtFeature.cmake index 9bbf6e700b4..d8f031f5b27 100644 --- a/cmake/QtFeature.cmake +++ b/cmake/QtFeature.cmake @@ -59,6 +59,10 @@ function(qt_feature_module_begin) set(__QtFeature_define_definitions "" PARENT_SCOPE) endfunction() +# Define a Qt feature. +# +# The vcpkg-related arguments are relevant for configure only and are documented +# at the top of the qt_feature implementation in QtProcessConfigureArgs.cmake. function(qt_feature feature) set(original_name "${feature}") qt_feature_normalize_name("${feature}" feature) @@ -68,11 +72,14 @@ function(qt_feature feature) PRIVATE PUBLIC SYSTEM_LIBRARY + VCPKG_DEFAULT + VCPKG_OPTIONAL ) set(single_value_options LABEL PURPOSE SECTION + VCPKG_DESCRIPTION ) set(multi_value_options AUTODETECT @@ -80,6 +87,7 @@ function(qt_feature feature) ENABLE DISABLE EMIT_IF + VCPKG_DEPENDENT_FEATURES ) cmake_parse_arguments(PARSE_ARGV 1 arg "${no_value_options}" "${single_value_options}" "${multi_value_options}" @@ -389,6 +397,10 @@ function(qt_feature_deprecated feature) endif() endfunction() +function(qt_feature_vcpkg_scope name) + # This is just a stub. The real implementation is called at configure script time. +endfunction() + function(qt_evaluate_to_boolean expressionVar) if(${${expressionVar}}) set(${expressionVar} ON PARENT_SCOPE) @@ -816,9 +828,9 @@ endmacro() macro(_qt_internal_parse_feature_definition feature) cmake_parse_arguments(arg - "PRIVATE;PUBLIC;ALIAS_NEGATE" - "LABEL;PURPOSE;SECTION;ALIAS_OF_FEATURE;ALIAS_OF_CACHE" - "AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF" + "PRIVATE;PUBLIC;ALIAS_NEGATE;VCPKG_DEFAULT;VCPKG_OPTIONAL" + "LABEL;PURPOSE;SECTION;ALIAS_OF_FEATURE;ALIAS_OF_CACHE;VCPKG_DESCRIPTION" + "AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF;VCPKG_DEPENDENT_FEATURES" ${_QT_FEATURE_DEFINITION_${feature}}) endmacro() diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake index 29c12dcd826..82538ab6ffe 100644 --- a/cmake/QtFindPackageHelpers.cmake +++ b/cmake/QtFindPackageHelpers.cmake @@ -10,12 +10,39 @@ # - Or remove the <builddir>/CMakeCache.txt file and configure from scratch # - Or remove the QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES cache variable (by # editing CMakeCache.txt) and reconfigure. +# +# It's possible to annotate the qt_find_package with information on how to +# generate a vcpkg manifest to satisfy this qt_find_package call. +# +# VCPKG_PORT <name> +# Name of the vcpkg port (package) to install. +# +# VCPKG_PLATFORM <expression> +# vcpkg platform expression, e.g. "!windows". +# See https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json#platform-expression +# +# VCPKG_VERSION <version> +# The minimum version of the vcpkg port to install +# See https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json#version +# +# VCPKG_ADD_TO_FEATURE <name> +# Add this port to the vcpkg feature with the given name. Create the feature if non-existent. +# +# VCPKG_DEFAULT_FEATURES <ON/OFF> +# ON by default. Set this to OFF to avoid that the vcpkg feature is added to +# vcpkg.json's default features. Only useful if VCPKG_ADD_TO_FEATURE is set. macro(qt_find_package) # Get the target names we expect to be provided by the package. set(find_package_options CONFIG NO_MODULE MODULE REQUIRED) set(options ${find_package_options} MARK_OPTIONAL) - set(oneValueArgs MODULE_NAME QMAKE_LIB) - set(multiValueArgs PROVIDED_TARGETS COMPONENTS OPTIONAL_COMPONENTS) + set(oneValueArgs MODULE_NAME QMAKE_LIB + VCPKG_ADD_TO_FEATURE + VCPKG_DEFAULT_FEATURES + VCPKG_PLATFORM + VCPKG_PORT + VCPKG_VERSION + ) + set(multiValueArgs PROVIDED_TARGETS COMPONENTS OPTIONAL_COMPONENTS VCPKG_FEATURES) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) # If some Qt internal project calls qt_find_package(WrapFreeType), but WrapFreeType was already @@ -406,13 +433,13 @@ function(qt_record_extra_main_tools_package_dependency endif() if (TARGET "${main_target_name}") get_target_property(extra_packages "${main_target_name}" - QT_EXTRA_TOOLS_PACKAGE_DEPENDENCIES) + _qt_extra_tools_package_dependencies) if(NOT extra_packages) set(extra_packages "") endif() list(APPEND extra_packages "${dep_package_name}\;${dep_package_version}") - set_target_properties("${main_target_name}" PROPERTIES QT_EXTRA_TOOLS_PACKAGE_DEPENDENCIES + set_target_properties("${main_target_name}" PROPERTIES _qt_extra_tools_package_dependencies "${extra_packages}") endif() endfunction() @@ -457,6 +484,52 @@ function(qt_record_extra_third_party_dependency main_target_name dep_target) endif() endfunction() +# Record a third party dependency for a standalone tools package. +# +# This function records a dependency between the standalone pacakge PACKAGE_BASE_NAME and third +# party dependency DEPENDENCY_PACKAGE_NAME and DEPENDENCY_PACKAGE_VERSION +# at the CMake package level. +# +# E.g. A Qt6GarageTools package with the PACKAGE_BASE_NAME 'Garage', +# needs to call find_package(ZLIB 1.2) (non-qt-package). +function(qt_internal_record_tools_package_extra_third_party_dependency) + set(opt_args "") + set(single_args + PACKAGE_BASE_NAME + ) + set(multi_args + DEPENDENCY_PACKAGE_NAME + DEPENDENCY_PACKAGE_VERSION + ) + cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}") + _qt_internal_validate_all_args_are_parsed(arg) + + if(NOT arg_PACKAGE_BASE_NAME) + message(FATAL_ERROR "PACKAGE_BASE_NAME is required.") + endif() + set(id "${arg_PACKAGE_BASE_NAME}") + + if(NOT arg_DEPENDENCY_PACKAGE_NAME) + message(FATAL_ERROR "DEPENDENCY_PACKAGE_NAME is required.") + endif() + set(dep_package_name "${arg_DEPENDENCY_PACKAGE_NAME}") + + if(arg_DEPENDENCY_PACKAGE_VERSION) + set(dep_package_version "${arg_DEPENDENCY_PACKAGE_VERSION}") + else() + set(dep_package_version "") + endif() + + get_cmake_property(extra_deps _qt_standalone_tool_package_${id}_third_party_dependencies) + if(NOT extra_deps) + set(extra_deps "") + endif() + + list(APPEND extra_deps "${dep_package_name}\;${dep_package_version}") + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_third_party_dependencies + "${extra_deps}") +endfunction() + # Sets out_var to TRUE if the non-namespaced ${lib} target is exported as part of Qt6Targets.cmake. function(qt_internal_is_lib_part_of_qt6_package lib out_var) if (lib STREQUAL "Platform" diff --git a/cmake/QtModuleToolsConfig.cmake.in b/cmake/QtModuleToolsConfig.cmake.in index 43b826c2060..1bd54239edf 100644 --- a/cmake/QtModuleToolsConfig.cmake.in +++ b/cmake/QtModuleToolsConfig.cmake.in @@ -18,10 +18,17 @@ if(NOT DEFINED "@INSTALL_CMAKE_NAMESPACE@@target@_FOUND") set("@INSTALL_CMAKE_NAMESPACE@@target@_FOUND" TRUE) endif() +set(__qt_@target@_should_include_targets_code "@QT_SHOULD_INCLUDE_TARGETS_CODE@") + # Do the checks inside Targets.cmake even when the file is still being generated -include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@TargetsPrecheck.cmake") +if(__qt_@target@_should_include_targets_code) + include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@TargetsPrecheck.cmake") +endif() -if(NOT __qt_@target@_skip_include_targets_file AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND) +if(NOT __qt_@target@_skip_include_targets_file + AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND + AND __qt_@target@_should_include_targets_code + ) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS) @@ -30,7 +37,8 @@ if(NOT __qt_@target@_skip_include_targets_file AND @INSTALL_CMAKE_NAMESPACE@@tar set(__qt_@target@_targets_file_included ON) endif() -foreach(extra_cmake_include @extra_cmake_includes@) +set(__qt_@target@_extra_cmake_includes "@extra_cmake_includes@") +foreach(extra_cmake_include IN LISTS __qt_@target@_extra_cmake_includes) include("${CMAKE_CURRENT_LIST_DIR}/${extra_cmake_include}") endforeach() diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake index b8e46085a98..2fd2ff79478 100644 --- a/cmake/QtPostProcessHelpers.cmake +++ b/cmake/QtPostProcessHelpers.cmake @@ -202,12 +202,10 @@ function(qt_internal_create_module_depends_file target) # Extra QtFooModuleTools packages to be added as dependencies to # QtModuleDependencies.cmake. Needed for QtWaylandCompositor / QtWaylandClient. - if(NOT is_interface_lib) - get_target_property(extra_tools_package_dependencies "${target}" - QT_EXTRA_TOOLS_PACKAGE_DEPENDENCIES) - if(extra_tools_package_dependencies) - list(APPEND main_module_tool_deps "${extra_tools_package_dependencies}") - endif() + get_target_property(extra_tools_package_dependencies "${target}" + _qt_extra_tools_package_dependencies) + if(extra_tools_package_dependencies) + list(APPEND main_module_tool_deps "${extra_tools_package_dependencies}") endif() qt_internal_get_qt_all_known_modules(known_modules) @@ -801,8 +799,15 @@ endfunction() function(qt_create_tools_config_files) # Create packages like Qt6CoreTools/Qt6CoreToolsConfig.cmake. foreach(module_name ${QT_KNOWN_MODULES_WITH_TOOLS}) - qt_export_tools("${module_name}") + qt_export_tools(MODULE_NAME "${module_name}") endforeach() + + get_cmake_property(standalone_packages _qt_standalone_tool_packages) + if(standalone_packages) + foreach(package_name IN LISTS standalone_packages) + qt_export_tools(PACKAGE_BASE_NAME "${package_name}") + endforeach() + endif() endfunction() function(qt_internal_create_config_file_for_standalone_tests) @@ -835,9 +840,11 @@ function(qt_internal_create_config_file_for_standalone_tests) endif() endforeach() - # Skip generating and installing file if no modules were built. This make sure not to install - # anything when build qtx11extras on macOS for example. - if(NOT modules) + get_cmake_property(tool_package_base_names _qt_standalone_tool_packages) + + # Skip generating and installing file if no modules or tools were built. This makes sure not + # to install anything when building qtx11extras on macOS for example. + if(NOT modules AND NOT tool_package_base_names) return() endif() @@ -846,7 +853,22 @@ function(qt_internal_create_config_file_for_standalone_tests) qt_internal_get_standalone_parts_config_file_name(tests_config_file_name) # Substitution variables. - list(JOIN modules "\n " QT_MODULE_PACKAGES) + if(modules) + list(JOIN modules "\n " module_string) + set(QT_MODULE_PACKAGES " QT_MODULE_PACKAGES + ${module_string}") + endif() + + if(tool_package_base_names) + # We only have the base package names, so we need to append Tools to each of the package + # names + set(tool_packages "${tool_package_base_names}") + list(TRANSFORM tool_packages APPEND Tools) + + list(JOIN tool_packages "\n " tool_packages_string) + set(QT_TOOL_PACKAGES " QT_TOOL_PACKAGES + ${tool_packages_string}") + endif() configure_file( "${QT_CMAKE_DIR}/QtStandaloneTestsConfig.cmake.in" diff --git a/cmake/QtProcessConfigureArgs.cmake b/cmake/QtProcessConfigureArgs.cmake index bdedfb0b734..833daceba27 100644 --- a/cmake/QtProcessConfigureArgs.cmake +++ b/cmake/QtProcessConfigureArgs.cmake @@ -11,11 +11,13 @@ # If empty, qtbase/top-level is assumed. # TOP_LEVEL: TRUE, if this is a top-level build. +# The CMake version required for running the configure script. +# This must be less than or equal to the lowest QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_*. +cmake_minimum_required(VERSION 3.19) + include(${CMAKE_CURRENT_LIST_DIR}/QtFeatureCommon.cmake) include(${CMAKE_CURRENT_LIST_DIR}/QtBuildInformation.cmake) - -cmake_policy(SET CMP0007 NEW) -cmake_policy(SET CMP0057 NEW) +include(${CMAKE_CURRENT_LIST_DIR}/QtVcpkgManifestHelpers.cmake) set(cmake_args "") macro(push) @@ -85,8 +87,11 @@ list(TRANSFORM configure_args STRIP) unset(generator) set(auto_detect_compiler TRUE) set(auto_detect_generator ${qtbase_or_top_level_build}) +set(dry_run FALSE) set(no_prefix_option FALSE) set(skipped_qtrepos "") +set(use_vcpkg FALSE) +set(generate_vcpkg_manifest "unknown") unset(device_options) unset(options_json_file) set_property(GLOBAL PROPERTY UNHANDLED_ARGS "") @@ -100,6 +105,20 @@ while(NOT "${configure_args}" STREQUAL "") list(POP_FRONT configure_args generator) elseif(arg STREQUAL "-cmake-use-default-generator") set(auto_detect_generator FALSE) + elseif(arg STREQUAL "-dry-run") + set(dry_run TRUE) + elseif(arg MATCHES "^-(no-)?vcpkg$") + if(CMAKE_MATCH_1 STREQUAL "no-") + set(use_vcpkg FALSE) + else() + set(use_vcpkg TRUE) + endif() + elseif(arg MATCHES "^-(no-)?generate-vcpkg-manifest$") + if(CMAKE_MATCH_1 STREQUAL "no-") + set(generate_vcpkg_manifest FALSE) + else() + set(generate_vcpkg_manifest TRUE) + endif() elseif(arg STREQUAL "-no-guess-compiler") set(auto_detect_compiler FALSE) elseif(arg STREQUAL "-list-features") @@ -171,6 +190,18 @@ while(NOT "${configure_args}" STREQUAL "") endif() endwhile() +# Turn on vcpkg usage if requested. +# Set the manifest directory to where we generate the manifest file. +if(use_vcpkg) + push(-DQT_USE_VCPKG=ON) + push("-DVCPKG_MANIFEST_DIR=${CMAKE_CURRENT_BINARY_DIR}") +endif() + +# By default, generate a manifest if using vcpkg. +if(generate_vcpkg_manifest STREQUAL "unknown") + set(generate_vcpkg_manifest ${use_vcpkg}) +endif() + # Read the specified manually generator value from CMake command line. # The '-cmake-generator' argument has higher priority than CMake command line. if(NOT generator) @@ -225,11 +256,108 @@ endif() set_property(GLOBAL PROPERTY COMMANDLINE_KNOWN_FEATURES "") +# Define a Qt feature. +# +# Arguments that start with VCPKG_ affect the creation of vcpkg features. If +# either VCPKG_DEFAULT or VCPGK_OPTIONAL are given, a corresponding vcpkg +# feature will be created. +# +# VCPKG_DEFAULT +# Specifies to create a vcpkg feature that will be added to the manifest's +# default features. +# +# VCPKG_OPTIONAL +# Specifies to create an optional vcpkg feature. +# +# VCPKG_DESCRIPTION <string> +# Optional description of the vcpkg feature. If not given, the description +# is derived from PURPOSE, or LABEL, or the feature name. +# +# VCPKG_DEPENDENT_FEATURES <features> +# List of vcpkg features this feature depends upon. +# For example, the "jpeg" feature would use "VCPKG_DEPENDENT_FEATURES gui". function(qt_feature feature) - cmake_parse_arguments(arg "" "PURPOSE;SECTION;" "" ${ARGN}) + set(no_value_options + VCPKG_DEFAULT + VCPKG_OPTIONAL + ) + set(single_value_options + LABEL + PURPOSE + SECTION + VCPKG_DESCRIPTION + ) + set(multi_value_options + VCPKG_DEPENDENT_FEATURES + ) + cmake_parse_arguments(PARSE_ARGV 1 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + set_property(GLOBAL APPEND PROPERTY COMMANDLINE_KNOWN_FEATURES "${feature}") set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_PURPOSE_${feature} "${arg_PURPOSE}") set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_SECTION_${feature} "${arg_SECTION}") + + if(NOT generate_vcpkg_manifest) + return() + endif() + + set(unknown_vcpkg_args "${arg_UNPARSED_ARGUMENTS}") + list(FILTER unknown_vcpkg_args INCLUDE REGEX "^VCPKG_") + if(NOT "${unknown_vcpkg_args}" STREQUAL "") + message(FATAL_ERROR "Unknown arguments passed to qt_feature: ${unknown_vcpkg_args}") + endif() + + set(create_vcpkg_feature FALSE) + if(arg_VCPKG_DEFAULT OR arg_VCPKG_OPTIONAL) + set(create_vcpkg_feature TRUE) + else() + get_cmake_property(vcpkg_features_to_create _QT_VCPKG_FEATURES_TO_CREATE) + if("${feature}" IN_LIST vcpkg_features_to_create) + set(create_vcpkg_feature TRUE) + list(REMOVE_ITEM vcpkg_features_to_create "${feature}") + set_property(GLOBAL PROPERTY + _QT_VCPKG_FEATURES_TO_CREATE ${vcpkg_features_to_create} + ) + endif() + endif() + + if(NOT create_vcpkg_feature) + return() + endif() + + # Determine the description + if(DEFINED arg_VCPKG_DESCRIPTION) + set(description "${arg_VCPKG_DESCRIPTION}") + elseif(DEFINED arg_PURPOSE) + set(description "${arg_PURPOSE}") + elseif(DEFINED arg_LABEL) + set(description "${arg_LABEL}") + else() + set(description "${feature} support") + endif() + + # Determine the dependent features (e.g. gui for freetype) + set(dependent_features "") + get_cmake_property(vcpkg_scope _QT_VCPKG_SCOPE) + if(vcpkg_scope) + list(APPEND dependent_features "${vcpkg_scope}") + endif() + if(DEFINED arg_VCPKG_DEPENDENT_FEATURES) + list(APPEND dependent_features "${arg_VCPKG_DEPENDENT_FEATURES}") + endif() + + # Features that aren't dependencies of other features are added to default-features + # unless VCPKG_DEFAULT or VCPKG_OPTIONAL are specified. + set(additional_args "") + if(NOT arg_VCKG_DEFAULT AND NOT arg_VCPKG_OPTIONAL AND dependent_features STREQUAL "") + list(APPEND additional_args DEFAULT) + endif() + qt_vcpkg_feature("${feature}" "${description}" ${additional_args}) + + foreach(dependent_feature IN LISTS dependent_features) + qt_vcpkg_add_feature_dependencies("${dependent_feature}" "${feature}") + endforeach() endfunction() function(qt_feature_alias feature) @@ -260,11 +388,83 @@ function(qt_feature_deprecated feature) set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_SECTION_${feature} "${arg_SECTION}") endfunction() +function(qt_feature_vcpkg_scope name) + set_property(GLOBAL PROPERTY _QT_VCPKG_SCOPE ${name}) +endfunction() + function(find_package) message(FATAL_ERROR "find_package must not be used directly in configure.cmake. " "Use qt_find_package or guard the call with an if(NOT QT_CONFIGURE_RUNNING) block.") endfunction() +function(qt_init_vcpkg_manifest_if_needed) + get_property(manifest_initialized GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON SET) + if(manifest_initialized) + return() + endif() + + if(TOP_LEVEL) + set(package_name "qt") + else() + get_filename_component(package_name "${MODULE_ROOT}" NAME) + endif() + qt_vcpkg_manifest_init(NAME "${package_name}") +endfunction() + +function(qt_find_package name) + if(NOT generate_vcpkg_manifest) + return() + endif() + + set(no_value_options "") + set(single_value_options + VCPKG_ADD_TO_FEATURE + VCPKG_DEFAULT_FEATURES + VCPKG_PLATFORM + VCPKG_PORT + VCPKG_VERSION + ) + set(multi_value_options + VCPKG_FEATURES + ) + cmake_parse_arguments(PARSE_ARGV 1 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + + set(unknown_vcpkg_args "${arg_UNPARSED_ARGUMENTS}") + list(FILTER unknown_vcpkg_args INCLUDE REGEX "^VCPKG_") + if(NOT "${unknown_vcpkg_args}" STREQUAL "") + message(FATAL_ERROR "Unknown arguments passed to qt_find_package: ${unknown_vcpkg_args}") + endif() + + if(NOT DEFINED arg_VCPKG_PORT) + return() + endif() + + qt_init_vcpkg_manifest_if_needed() + + set(dependency_args "${arg_VCPKG_PORT}") + if(DEFINED arg_VCPKG_VERSION) + list(APPEND dependency_args VERSION "${arg_VCPKG_VERSION}") + endif() + if(DEFINED arg_VCPKG_PLATFORM) + list(APPEND dependency_args PLATFORM "${arg_VCPKG_PLATFORM}") + endif() + if(DEFINED arg_VCPKG_DEFAULT_FEATURES) + list(APPEND dependency_args DEFAULT_FEATURES "${arg_VCPKG_DEFAULT_FEATURES}") + endif() + if(DEFINED arg_VCPKG_ADD_TO_FEATURE) + list(APPEND dependency_args ADD_TO_FEATURE "${arg_VCPKG_ADD_TO_FEATURE}") + set_property(GLOBAL APPEND PROPERTY + _QT_VCPKG_FEATURES_TO_CREATE "${arg_VCPKG_ADD_TO_FEATURE}" + ) + endif() + if(DEFINED arg_VCPKG_FEATURES) + list(APPEND dependency_args FEATURES "${arg_VCPKG_FEATURES}") + endif() + qt_vcpkg_add_dependency(${dependency_args}) +endfunction() + macro(defstub name) function(${name}) endfunction() @@ -289,7 +489,6 @@ defstub(qt_configure_end_summary_section) defstub(qt_extra_definition) defstub(qt_feature_config) defstub(qt_feature_definition) -defstub(qt_find_package) defstub(set_package_properties) defstub(qt_qml_find_python) defstub(qt_set01) @@ -391,6 +590,9 @@ endfunction() # stub functions above. set(QT_CONFIGURE_RUNNING ON) +# Make sure that configure sees all qt_find_package calls. +set(QT_FIND_ALL_PACKAGES_ALWAYS ON) + #################################################################################################### # Load qt_cmdline.cmake files @@ -414,6 +616,7 @@ while(commandline_files) unset(commandline_subconfigs) if(EXISTS "${configure_file}") include("${configure_file}") + set_property(GLOBAL PROPERTY _QT_VCPKG_SCOPE) endif() if(EXISTS "${commandline_file}") include("${commandline_file}") @@ -1188,9 +1391,109 @@ if(INPUT_sysroot) "to pass the sysroot to CMake.\n") endif() +function(qt_generate_vcpkg_manifest) + # Check if manifest was initialized (i.e., any dependencies were found) + get_property(manifest_initialized GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON SET) + if(NOT manifest_initialized) + # For repositories that don't need 3rd-party libs, generate an empty vcpkg.json. + qt_init_vcpkg_manifest_if_needed() + endif() + + # Write the manifest file + set(manifest_file "${CMAKE_CURRENT_BINARY_DIR}/vcpkg.json") + qt_vcpkg_write_manifest("${manifest_file}") +endfunction() + +function(qt_select_vcpkg_features out_var cmake_args) + # Extract enabled/disabled features from cmake_args. + set(normalized_enabled_features "") + set(normalized_disabled_features "") + foreach(arg IN LISTS cmake_args) + if(arg MATCHES "^-DFEATURE_([^=]+)=(.*)") + if(CMAKE_MATCH_2) + list(APPEND normalized_enabled_features "${CMAKE_MATCH_1}") + else() + list(APPEND normalized_disabled_features "${CMAKE_MATCH_1}") + endif() + endif() + endforeach() + + if(normalized_enabled_features STREQUAL "" AND normalized_disabled_features STREQUAL "") + return() + endif() + + # Convert normalized feature names back to original names + set(enabled_features "") + set(disabled_features "") + foreach(original_feature IN LISTS commandline_known_features) + qt_feature_normalize_name("${original_feature}" normalized_feature) + if(normalized_feature IN_LIST normalized_enabled_features) + list(APPEND enabled_features "${original_feature}") + endif() + if(normalized_feature IN_LIST normalized_disabled_features) + list(APPEND disabled_features "${original_feature}") + endif() + endforeach() + + set(manifest_file_path "${CMAKE_CURRENT_BINARY_DIR}/vcpkg.json") + if(NOT EXISTS "${manifest_file_path}") + return() + endif() + + file(READ "${manifest_file_path}" json) + qt_vcpkg_set_internal_manifest_data("${json}") + + # Enable all default vcpkg feature that were not explicitly disabled. + qt_vcpkg_get_default_features(vcpkg_default_features "${json}") + set(vcpkg_features_to_enable ${vcpkg_default_features}) + list(REMOVE_ITEM vcpkg_features_to_enable ${disabled_features}) + + # Enable all vcpkg features that were explicitly enabled. Filter out non-vcpkg features. + qt_vcpkg_get_features(all_vcpkg_features "${json}") + set(enabled_features_without_vcpkg_features "${enabled_features}") + list(REMOVE_ITEM enabled_features_without_vcpkg_features ${all_vcpkg_features}) + list(APPEND vcpkg_features_to_enable ${enabled_features}) + list(REMOVE_ITEM vcpkg_features_to_enable ${enabled_features_without_vcpkg_features}) + list(REMOVE_DUPLICATES vcpkg_features_to_enable) + + # If we're enabling exactly the default features, we don't have to explicitly enable them. + if(vcpkg_features_to_enable STREQUAL vcpkg_default_features) + return() + endif() + + list(APPEND cmake_args "-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON") + list(JOIN vcpkg_features_to_enable "[[;]]" manifest_args) + list(APPEND cmake_args "-DVCPKG_MANIFEST_FEATURES=${manifest_args}") + set("${out_var}" "${cmake_args}" PARENT_SCOPE) +endfunction() + +if(generate_vcpkg_manifest) + qt_generate_vcpkg_manifest() +endif() + +if(use_vcpkg) + qt_select_vcpkg_features(cmake_args "${cmake_args}") +endif() + # Restore the escaped semicolons in arguments that are lists list(TRANSFORM cmake_args REPLACE "\\[\\[;\\]\\]" "\\\\;") +if(dry_run) + if(CMAKE_COMMAND MATCHES " ") + set(pretty_command_line "\"${CMAKE_COMMAND}\"") + else() + set(pretty_command_line "${CMAKE_COMMAND}") + endif() + foreach(arg IN LISTS cmake_args) + if(arg MATCHES "[ ;]") + set(arg "\"${arg}\"") + endif() + string(APPEND pretty_command_line " ${arg}") + endforeach() + message("${pretty_command_line}") + return() +endif() + execute_process(COMMAND "${CMAKE_COMMAND}" ${cmake_args} COMMAND_ECHO STDOUT RESULT_VARIABLE exit_code) diff --git a/cmake/QtStandaloneTestsConfig.cmake.in b/cmake/QtStandaloneTestsConfig.cmake.in index 9d548d14699..47ee7e8353a 100644 --- a/cmake/QtStandaloneTestsConfig.cmake.in +++ b/cmake/QtStandaloneTestsConfig.cmake.in @@ -2,7 +2,7 @@ # SPDX-License-Identifier: BSD-3-Clause set(__standalone_parts_qt_packages_args - QT_MODULE_PACKAGES - @QT_MODULE_PACKAGES@ +@QT_MODULE_PACKAGES@ +@QT_TOOL_PACKAGES@ ) qt_internal_find_standalone_parts_qt_packages(__standalone_parts_qt_packages_args) diff --git a/cmake/QtTargetHelpers.cmake b/cmake/QtTargetHelpers.cmake index 397628ba11a..da210820bb2 100644 --- a/cmake/QtTargetHelpers.cmake +++ b/cmake/QtTargetHelpers.cmake @@ -925,6 +925,12 @@ function(qt_internal_export_additional_targets_file_finalizer id) list(LENGTH arg_TARGETS num_TARGETS) + if(num_TARGETS EQUAL 0) + # Return early without creating and installing the additional file if there are no targets + # to process. + return() + endif() + # Determine the release configurations we're currently building if(QT_GENERATOR_IS_MULTI_CONFIG) set(active_configurations ${CMAKE_CONFIGURATION_TYPES}) diff --git a/cmake/QtToolHelpers.cmake b/cmake/QtToolHelpers.cmake index fe568d09ee6..5d531818ebd 100644 --- a/cmake/QtToolHelpers.cmake +++ b/cmake/QtToolHelpers.cmake @@ -360,21 +360,181 @@ echo. > ${target_bin_dir}/${target}_try_run_passed" DEPENDS ${target_bin_dir}/${target}_try_run_passed) endfunction() +# Create a standalone FooTools package, similar to the ones automatically generated by +# qt_internal_add_module, e.g. Core -> CoreTools. +# +# A standalone tools package can be useful when one wants to associate some special targets and +# cmake scripts to a package that is not associated with any Qt module, and is not architecture +# dependent (e.g. java binaries). +# +# Arguments +# PACKAGE_BASE_NAME - base name of the package, e.g. for a value of Foo, it will create a +# Qt6FooToolsConfig.cmake file. +# +# PACKAGE_VERSION - version to use for the package, defaults to PROJECT_VERSION. +# +# EXTRA_CMAKE_FILES - list of additional cmake files to install alongside the package +# +# EXTRA_CMAKE_INCLUDES - list of cmake files to include in the package config file +# +# EXTRA_CMAKE_STATEMENTS - list of additional cmake statements (strings) to append to the end of +# the package config file. +# +# TOOL_TARGETS - list of add_executable targets that should be install(EXPORT)ed for this package. +# It can NOT take imported targets or custom targets. +# +# TOOL_PACKAGE_DEPENDENCIES - list of other Qt Tools package dependencies that should be +# find_package'd when using this Tools package. +function(qt_internal_add_tools_package) + set(opt_args "") + set(single_args + PACKAGE_BASE_NAME + PACKAGE_VERSION + ) + set(multi_args + EXTRA_CMAKE_FILES + EXTRA_CMAKE_INCLUDES + EXTRA_CMAKE_STATEMENTS + TOOL_TARGETS + TOOL_PACKAGE_DEPENDENCIES + ) + cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}") + _qt_internal_validate_all_args_are_parsed(arg) + + if(NOT arg_PACKAGE_BASE_NAME) + message(FATAL_ERROR "Missing PACKAGE_BASE_NAME value") + endif() + + if(arg_PACKAGE_VERSION) + set(tools_package_version "${arg_PACKAGE_VERSION}") + else() + set(tools_package_version "${PROJECT_VERSION}") + endif() + + set(id "${arg_PACKAGE_BASE_NAME}") + _qt_internal_append_to_cmake_property_without_duplicates(_qt_standalone_tool_packages "${id}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_package_base_name "${id}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_version + "${tools_package_version}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_list_dir + "${CMAKE_CURRENT_LIST_DIR}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_extra_cmake_files + "${arg_EXTRA_CMAKE_FILES}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_extra_cmake_includes + "${arg_EXTRA_CMAKE_INCLUDES}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_extra_cmake_statements + "${arg_EXTRA_CMAKE_STATEMENTS}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_tool_targets + "${arg_TOOL_TARGETS}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_tool_package_dependencies + "${arg_TOOL_PACKAGE_DEPENDENCIES}") +endfunction() + +# Creates a FooTools package with information about tool targets. +# The source of information for the created package is taken either from a Qt module and its +# tool targets, or from global properties associated with a standalone tools package. function(qt_export_tools module_name) + set(opt_args "") + set(single_args + MODULE_NAME + PACKAGE_BASE_NAME + ) + set(multi_args "") + cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}") + _qt_internal_validate_all_args_are_parsed(arg) + # Bail out when not building tools. if(NOT QT_WILL_BUILD_TOOLS) return() endif() - # If no tools were defined belonging to this module, don't create a config and targets file. - if(NOT "${module_name}" IN_LIST QT_KNOWN_MODULES_WITH_TOOLS) - return() + if(NOT arg_MODULE_NAME AND NOT arg_PACKAGE_BASE_NAME) + message(FATAL_ERROR "Either MODULE_NAME or PACKAGE_BASE_NAME must be specified") endif() - # The tools target name. For example: CoreTools - set(target "${module_name}Tools") + # Qt module case. + if(arg_MODULE_NAME) + # The tools package name. For example: CoreTools + set(module_name "${arg_MODULE_NAME}") + + # If no tools were defined belonging to this module, don't create a config and targets file. + if(NOT "${module_name}" IN_LIST QT_KNOWN_MODULES_WITH_TOOLS) + return() + endif() + + set(package_name "${module_name}Tools") + set(known_tools ${QT_KNOWN_MODULE_${module_name}_TOOLS}) + endif() + + # Standalone package case. + if(arg_PACKAGE_BASE_NAME) + set(package_name "${arg_PACKAGE_BASE_NAME}Tools") + + set(id "${arg_PACKAGE_BASE_NAME}") + + get_cmake_property(standalone_tools_package_version + _qt_standalone_tool_package_${id}_version) + if(NOT standalone_tools_package_version) + message(FATAL_ERROR "Missing version for standalone tools package ${id}") + endif() + + get_cmake_property(standalone_tools_list_dir + _qt_standalone_tool_package_${id}_list_dir) + if(NOT standalone_tools_list_dir) + set(standalone_tools_list_dir "") + endif() + + get_cmake_property(package_extra_cmake_files + _qt_standalone_tool_package_${id}_extra_cmake_files) + if(NOT package_extra_cmake_files) + set(package_extra_cmake_files "") + endif() - set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}") + get_cmake_property(package_extra_cmake_includes + _qt_standalone_tool_package_${id}_extra_cmake_includes) + if(NOT package_extra_cmake_includes) + set(package_extra_cmake_includes "") + endif() + + get_cmake_property(package_extra_cmake_statements + _qt_standalone_tool_package_${id}_extra_cmake_statements) + if(NOT package_extra_cmake_statements) + set(package_extra_cmake_statements "") + endif() + + get_cmake_property(known_tools _qt_standalone_tool_package_${id}_tool_targets) + if(NOT known_tools) + set(known_tools "") + endif() + + get_cmake_property(tool_package_dependencies + _qt_standalone_tool_package_${id}_tool_package_dependencies) + if(NOT tool_package_dependencies) + set(tool_package_dependencies "") + endif() + + get_cmake_property(third_party_package_dependencies + _qt_standalone_tool_package_${id}_third_party_dependencies) + if(NOT third_party_package_dependencies) + set(third_party_package_dependencies "") + endif() + + unset(id) + endif() + + # This is used as a substitution variable, ala @target@ in the config / dependencies / + # etc files. + set(target ${package_name}) + + set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${package_name}") qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix}) qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix}) @@ -395,7 +555,16 @@ function(qt_export_tools module_name) set(first_tool_package_version "") - set(known_tools ${QT_KNOWN_MODULE_${module_name}_TOOLS}) + if(package_extra_cmake_files) + list(APPEND extra_cmake_files ${package_extra_cmake_files}) + foreach(cmake_file ${package_extra_cmake_files}) + file(COPY "${cmake_file}" DESTINATION "${config_build_dir}") + endforeach() + endif() + + if(package_extra_cmake_includes) + list(APPEND extra_cmake_includes ${package_extra_cmake_includes}) + endif() foreach(tool_name IN LISTS known_tools) # Specific tools can have package dependencies. @@ -429,9 +598,10 @@ function(qt_export_tools module_name) if (QT_WILL_RENAME_TOOL_TARGETS) string(REGEX REPLACE "_native$" "" tool_name ${tool_name}) endif() - # `__qt_${target}_targets_file_included` is defined in the QtModuleToolsConfig.cmake.in + # `__qt_${package_name}_targets_file_included` is defined in the + # QtModuleToolsConfig.cmake.in set(extra_cmake_statements "${extra_cmake_statements} -if(__qt_${target}_targets_file_included AND ${INSTALL_CMAKE_NAMESPACE}${target}_FOUND) +if(__qt_${package_name}_targets_file_included AND ${INSTALL_CMAKE_NAMESPACE}${package_name}_FOUND) __qt_internal_promote_target_to_global(${INSTALL_CMAKE_NAMESPACE}::${tool_name}) endif() ") @@ -446,29 +616,64 @@ endif() endif() endforeach() - string(APPEND extra_cmake_statements -"set(${QT_CMAKE_EXPORT_NAMESPACE}${module_name}Tools_TARGETS \"${tool_targets}\")") + if(tool_targets) + string(APPEND extra_cmake_statements +"set(${QT_CMAKE_EXPORT_NAMESPACE}${package_name}Tools_TARGETS \"${tool_targets}\")") + endif() + + if(package_extra_cmake_statements) + foreach(statement ${package_extra_cmake_statements}) + string(APPEND extra_cmake_statements "\n${statement}") + endforeach() + endif() # Extract package dependencies that were determined in QtPostProcess, but only if ${module_name} # is an actual target. # module_name can be a non-existent target, if the tool doesn't have an existing associated # module, e.g. qtwaylandscanner. - if(TARGET "${module_name}") + if(module_name AND TARGET "${module_name}") get_target_property(module_package_deps "${module_name}" _qt_tools_package_deps) if(module_package_deps) list(APPEND package_deps "${module_package_deps}") endif() endif() - # Configure and install dependencies file for the ${module_name}Tools package. + if(tool_package_dependencies) + list(APPEND package_deps "${tool_package_dependencies}") + endif() + + if(third_party_package_dependencies) + foreach(third_party_dep IN LISTS third_party_package_dependencies) + list(GET third_party_dep 0 third_party_dep_name) + list(GET third_party_dep 1 third_party_dep_version) + + # Assume that all tool thirdparty deps are mandatory. + # TODO: Components are not supported + list(APPEND third_party_deps + "${third_party_dep_name}\\\;FALSE\\\;${third_party_dep_version}\\\;\\\;") + endforeach() + endif() + + # Generate ConfigExtras.cmake if a template exists. Include it first. + set(config_extras_path_in + "${standalone_tools_list_dir}/${path_suffix}ConfigExtras.cmake.in") + if(EXISTS "${config_extras_path_in}") + configure_file("${config_extras_path_in}" + "${config_build_dir}/${path_suffix}ConfigExtras.cmake" + @ONLY) + list(PREPEND extra_cmake_files "${config_build_dir}/${path_suffix}ConfigExtras.cmake") + list(PREPEND extra_cmake_includes "${path_suffix}ConfigExtras.cmake") + endif() + + # Configure and install dependencies file for the ${package_name}Tools package. configure_file( "${QT_CMAKE_DIR}/QtModuleToolsDependencies.cmake.in" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Dependencies.cmake" @ONLY ) qt_install(FILES - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Dependencies.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) @@ -481,29 +686,43 @@ endif() ) endif() - # Configure and install the ${module_name}Tools package Config file. + # Used in the template. + set(QT_SHOULD_INCLUDE_TARGETS_CODE FALSE) + if(known_tools) + set(QT_SHOULD_INCLUDE_TARGETS_CODE TRUE) + endif() + + # Configure and install the ${package_name}Tools package Config file. qt_internal_get_min_new_policy_cmake_version(min_new_policy_version) qt_internal_get_max_new_policy_cmake_version(max_new_policy_version) configure_package_config_file( "${QT_CMAKE_DIR}/QtModuleToolsConfig.cmake.in" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Config.cmake" INSTALL_DESTINATION "${config_install_dir}" ) - qt_configure_file( - OUTPUT "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" - CONTENT + if(known_tools) + qt_configure_file( + OUTPUT + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}TargetsPrecheck.cmake" + CONTENT "_qt_internal_should_include_targets( TARGETS ${known_tools} NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: - OUT_VAR_SHOULD_SKIP __qt_${target}_skip_include_targets_file + OUT_VAR_SHOULD_SKIP __qt_${package_name}_skip_include_targets_file ) ") + endif() - # There might be Tools packages which don't have a corresponding real module_name target, like - # WaylandScannerTools. - # In that case we'll use the package version of the first tool that belongs to that package. - if(TARGET "${module_name}") + # There are multiple sources where a tools' package version can come from. + # For a standalone tools package, it is explicitly given. + # For a package associated with a Qt module, it comes from a module. + # For a package without a Qt module, like WaylandScannerTools, + # we'll use the package version of the first tool that belongs to that package. + if(standalone_tools_package_version) + # Use the explicitly given package version. + set(tools_package_version "${standalone_tools_package_version}") + elseif(TARGET "${module_name}") qt_internal_get_package_version_of_target("${module_name}" tools_package_version) elseif(first_tool_package_version) set(tools_package_version "${first_tool_package_version}") @@ -513,56 +732,63 @@ endif() set(tools_package_version "${PROJECT_VERSION}") if(FEATURE_developer_build) message(WARNING - "Could not determine package version of tools package ${module_name}. " + "Could not determine package version of tools package ${package_name}. " "Defaulting to project version ${PROJECT_VERSION}.") endif() endif() message(TRACE - "Exporting tools package ${module_name}Tools with package version ${tools_package_version}" + "Exporting tools package ${package_name}Tools with package version ${tools_package_version}" "\n included targets: ${tool_targets_non_prefixed}") write_basic_package_version_file( - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersionImpl.cmake" VERSION "${tools_package_version}" COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT ) qt_internal_write_qt_package_version_file( - "${INSTALL_CMAKE_NAMESPACE}${target}" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + "${INSTALL_CMAKE_NAMESPACE}${package_name}" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersion.cmake" ) qt_install(FILES - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Config.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersion.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersionImpl.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) - set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets") - qt_install(EXPORT "${export_name}" - NAMESPACE "${QT_CMAKE_EXPORT_NAMESPACE}::" - DESTINATION "${config_install_dir}") - - qt_internal_export_additional_targets_file( - TARGETS ${QT_KNOWN_MODULE_${module_name}_TOOLS} - TARGET_EXPORT_NAMES ${tool_targets} - EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} - CONFIG_INSTALL_DIR "${config_install_dir}") + if(known_tools) + qt_install(FILES + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}TargetsPrecheck.cmake" + DESTINATION "${config_install_dir}" + COMPONENT Devel + ) - # Create versionless targets file. - configure_file( - "${QT_CMAKE_DIR}/QtModuleToolsVersionlessTargets.cmake.in" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}VersionlessTargets.cmake" - @ONLY - ) + set(export_name "${INSTALL_CMAKE_NAMESPACE}${package_name}Targets") + qt_install(EXPORT "${export_name}" + NAMESPACE "${QT_CMAKE_EXPORT_NAMESPACE}::" + DESTINATION "${config_install_dir}") + + qt_internal_export_additional_targets_file( + TARGETS ${known_tools} + TARGET_EXPORT_NAMES ${tool_targets} + EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${package_name} + CONFIG_INSTALL_DIR "${config_install_dir}") + + # Create versionless targets file. + configure_file( + "${QT_CMAKE_DIR}/QtModuleToolsVersionlessTargets.cmake.in" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}VersionlessTargets.cmake" + @ONLY + ) - qt_install(FILES - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}VersionlessTargets.cmake" - DESTINATION "${config_install_dir}" - COMPONENT Devel - ) + qt_install(FILES + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}VersionlessTargets.cmake" + DESTINATION "${config_install_dir}" + COMPONENT Devel + ) + endif() endfunction() # Returns the target name for the tool with the given name. diff --git a/cmake/QtVcpkgManifestHelpers.cmake b/cmake/QtVcpkgManifestHelpers.cmake new file mode 100644 index 00000000000..1b556610915 --- /dev/null +++ b/cmake/QtVcpkgManifestHelpers.cmake @@ -0,0 +1,354 @@ +# CMake API for generating vcpkg.json manifest files + +# Initialize the internal vcpkg manifest data with the given JSON string. +# +# This function is called internally by qt_vcpkg_manifest_init and may be used to set the internal +# JSON data to a JSON string read from a file. +function(qt_vcpkg_set_internal_manifest_data json) + set_property(GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON "${json}") +endfunction() + +# Initialize a new vcpkg manifest with basic package information. +# +# This function creates the foundation for a vcpkg.json manifest file by setting up +# the basic structure with package name and version. It must be called before any +# other qt_vcpkg_* functions. +# +# Arguments: +# NAME - Required. The package name for the vcpkg manifest +# VERSION - Optional. The package version string +# BUILTIN_BASELINE - Optional. Baseline for version resolution. +function(qt_vcpkg_manifest_init) + set(no_value_options "") + set(single_value_options + BUILTIN_BASELINE + NAME + VERSION + ) + set(multi_value_options "") + cmake_parse_arguments(PARSE_ARGV 0 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + if(arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + + if(NOT DEFINED arg_NAME) + message(FATAL_ERROR "qt_vcpkg_manifest_init: NAME is required") + endif() + + string(JSON manifest_json SET "{}" name "\"${arg_NAME}\"") + string(JSON manifest_json SET "${manifest_json}" dependencies "[]") + string(JSON manifest_json SET "${manifest_json}" features "{}") + string(JSON manifest_json SET "${manifest_json}" default-features "[]") + if(DEFINED arg_VERSION) + string(JSON manifest_json SET "${manifest_json}" version "\"${arg_VERSION}\"") + endif() + if(DEFINED arg_BUILTIN_BASELINE) + string(JSON manifest_json SET "${manifest_json}" builtin-baseline + "\"${arg_BUILTIN_BASELINE}\"" + ) + endif() + + qt_vcpkg_set_internal_manifest_data("${manifest_json}") +endfunction() + +# Add a dependency to the vcpkg manifest. +# +# This function adds either a simple string dependency or a complex dependency object +# to the manifest's dependencies array or to a specific feature's dependencies. +# +# Arguments: +# dependency - Required. The name of the package dependency +# VERSION - Optional. Specific version constraint for the dependency +# PLATFORM - Optional. Platform expression to limit when dependency is used +# FEATURES - Optional. List of features to enable for this dependency +# DEFAULT_FEATURES - Optional. Boolean to set default-features. +# ADD_TO_FEATURE - Optional. Name of feature to add this dependency to. If not specified, +# adds to the manifest's root dependencies array. +# +# If VERSION, PLATFORM, FEATURES, or DEFAULT_FEATURES are specified, a complex dependency object is +# created. When FEATURES is specified, "default-features": false is automatically set. Otherwise, a +# simple string dependency is added. +# +# If ADD_TO_FEATURE is specified but the feature doesn't exist, it will be created with a default +# description. +function(qt_vcpkg_add_dependency name) + set(no_value_options "") + set(single_value_options + ADD_TO_FEATURE + DEFAULT_FEATURES + PLATFORM + VERSION + ) + set(multi_value_options + FEATURES + ) + cmake_parse_arguments(PARSE_ARGV 1 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + if(arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + + get_property(manifest_json GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON) + if(NOT manifest_json) + message(FATAL_ERROR "qt_vcpkg_add_dependency: Must call qt_vcpkg_manifest_init first") + endif() + + if(arg_ADD_TO_FEATURE) + # Check if feature exists, create with default description if not + string(JSON feature_obj ERROR_VARIABLE feature_error GET "${manifest_json}" features + ${arg_ADD_TO_FEATURE} + ) + if(feature_error) + string(JSON feature_obj SET "{}" description "\"Use ${arg_ADD_TO_FEATURE}\"") + endif() + + string(JSON deps_exists ERROR_VARIABLE deps_error GET "${feature_obj}" dependencies) + if(deps_error) + string(JSON feature_obj SET "${feature_obj}" dependencies "[]") + endif() + + set(target_obj "${feature_obj}") + set(target_path "features" "${arg_ADD_TO_FEATURE}") + else() + set(target_obj "${manifest_json}") + set(target_path "") + endif() + + string(JSON deps_length LENGTH "${target_obj}" dependencies) + if(DEFINED arg_VERSION OR DEFINED arg_FEATURES OR DEFINED arg_PLATFORM + OR DEFINED arg_DEFAULT_FEATURES) + string(JSON dep_obj SET "{}" name "\"${name}\"") + + if(arg_VERSION) + string(JSON dep_obj SET "${dep_obj}" version>= "\"${arg_VERSION}\"") + endif() + + if(arg_FEATURES) + if(NOT DEFINED arg_DEFAULT_FEATURES) + set(arg_DEFAULT_FEATURES OFF) + endif() + string(JSON dep_obj SET "${dep_obj}" features "[]") + set(feature_index 0) + foreach(feature ${arg_FEATURES}) + string(JSON dep_obj SET "${dep_obj}" features ${feature_index} "\"${feature}\"") + math(EXPR feature_index "${feature_index} + 1") + endforeach() + endif() + + if(DEFINED arg_DEFAULT_FEATURES) + if(arg_DEFAULT_FEATURES) + string(JSON dep_obj SET "${dep_obj}" default-features true) + else() + string(JSON dep_obj SET "${dep_obj}" default-features false) + endif() + endif() + + if(arg_PLATFORM) + string(JSON dep_obj SET "${dep_obj}" platform "\"${arg_PLATFORM}\"") + endif() + + string(JSON target_obj SET "${target_obj}" dependencies ${deps_length} "${dep_obj}") + else() + string(JSON target_obj SET "${target_obj}" dependencies ${deps_length} "\"${name}\"") + endif() + + if(arg_ADD_TO_FEATURE) + string(JSON manifest_json SET "${manifest_json}" features ${arg_ADD_TO_FEATURE} + "${target_obj}" + ) + else() + set(manifest_json "${target_obj}") + endif() + + set_property(GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON "${manifest_json}") +endfunction() + +# Add a feature definition to the vcpkg manifest. +# +# This function creates or updates a basic feature in the manifest with the specified +# description and metadata. It does not modify feature dependencies - use the dedicated +# dependency functions for that purpose. +# +# Arguments: +# name - Required. The feature name +# description - Required. Human-readable description of the feature +# DEFAULT - Optional flag. If set, feature is added to default-features +# SUPPORTS - Optional. Platform expression defining where feature is supported +# +# The function preserves existing dependencies when updating an existing feature. +function(qt_vcpkg_feature name description) + set(no_value_options DEFAULT) + set(single_value_options SUPPORTS) + set(multi_value_options "") + cmake_parse_arguments(PARSE_ARGV 2 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + if(arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + + get_property(manifest_json GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON) + if(NOT manifest_json) + message(FATAL_ERROR "qt_vcpkg_feature: Must call qt_vcpkg_manifest_init first") + endif() + + string(JSON feature_obj ERROR_VARIABLE feature_error GET "${manifest_json}" features ${name}) + if(feature_error) + set(feature_obj "{}") + endif() + string(JSON feature_obj SET "${feature_obj}" description "\"${description}\"") + + if(arg_SUPPORTS) + string(JSON feature_obj SET "${feature_obj}" supports "\"${arg_SUPPORTS}\"") + endif() + + string(JSON manifest_json SET "${manifest_json}" features ${name} "${feature_obj}") + + if(arg_DEFAULT) + string(JSON default_features_length LENGTH "${manifest_json}" default-features) + string(JSON manifest_json SET "${manifest_json}" default-features ${default_features_length} + "\"${name}\"" + ) + endif() + + set_property(GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON "${manifest_json}") +endfunction() + +# Add feature dependencies to an existing feature. +# +# This function creates self-referential dependencies where one feature in a package +# depends on other features in the same package. +# +# Arguments: +# feature_name - Required. Name of the feature to modify +# dependency_features - Required. List of features this feature depends on +# +# Creates a dependency object with the package's own name and the specified features, +# with "default-features": false to only enable the specified features. +function(qt_vcpkg_add_feature_dependencies feature_name) + set(dependency_features ${ARGN}) + + get_property(manifest_json GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON) + if(NOT manifest_json) + message(FATAL_ERROR + "qt_vcpkg_add_feature_dependencies: Must call qt_vcpkg_manifest_init first" + ) + endif() + + string(JSON package_name GET "${manifest_json}" name) + qt_vcpkg_add_dependency(${package_name} ADD_TO_FEATURE ${feature_name} + FEATURES ${dependency_features} + ) +endfunction() + +# Write the vcpkg manifest to a file. +# +# This function serializes the current manifest JSON structure to the specified +# output file. +# +# Arguments: +# output_file - Required. Path where the vcpkg.json manifest should be written +# +# The function removes empty top-level elements from the manifest before writing +# to avoid cluttering the output file. +function(qt_vcpkg_write_manifest output_file) + get_property(manifest_json GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON) + if(NOT manifest_json) + message(FATAL_ERROR "qt_vcpkg_write_manifest: Must call qt_vcpkg_manifest_init first") + endif() + + # Remove empty elements + foreach(element_name IN ITEMS dependencies features default-features) + string(JSON element_length LENGTH "${manifest_json}" "${element_name}") + if(element_length EQUAL 0) + string(JSON manifest_json REMOVE "${manifest_json}" "${element_name}") + endif() + endforeach() + + file(CONFIGURE OUTPUT "${output_file}" CONTENT "${manifest_json}") + message(STATUS "Generated vcpkg manifest: ${output_file}") +endfunction() + +# Return the default-features of the current manifest in out_var. +# +# This function reads the default-features from the internal manifest data and +# writes their names to out_var. +function(qt_vcpkg_get_default_features out_var) + get_property(manifest_json GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON) + if(NOT manifest_json) + message(FATAL_ERROR "qt_vcpkg_get_default_features: Must call qt_vcpkg_manifest_init first") + endif() + + set("${out_var}" "" PARENT_SCOPE) + string(JSON default_features ERROR_VARIABLE json_error GET "${manifest_json}" default-features) + if(json_error) + return() + endif() + string(JSON default_features_length ERROR_VARIABLE json_error LENGTH "${default_features}") + if(json_error) + return() + endif() + + set(result "") + math(EXPR max_i "${default_features_length} - 1") + foreach(i RANGE 0 ${max_i}) + string(JSON element ERROR_VARIABLE json_error GET "${default_features}" "${i}") + if(json_error) + continue() + endif() + string(JSON element_type ERROR_VARIABLE json_error TYPE "${default_features}" "${i}") + if(json_error) + continue() + endif() + + set(feature "") + if(element_type STREQUAL "STRING") + set(feature "${element}") + elseif(element_type STREQUAL "OBJECT") + string(JSON feature ERROR_VARIABLE json_error GET "${element}" "name") + if(json_error) + continue() + endif() + endif() + + list(APPEND result "${feature}") + endforeach() + + set("${out_var}" "${result}" PARENT_SCOPE) +endfunction() + +# Return the names of all features in the current manifest in out_var. +# +# This function reads the features map from the current manifest and returns its keys +# (the feature names) in out_var. +function(qt_vcpkg_get_features out_var) + get_property(manifest_json GLOBAL PROPERTY _QT_VCPKG_MANIFEST_JSON) + if(NOT manifest_json) + message(FATAL_ERROR "qt_vcpkg_get_features: Must call qt_vcpkg_manifest_init first") + endif() + + set("${out_var}" "" PARENT_SCOPE) + string(JSON features_obj ERROR_VARIABLE json_error GET "${manifest_json}" features) + if(json_error) + return() + endif() + string(JSON features_length ERROR_VARIABLE json_error LENGTH "${features_obj}") + if(json_error) + return() + endif() + + set(result "") + math(EXPR max_i "${features_length} - 1") + foreach(i RANGE 0 ${max_i}) + string(JSON feature ERROR_VARIABLE json_error MEMBER "${features_obj}" ${i}) + if(json_error) + continue() + endif() + list(APPEND result "${feature}") + endforeach() + + set("${out_var}" "${result}" PARENT_SCOPE) +endfunction() diff --git a/cmake/QtWrapperScriptHelpers.cmake b/cmake/QtWrapperScriptHelpers.cmake index f76d52bca91..95380386300 100644 --- a/cmake/QtWrapperScriptHelpers.cmake +++ b/cmake/QtWrapperScriptHelpers.cmake @@ -98,6 +98,19 @@ export CMAKE_GENERATOR=Xcode endif() file(TO_NATIVE_PATH "${__relative_path_to_cmake_scripts_dir}" __relative_path_to_cmake_scripts_dir) + + # Store arguments we want to forward from configure to qt-configure-module arguments in a + # side-car file. If there's nothing to forward, create an empty file. + set(initial_configure_args "") + if(QT_USE_VCPKG) + list(APPEND initial_configure_args -vcpkg) + endif() + set(side_car_file_name "qt-configure-module-flags.txt") + set(side_car_file_path "${__GlobalConfig_build_dir}/${side_car_file_name}") + string(JOIN "\n" side_car_file_content "${initial_configure_args}") + file(CONFIGURE OUTPUT "${side_car_file_path}" CONTENT "${side_car_file_content}\n") + qt_copy_or_install(FILES "${side_car_file_path}" DESTINATION "${__GlobalConfig_install_dir}") + if(generate_unix) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-configure-module.in" "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-configure-module" @ONLY diff --git a/config_help.txt b/config_help.txt index 583c14a7b20..9550f3f2768 100644 --- a/config_help.txt +++ b/config_help.txt @@ -69,6 +69,7 @@ Build options: system generator. -cmake-file-api ...... Let CMake store build metadata for loading the build into an IDE. [no; yes if -developer-build] + -dry-run ............. Only print the CMake command but don't execute it. -no-guess-compiler ... Do not guess the compiler from the target mkspec. -release ............. Build Qt with optimizations and without debug symbols [yes] @@ -193,7 +194,10 @@ Build environment: -pkg-config .......... Use pkg-config [auto] (Unix only) - -vcpkg ............... Use vcpkg [no] + -vcpkg ............... Use vcpkg for downloading and finding 3rd-party + dependencies [no] + -generate-vcpkg-manifest ... Generate a vcpkg.json file in the build directory + [no; yes if -vcpkg] -D <string> .......... Pass additional preprocessor define -I <string> .......... Pass additional include path diff --git a/configure.cmake b/configure.cmake index 02f4d8b8c84..2c01aafa53b 100644 --- a/configure.cmake +++ b/configure.cmake @@ -8,7 +8,9 @@ #### Libraries qt_find_package(WrapSystemZLIB 1.0.8 MODULE - PROVIDED_TARGETS WrapSystemZLIB::WrapSystemZLIB MODULE_NAME global QMAKE_LIB zlib) + PROVIDED_TARGETS WrapSystemZLIB::WrapSystemZLIB MODULE_NAME global QMAKE_LIB zlib + VCPKG_PORT zlib +) # Work around global target promotion failure when WrapZLIB is used on APPLE platforms. # What ends up happening is that the ZLIB::ZLIB target is not promoted to global by qt_find_package, # then qt_find_package(WrapSystemPNG) tries to find its dependency ZLIB::ZLIB, sees it's not global @@ -24,7 +26,10 @@ endif() # directory scope. qt_find_package(Threads MODULE PROVIDED_TARGETS Threads::Threads) qt_find_package(WrapOpenSSLHeaders MODULE - PROVIDED_TARGETS WrapOpenSSLHeaders::WrapOpenSSLHeaders MODULE_NAME core) + PROVIDED_TARGETS WrapOpenSSLHeaders::WrapOpenSSLHeaders MODULE_NAME core + VCPKG_PORT openssl + VCPKG_ADD_TO_FEATURE openssl +) # openssl_headers # OPENSSL_VERSION_MAJOR is not defined for OpenSSL 1.1.1 qt_config_compile_test(opensslv11_headers @@ -1125,6 +1130,7 @@ elseif(QT_COORD_TYPE STREQUAL "float") endif() qt_feature("gui" PRIVATE LABEL "Qt Gui" + VCPKG_DEFAULT ) qt_feature_config("gui" QMAKE_PUBLIC_QT_CONFIG NEGATE) @@ -1132,6 +1138,7 @@ qt_feature("network" PRIVATE LABEL "Qt Network" SECTION "Module" PURPOSE "Provides the Qt Network module." + VCPKG_DEFAULT ) qt_feature("printsupport" PRIVATE LABEL "Qt PrintSupport" @@ -1143,6 +1150,7 @@ qt_feature("sql" PRIVATE LABEL "Qt Sql" SECTION "Module" PURPOSE "Provides the Sql module." + VCPKG_OPTIONAL ) qt_feature("testlib" PRIVATE LABEL "Qt Testlib" @@ -1170,6 +1178,7 @@ qt_feature("openssl" PRIVATE LABEL "OpenSSL" CONDITION QT_FEATURE_openssl_runtime OR QT_FEATURE_openssl_linked ENABLE false + VCPKG_DEFAULT ) qt_feature_definition("openssl" "QT_NO_OPENSSL" NEGATE) qt_feature_config("openssl" QMAKE_PUBLIC_QT_CONFIG) diff --git a/qt_cmdline.cmake b/qt_cmdline.cmake index 0baa675da46..97a225d670d 100644 --- a/qt_cmdline.cmake +++ b/qt_cmdline.cmake @@ -55,7 +55,6 @@ qt_commandline_option(unity-build-batch-size CMAKE_VARIABLE QT_UNITY_BUILD_BATCH_SIZE ) qt_commandline_option(ccache TYPE boolean NAME ccache CMAKE_VARIABLE QT_USE_CCACHE) -qt_commandline_option(vcpkg TYPE boolean CMAKE_VARIABLE QT_USE_VCPKG) qt_commandline_option(commercial TYPE void) qt_commandline_option(confirm-license TYPE void) qt_commandline_option(dbus TYPE optionalString VALUES no yes linked runtime) diff --git a/src/corelib/Qt6AndroidMacros.cmake b/src/corelib/Qt6AndroidMacros.cmake index 6a83e947146..be362ba1925 100644 --- a/src/corelib/Qt6AndroidMacros.cmake +++ b/src/corelib/Qt6AndroidMacros.cmake @@ -106,6 +106,27 @@ function(qt6_add_android_dynamic_features target) endif() endfunction() + +function(qt_add_android_dynamic_feature_java_source_dirs) + qt6_add_android_dynamic_feature_java_source_dirs(${ARGV}) +endfunction() + +# Add java source directories for dynamic feature. Intermediate solution until java library +# support exists. +function(qt6_add_android_dynamic_feature_java_source_dirs target) + + set(opt_args "") + set(single_args "") + set(multi_args + SOURCE_DIRS + ) + cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}") + if(arg_SOURCE_DIRS) + set_property(TARGET ${target} APPEND PROPERTY + _qt_android_gradle_java_source_dirs ${arg_SOURCE_DIRS}) + endif() +endfunction() + # Generate the deployment settings json file for a cmake target. function(qt6_android_generate_deployment_settings target) # Information extracted from mkspecs/features/android/android_deployment_settings.prf diff --git a/src/corelib/configure.cmake b/src/corelib/configure.cmake index edcfba0f6ce..08908082991 100644 --- a/src/corelib/configure.cmake +++ b/src/corelib/configure.cmake @@ -31,7 +31,10 @@ qt_find_package_extend_sbom(TARGETS GLIB2::GLIB2 LICENSE_EXPRESSION "LGPL-2.1-or-later" ) qt_find_package(ICU 50.1 COMPONENTS i18n uc data PROVIDED_TARGETS ICU::i18n ICU::uc ICU::data - MODULE_NAME core QMAKE_LIB icu) + MODULE_NAME core QMAKE_LIB icu + VCPKG_PORT icu + VCPKG_PLATFORM !windows +) if(QT_FEATURE_dlopen) qt_add_qmake_lib_dependency(icu libdl) @@ -49,7 +52,9 @@ qt_find_package_extend_sbom(TARGETS Libb2::Libb2 qt_find_package(WrapRt MODULE PROVIDED_TARGETS WrapRt::WrapRt MODULE_NAME core QMAKE_LIB librt) qt_find_package(WrapSystemPCRE2 10.20 MODULE - PROVIDED_TARGETS WrapSystemPCRE2::WrapSystemPCRE2 MODULE_NAME core QMAKE_LIB pcre2) + PROVIDED_TARGETS WrapSystemPCRE2::WrapSystemPCRE2 MODULE_NAME core QMAKE_LIB pcre2 + VCPKG_PORT pcre2 +) set_package_properties(WrapPCRE2 PROPERTIES TYPE REQUIRED) if((QNX) OR QT_FIND_ALL_PACKAGES_ALWAYS) qt_find_package(PPS MODULE PROVIDED_TARGETS PPS::PPS MODULE_NAME core QMAKE_LIB pps) diff --git a/src/corelib/doc/src/cmake/qt_add_android_dynamic_feature_java_source_dirs.qdoc b/src/corelib/doc/src/cmake/qt_add_android_dynamic_feature_java_source_dirs.qdoc new file mode 100644 index 00000000000..cf670110cab --- /dev/null +++ b/src/corelib/doc/src/cmake/qt_add_android_dynamic_feature_java_source_dirs.qdoc @@ -0,0 +1,30 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page qt_add_android_dynamic_feature_java_source_dirs.html +\ingroup cmake-commands-qtcore + +\title qt_add_android_dynamic_feature_java_source_dirs +\keyword qt6_add_android_dynamic_feature_java_source_dirs + +\summary {Adds Java source directories to a dynamic feature build.} + +\include cmake-find-package-core.qdocinc + +\cmakecommandsince 6.11 + +\section1 Synopsis + +\badcode +qt_add_android_dynamic_feature_java_source_dirs(target [SOURCE_DIRS <directory1> <directory2> ...]) +\endcode + +\versionlessCMakeCommandsNote qt6_add_android_dynamic_feature_java_source_dirs() + +\section1 Description + +The command adds extra Java/Kotlin source directories to the \c {target} +executable when building the executable app with dynamic feature functionality. +To be used in conjunction with qt6_add_android_dynamic_features(). +*/ diff --git a/src/corelib/itemmodels/qrangemodel_impl.h b/src/corelib/itemmodels/qrangemodel_impl.h index 70552cbfe05..88bd6cf444e 100644 --- a/src/corelib/itemmodels/qrangemodel_impl.h +++ b/src/corelib/itemmodels/qrangemodel_impl.h @@ -28,7 +28,7 @@ #include <functional> #include <iterator> #include <type_traits> -#include <QtCore/q20type_traits.h> +#include <QtCore/qxptype_traits.h> #include <tuple> #include <QtCore/q23utility.h> @@ -562,35 +562,30 @@ namespace QRangeModelDetails } }; - template <typename P, typename R, typename = void> - struct protocol_parentRow : std::false_type {}; template <typename P, typename R> - struct protocol_parentRow<P, R, - std::void_t<decltype(std::declval<P&>().parentRow(std::declval<wrapped_t<R>&>()))>> - : std::true_type {}; + using protocol_parentRow_test = decltype(std::declval<P&>() + .parentRow(std::declval<QRangeModelDetails::wrapped_t<R>&>())); + template <typename P, typename R> + using protocol_parentRow = qxp::is_detected<protocol_parentRow_test, P, R>; - template <typename P, typename R, typename = void> - struct protocol_childRows : std::false_type {}; template <typename P, typename R> - struct protocol_childRows<P, R, - std::void_t<decltype(std::declval<P&>().childRows(std::declval<wrapped_t<R>&>()))>> - : std::true_type {}; + using protocol_childRows_test = decltype(std::declval<P&>() + .childRows(std::declval<QRangeModelDetails::wrapped_t<R>&>())); + template <typename P, typename R> + using protocol_childRows = qxp::is_detected<protocol_childRows_test, P, R>; - template <typename P, typename R, typename = void> - struct protocol_setParentRow : std::false_type {}; template <typename P, typename R> - struct protocol_setParentRow<P, R, - std::void_t<decltype(std::declval<P&>().setParentRow(std::declval<wrapped_t<R>&>(), - std::declval<wrapped_t<R>*>()))>> - : std::true_type {}; + using protocol_setParentRow_test = decltype(std::declval<P&>() + .setParentRow(std::declval<QRangeModelDetails::wrapped_t<R>&>(), + std::declval<QRangeModelDetails::wrapped_t<R>*>())); + template <typename P, typename R> + using protocol_setParentRow = qxp::is_detected<protocol_setParentRow_test, P, R>; - template <typename P, typename R, typename = void> - struct protocol_mutable_childRows : std::false_type {}; template <typename P, typename R> - struct protocol_mutable_childRows<P, R, - std::void_t<decltype(refTo(std::declval<P&>().childRows(std::declval<wrapped_t<R>&>())) - = {}) >> - : std::true_type {}; + using protocol_mutable_childRows_test = decltype(refTo(std::declval<P&>() + .childRows(std::declval<wrapped_t<R>&>())) = {}); + template <typename P, typename R> + using protocol_mutable_childRows = qxp::is_detected<protocol_mutable_childRows_test, P, R>; template <typename P, typename = void> struct protocol_newRow : std::false_type {}; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 02c9f00f301..607dc23f56c 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2696,23 +2696,38 @@ static void err_method_notfound(const QObject *object, case QSIGNAL_CODE: type = "signal"; break; } const char *loc = extract_location(method); + const char *err; if (strchr(method, ')') == nullptr) // common typing mistake - qCWarning(lcConnect, "QObject::%s: Parentheses expected, %s %s::%s%s%s", func, type, - object->metaObject()->className(), method + 1, loc ? " in " : "", loc ? loc : ""); + err = "Parentheses expected,"; else - qCWarning(lcConnect, "QObject::%s: No such %s %s::%s%s%s", func, type, - object->metaObject()->className(), method + 1, loc ? " in " : "", loc ? loc : ""); + err = "No such"; + qCWarning(lcConnect, "QObject::%s: %s %s %s::%s%s%s", func, err, type, + object->metaObject()->className(), method + 1, loc ? " in " : "", loc ? loc : ""); +} + +enum class ConnectionEnd : bool { Sender, Receiver }; +Q_DECL_COLD_FUNCTION +static void err_info_about_object(const char *func, const QObject *o, ConnectionEnd end) +{ + if (!o) + return; + const QString name = o->objectName(); + if (name.isEmpty()) + return; + const bool sender = end == ConnectionEnd::Sender; + qCWarning(lcConnect, "QObject::%s: (%s name:%*s'%ls')", + func, + sender ? "sender" : "receiver", + sender ? 3 : 1, // ← length of generated whitespace + "", + qUtf16Printable(name)); } Q_DECL_COLD_FUNCTION static void err_info_about_objects(const char *func, const QObject *sender, const QObject *receiver) { - QString a = sender ? sender->objectName() : QString(); - QString b = receiver ? receiver->objectName() : QString(); - if (!a.isEmpty()) - qCWarning(lcConnect, "QObject::%s: (sender name: '%s')", func, a.toLocal8Bit().data()); - if (!b.isEmpty()) - qCWarning(lcConnect, "QObject::%s: (receiver name: '%s')", func, b.toLocal8Bit().data()); + err_info_about_object(func, sender, ConnectionEnd::Sender); + err_info_about_object(func, receiver, ConnectionEnd::Receiver); } Q_DECL_COLD_FUNCTION diff --git a/src/gui/accessible/linux/qspimatchrulematcher.cpp b/src/gui/accessible/linux/qspimatchrulematcher.cpp index 1c8f17ac335..48357f7ae63 100644 --- a/src/gui/accessible/linux/qspimatchrulematcher.cpp +++ b/src/gui/accessible/linux/qspimatchrulematcher.cpp @@ -24,8 +24,9 @@ QSpiMatchRuleMatcher::QSpiMatchRuleMatcher(const QSpiMatchRule &matchRule) { // extract roles encoded in bitset stored in multiple 32 bit integers for (qsizetype i = 0; i < matchRule.roles.size(); ++i) { + const auto role = matchRule.roles.at(i); for (int j = 0; j < 32; j++) { - if (matchRule.roles.at(i) & (1 << j)) { + if (role & (1 << j)) { const auto atspiRole = i * 32 + j; if (atspiRole < ATSPI_ROLE_LAST_DEFINED) m_roles.insert(AtspiRole(atspiRole)); @@ -37,6 +38,7 @@ QSpiMatchRuleMatcher::QSpiMatchRuleMatcher(const QSpiMatchRule &matchRule) } // use qualified interface names to match what accessibleInterfaces() returns + m_interfaces.reserve(matchRule.interfaces.size()); for (const QString &ifaceName : matchRule.interfaces) m_interfaces.push_back("org.a11y.atspi."_L1 + ifaceName); } diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake index dac2d072e42..b14f7e74ad2 100644 --- a/src/gui/configure.cmake +++ b/src/gui/configure.cmake @@ -30,6 +30,7 @@ set_property(CACHE INPUT_libpng PROPERTY STRINGS undefined no qt system) #### Libraries qt_set01(X11_SUPPORTED LINUX OR HPUX OR FREEBSD OR NETBSD OR OPENBSD OR SOLARIS OR HURD) +qt_feature_vcpkg_scope(gui) qt_find_package(ATSPI2 MODULE PROVIDED_TARGETS PkgConfig::ATSPI2 MODULE_NAME gui QMAKE_LIB atspi) qt_find_package(DirectFB PROVIDED_TARGETS PkgConfig::DirectFB MODULE_NAME gui QMAKE_LIB directfb) qt_find_package(Libdrm MODULE PROVIDED_TARGETS Libdrm::Libdrm MODULE_NAME gui QMAKE_LIB drm) @@ -39,15 +40,26 @@ qt_find_package(PlatformGraphics qt_find_package(EGL MODULE PROVIDED_TARGETS EGL::EGL MODULE_NAME gui QMAKE_LIB egl) qt_find_package(WrapSystemFreetype 2.2.0 MODULE - PROVIDED_TARGETS WrapSystemFreetype::WrapSystemFreetype MODULE_NAME gui QMAKE_LIB freetype) + PROVIDED_TARGETS WrapSystemFreetype::WrapSystemFreetype MODULE_NAME gui QMAKE_LIB freetype + VCPKG_PORT freetype + VCPKG_ADD_TO_FEATURE freetype +) if(QT_FEATURE_system_zlib) qt_add_qmake_lib_dependency(freetype zlib) endif() -qt_find_package(Fontconfig PROVIDED_TARGETS Fontconfig::Fontconfig MODULE_NAME gui QMAKE_LIB fontconfig) +qt_find_package(Fontconfig PROVIDED_TARGETS Fontconfig::Fontconfig MODULE_NAME gui + QMAKE_LIB fontconfig + VCPKG_PORT fontconfig + VCPKG_ADD_TO_FEATURE fontconfig + VCPKG_PLATFORM "linux" +) qt_add_qmake_lib_dependency(fontconfig freetype) qt_find_package(gbm MODULE PROVIDED_TARGETS gbm::gbm MODULE_NAME gui QMAKE_LIB gbm) qt_find_package(WrapSystemHarfbuzz 2.6.0 MODULE - PROVIDED_TARGETS WrapSystemHarfbuzz::WrapSystemHarfbuzz MODULE_NAME gui QMAKE_LIB harfbuzz) + PROVIDED_TARGETS WrapSystemHarfbuzz::WrapSystemHarfbuzz MODULE_NAME gui QMAKE_LIB harfbuzz + VCPKG_PORT harfbuzz + VCPKG_ADD_TO_FEATURE harfbuzz +) qt_find_package(Libinput MODULE PROVIDED_TARGETS Libinput::Libinput MODULE_NAME gui QMAKE_LIB libinput) qt_find_package_extend_sbom(TARGETS Libinput::Libinput @@ -61,11 +73,20 @@ qt_find_package_extend_sbom(TARGETS Libinput::Libinput "Copyright © 2013-2015 Red Hat, Inc." ) qt_find_package(WrapSystemJpeg MODULE - PROVIDED_TARGETS WrapSystemJpeg::WrapSystemJpeg MODULE_NAME gui QMAKE_LIB libjpeg) + PROVIDED_TARGETS WrapSystemJpeg::WrapSystemJpeg MODULE_NAME gui QMAKE_LIB libjpeg + VCPKG_PORT libjpeg-turbo + VCPKG_ADD_TO_FEATURE jpeg +) qt_find_package(WrapSystemMd4c MODULE - PROVIDED_TARGETS WrapSystemMd4c::WrapSystemMd4c MODULE_NAME gui QMAKE_LIB libmd4c) + PROVIDED_TARGETS WrapSystemMd4c::WrapSystemMd4c MODULE_NAME gui QMAKE_LIB libmd4c + VCPKG_PORT md4c + VCPKG_ADD_TO_FEATURE textmarkdownreader +) qt_find_package(WrapSystemPNG MODULE - PROVIDED_TARGETS WrapSystemPNG::WrapSystemPNG MODULE_NAME gui QMAKE_LIB libpng) + PROVIDED_TARGETS WrapSystemPNG::WrapSystemPNG MODULE_NAME gui QMAKE_LIB libpng + VCPKG_PORT libpng + VCPKG_ADD_TO_FEATURE png +) if(QT_FEATURE_system_zlib) qt_add_qmake_lib_dependency(libpng zlib) endif() diff --git a/src/network/configure.cmake b/src/network/configure.cmake index baadf23dbd7..5dd2af418fa 100644 --- a/src/network/configure.cmake +++ b/src/network/configure.cmake @@ -7,8 +7,12 @@ #### Libraries +qt_feature_vcpkg_scope(network) qt_find_package(WrapBrotli MODULE - PROVIDED_TARGETS WrapBrotli::WrapBrotliDec MODULE_NAME network QMAKE_LIB brotli) + PROVIDED_TARGETS WrapBrotli::WrapBrotliDec MODULE_NAME network QMAKE_LIB brotli + VCPKG_PORT brotli + VCPKG_ADD_TO_FEATURE brotli +) qt_find_package(Libproxy MODULE PROVIDED_TARGETS PkgConfig::Libproxy MODULE_NAME network QMAKE_LIB libproxy) qt_find_package(GSSAPI MODULE PROVIDED_TARGETS GSSAPI::GSSAPI MODULE_NAME network QMAKE_LIB gssapi) diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h index 9a491d4d058..35fb7f24dd5 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h @@ -29,7 +29,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(NSStatusItem); QT_BEGIN_NAMESPACE -class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon +class QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon { public: QCocoaSystemTrayIcon() {} diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h index 13dbdfbfbab..ba3d293e054 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h @@ -9,7 +9,6 @@ #include "qwayland-qt-dmabuf-server-buffer.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "dmabufserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h index a06bc96b87d..01ac4dbe718 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h @@ -9,7 +9,6 @@ #include "qwayland-drm-egl-server-buffer.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "drmeglserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h index 344046ae182..4f9e0aeced5 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h @@ -8,7 +8,6 @@ #include "qwayland-shm-emulation-server-buffer.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "shmserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h index 2f0867a8197..a1c413be5d9 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h @@ -8,7 +8,6 @@ #include "qwayland-qt-vulkan-server-buffer-unstable-v1.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "vulkanserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h index 780f5f3268e..6d86600bad2 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h @@ -82,8 +82,8 @@ private: friend class QWaylandWindow; }; -QT_END_NAMESPACE +} // namespace QtWaylandClient -} +QT_END_NAMESPACE #endif // QWAYLANDSHELLSURFACE_H diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h index bddb5c614e0..e2c54ef0078 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h @@ -52,8 +52,7 @@ public: const QString &app_id); }; -QT_END_NAMESPACE - -} +} // namespace QtWaylandClient +QT_END_NAMESPACE #endif // QWAYLANDXDGACTIVATIONV1_P_H diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h index 8a0cc9e79a7..680fcf69b9f 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h @@ -56,8 +56,7 @@ private: bool m_configured = false; }; -QT_END_NAMESPACE - -} +} // namespace QtWaylandClient +QT_END_NAMESPACE #endif // QWAYLANDXDGDECORATIONV1_P_H diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index a12311eff74..43c17672c23 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -201,8 +201,7 @@ private: friend class QWaylandXdgSurface; }; -QT_END_NAMESPACE - -} +} // namespace QtWaylandClient +QT_END_NAMESPACE #endif // QWAYLANDXDGSHELL_H diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp index 19694eab330..8bf2fb887f1 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp @@ -18,8 +18,8 @@ Q_LOGGING_CATEGORY(lcQpaWindowClass, "qt.qpa.windowclass") QWindowsWindowClassRegistry *QWindowsWindowClassRegistry::m_instance = nullptr; -QWindowsWindowClassRegistry::QWindowsWindowClassRegistry(WNDPROC proc) - : m_proc(proc) +QWindowsWindowClassRegistry::QWindowsWindowClassRegistry(WNDPROC defaultProcedure) + : m_defaultProcedure(defaultProcedure) { m_instance = this; } @@ -69,25 +69,19 @@ QString QWindowsWindowClassRegistry::registerWindowClass(const QWindowsWindowCla // add a UUID. The check needs to be performed for each name // in case new message windows are added (QTBUG-81347). // Note: GetClassInfo() returns != 0 when a class exists. - const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); - WNDCLASS wcinfo; - const bool classExists = GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(className.utf16()), &wcinfo) != FALSE - && wcinfo.lpfnWndProc != description.procedure; - - if (classExists) + if (shouldDecorateWindowClassName(description)) className += QUuid::createUuid().toString(); if (m_registeredWindowClassNames.contains(className)) // already registered in our list return className; - WNDCLASSEX wc; + const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); + + WNDCLASSEX wc{}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = description.style; wc.lpfnWndProc = description.procedure; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; wc.hInstance = appInstance; - wc.hCursor = nullptr; wc.hbrBackground = description.brush; if (description.hasIcon) { wc.hIcon = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE)); @@ -98,15 +92,9 @@ QString QWindowsWindowClassRegistry::registerWindowClass(const QWindowsWindowCla } else { wc.hIcon = static_cast<HICON>(LoadImage(nullptr, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); - wc.hIconSm = nullptr; } } - else { - wc.hIcon = nullptr; - wc.hIconSm = nullptr; - } - wc.lpszMenuName = nullptr; wc.lpszClassName = reinterpret_cast<LPCWSTR>(className.utf16()); ATOM atom = RegisterClassEx(&wc); if (!atom) @@ -122,7 +110,7 @@ QString QWindowsWindowClassRegistry::registerWindowClass(const QWindowsWindowCla QString QWindowsWindowClassRegistry::registerWindowClass(const QWindow *window) { - return registerWindowClass(QWindowsWindowClassDescription::fromWindow(window, m_proc)); + return registerWindowClass(QWindowsWindowClassDescription::fromWindow(window, m_defaultProcedure)); } QString QWindowsWindowClassRegistry::registerWindowClass(QString name, WNDPROC procedure) @@ -130,6 +118,21 @@ QString QWindowsWindowClassRegistry::registerWindowClass(QString name, WNDPROC p return registerWindowClass(QWindowsWindowClassDescription::fromName(name, procedure)); } +bool QWindowsWindowClassRegistry::shouldDecorateWindowClassName(const QWindowsWindowClassDescription &description) const +{ + return shouldDecorateWindowClassName(description.name, description.procedure); +} + +bool QWindowsWindowClassRegistry::shouldDecorateWindowClassName(const QString &name, WNDPROC procedure) const +{ + const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); + + WNDCLASS wc{}; + + return GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(name.utf16()), &wc) != FALSE + && wc.lpfnWndProc != procedure; +} + void QWindowsWindowClassRegistry::unregisterWindowClasses() { const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.h b/src/plugins/platforms/windows/qwindowswindowclassregistry.h index c19b4f616fb..c4a36b7f3c4 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.h +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.h @@ -22,7 +22,7 @@ class QWindowsWindowClassRegistry { Q_DISABLE_COPY_MOVE(QWindowsWindowClassRegistry) public: - QWindowsWindowClassRegistry(WNDPROC proc); + QWindowsWindowClassRegistry(WNDPROC defaultProcedure); ~QWindowsWindowClassRegistry(); static QWindowsWindowClassRegistry *instance(); @@ -34,11 +34,13 @@ public: private: static QString classNamePrefix(); + bool shouldDecorateWindowClassName(const QWindowsWindowClassDescription &description) const; + bool shouldDecorateWindowClassName(const QString &name, WNDPROC procedure) const; void unregisterWindowClasses(); static QWindowsWindowClassRegistry *m_instance; - WNDPROC m_proc; + WNDPROC m_defaultProcedure; QSet<QString> m_registeredWindowClassNames; }; diff --git a/src/plugins/sqldrivers/configure.cmake b/src/plugins/sqldrivers/configure.cmake index d96c220d70a..d12917f5631 100644 --- a/src/plugins/sqldrivers/configure.cmake +++ b/src/plugins/sqldrivers/configure.cmake @@ -13,12 +13,22 @@ set_property(CACHE INPUT_sqlite PROPERTY STRINGS undefined qt system) #### Libraries +qt_feature_vcpkg_scope(sql) qt_find_package(DB2 MODULE PROVIDED_TARGETS DB2::DB2 MODULE_NAME sqldrivers QMAKE_LIB db2) -qt_find_package(MySQL MODULE PROVIDED_TARGETS MySQL::MySQL MODULE_NAME sqldrivers QMAKE_LIB mysql) -qt_find_package(PostgreSQL MODULE PROVIDED_TARGETS PostgreSQL::PostgreSQL MODULE_NAME sqldrivers QMAKE_LIB psql) +qt_find_package(MySQL MODULE PROVIDED_TARGETS MySQL::MySQL MODULE_NAME sqldrivers QMAKE_LIB mysql + VCPKG_PORT libmysql + VCPKG_ADD_TO_FEATURE sql-mysql +) +qt_find_package(PostgreSQL MODULE PROVIDED_TARGETS PostgreSQL::PostgreSQL MODULE_NAME sqldrivers QMAKE_LIB psql + VCPKG_PORT libpq + VCPKG_ADD_TO_FEATURE sql-psql +) qt_find_package(Oracle MODULE PROVIDED_TARGETS Oracle::OCI MODULE_NAME sqldrivers QMAKE_LIB oci) qt_find_package(ODBC PROVIDED_TARGETS ODBC::ODBC MODULE_NAME sqldrivers QMAKE_LIB odbc) -qt_find_package(SQLite3 PROVIDED_TARGETS SQLite::SQLite3 MODULE_NAME sqldrivers QMAKE_LIB sqlite3) +qt_find_package(SQLite3 PROVIDED_TARGETS SQLite::SQLite3 MODULE_NAME sqldrivers QMAKE_LIB sqlite3 + VCPKG_PORT sqlite3 + VCPKG_ADD_TO_FEATURE sql-sqlite +) qt_find_package(Interbase MODULE PROVIDED_TARGETS Interbase::Interbase MODULE_NAME sqldrivers QMAKE_LIB ibase) # special case qt_find_package(Mimer MODULE PROVIDED_TARGETS MimerSQL::MimerSQL MODULE_NAME sqldrivers QMAKE_LIB mimer) @@ -60,6 +70,7 @@ qt_feature("sql-psql" PRIVATE qt_feature("sql-sqlite" PRIVATE LABEL "SQLite" CONDITION QT_FEATURE_datestring + VCPKG_DEFAULT ) qt_feature("system-sqlite" PRIVATE SYSTEM_LIBRARY LABEL " Using system provided SQLite" diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp index ffba4f775c8..13682256370 100644 --- a/src/plugins/styles/modernwindows/qwindows11style.cpp +++ b/src/plugins/styles/modernwindows/qwindows11style.cpp @@ -69,6 +69,10 @@ inline bool isAutoRaise(const QStyleOption *option) { return option->state.testFlag(QStyle::State_AutoRaise); } +inline bool hasFocus(const QStyleOption *option) +{ + return option->state.testFlag(QStyle::State_HasFocus); +} enum class ControlState { Normal, Hover, Pressed, Disabled }; inline ControlState calcControlState(const QStyleOption *option) { @@ -125,7 +129,7 @@ static constexpr int percentToAlpha(double percent) return qRound(percent * 255. / 100.); } -static constexpr std::array<QColor, 33> WINUI3ColorsLight { +static constexpr std::array<QColor, 34> WINUI3ColorsLight { QColor(0x00,0x00,0x00,percentToAlpha(3.73)), // subtleHighlightColor (fillSubtleSecondary) QColor(0x00,0x00,0x00,percentToAlpha(2.41)), // subtlePressedColor (fillSubtleTertiary) QColor(0x00,0x00,0x00,0x0F), //frameColorLight @@ -144,6 +148,7 @@ static constexpr std::array<QColor, 33> WINUI3ColorsLight { QColor(0xF9,0xF9,0xF9,percentToAlpha(50)), // fillControlSecondary QColor(0xF9,0xF9,0xF9,percentToAlpha(30)), // fillControlTertiary QColor(0xF9,0xF9,0xF9,percentToAlpha(30)), // fillControlDisabled + QColor(0xFF,0xFF,0xFF,percentToAlpha(100)), // fillControlInputActive QColor(0x00,0x00,0x00,percentToAlpha(2.41)), // fillControlAltSecondary QColor(0x00,0x00,0x00,percentToAlpha(5.78)), // fillControlAltTertiary QColor(0x00,0x00,0x00,percentToAlpha(9.24)), // fillControlAltQuarternary @@ -161,7 +166,7 @@ static constexpr std::array<QColor, 33> WINUI3ColorsLight { QColor(0x00,0x00,0x00,percentToAlpha(8.03)), // dividerStrokeDefault }; -static constexpr std::array<QColor, 33> WINUI3ColorsDark { +static constexpr std::array<QColor, 34> WINUI3ColorsDark { QColor(0xFF,0xFF,0xFF,percentToAlpha(6.05)), // subtleHighlightColor (fillSubtleSecondary) QColor(0xFF,0xFF,0xFF,percentToAlpha(4.19)), // subtlePressedColor (fillSubtleTertiary) QColor(0xFF,0xFF,0xFF,0x12), //frameColorLight @@ -180,6 +185,7 @@ static constexpr std::array<QColor, 33> WINUI3ColorsDark { QColor(0xFF,0xFF,0xFF,percentToAlpha(8.37)), // fillControlSecondary QColor(0xFF,0xFF,0xFF,percentToAlpha(3.26)), // fillControlTertiary QColor(0xFF,0xFF,0xFF,percentToAlpha(4.19)), // fillControlDisabled + QColor(0x1E,0x1E,0x1E,percentToAlpha(70)), // fillControlInputActive QColor(0x00,0x00,0x00,percentToAlpha(10.0)), // fillControlAltDefault QColor(0xFF,0xFF,0xFF,percentToAlpha(4.19)), // fillControlAltSecondary QColor(0xFF,0xFF,0xFF,percentToAlpha(6.98)), // fillControlAltTertiafillCy @@ -197,7 +203,7 @@ static constexpr std::array<QColor, 33> WINUI3ColorsDark { QColor(0xFF,0xFF,0xFF,percentToAlpha(8.37)), // dividerStrokeDefault }; -static constexpr std::array<std::array<QColor,33>, 2> WINUI3Colors { +static constexpr std::array<std::array<QColor,34>, 2> WINUI3Colors { WINUI3ColorsLight, WINUI3ColorsDark }; @@ -990,16 +996,9 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption case PE_PanelLineEdit: if (const auto *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5)); - drawRoundedRect(painter, frameRect, Qt::NoPen, option->palette.brush(QPalette::Base)); - + drawRoundedRect(painter, frameRect, Qt::NoPen, inputFillBrush(option, widget)); if (panel->lineWidth > 0) proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget); - - const bool isMouseOver = state & State_MouseOver; - const bool hasFocus = state & State_HasFocus; - const bool isEnabled = state & State_Enabled; - if (isMouseOver && isEnabled && hasFocus && !highContrastTheme) - drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor)); } break; case PE_FrameLineEdit: { @@ -2674,6 +2673,23 @@ QBrush QWindows11Style::controlFillBrush(const QStyleOption *option, ControlType return winUI3Color(colorEnums[int(controlType)][int(state)]); } +QBrush QWindows11Style::inputFillBrush(const QStyleOption *option, const QWidget *widget) const +{ + // slightly different states than in controlFillBrush + using namespace StyleOptionHelper; + const auto role = widget ? widget->backgroundRole() : QPalette::Window; + if (option->palette.isBrushSet(QPalette::Current, role)) + return option->palette.button(); + + if (isDisabled(option)) + return winUI3Color(fillControlDisabled); + if (hasFocus(option)) + return winUI3Color(fillControlInputActive); + if (isHover(option)) + return winUI3Color(fillControlSecondary); + return winUI3Color(fillControlDefault); +} + QColor QWindows11Style::controlTextColor(const QStyleOption *option, QPalette::ColorRole role) const { using namespace StyleOptionHelper; diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h index a51a93ddd9b..96c2c4136e0 100644 --- a/src/plugins/styles/modernwindows/qwindows11style_p.h +++ b/src/plugins/styles/modernwindows/qwindows11style_p.h @@ -42,6 +42,7 @@ enum WINUI3Color { fillControlSecondary, // button hover color (alpha) fillControlTertiary, // button pressed color (alpha) fillControlDisabled, // button disabled color (alpha) + fillControlInputActive, // input active fillControlAltSecondary, // checkbox/RadioButton default color (alpha) fillControlAltTertiary, // checkbox/RadioButton hover color (alpha) fillControlAltQuarternary, // checkbox/RadioButton pressed color (alpha) @@ -101,6 +102,7 @@ private: ControlAlt }; QBrush controlFillBrush(const QStyleOption *option, ControlType controlType) const; + QBrush inputFillBrush(const QStyleOption *option, const QWidget *widget) const; // ControlType::ControlAlt can be mapped to QPalette directly QColor controlTextColor(const QStyleOption *option, QPalette::ColorRole role = QPalette::ButtonText) const; diff --git a/tests/auto/cmake/RunCMake/CMakeLists.txt b/tests/auto/cmake/RunCMake/CMakeLists.txt index ec182debccd..aac9b43bac7 100644 --- a/tests/auto/cmake/RunCMake/CMakeLists.txt +++ b/tests/auto/cmake/RunCMake/CMakeLists.txt @@ -30,3 +30,7 @@ if(TARGET Qt6::Platform) qt_internal_add_RunCMake_test(Sbom ${extra_run_cmake_args}) endif() endif() + +list(APPEND extra_run_cmake_args "-DQT_WILL_INSTALL=${QT_WILL_INSTALL}") +list(APPEND extra_run_cmake_args "-DQT_REPO_MODULE_VERSION=${QT_REPO_MODULE_VERSION}") +qt_internal_add_RunCMake_test(StandaloneToolsPackage ${extra_run_cmake_args}) diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/CMakeLists.txt b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/CMakeLists.txt new file mode 100644 index 00000000000..d490ae0713c --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(${RunCMake_TEST} LANGUAGES CXX VERSION "${QT_REPO_MODULE_VERSION}") +include(${RunCMake_TEST}.cmake) diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/Qt6GarageToolsConfigExtras.cmake.in b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/Qt6GarageToolsConfigExtras.cmake.in new file mode 100644 index 00000000000..35271634fde --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/Qt6GarageToolsConfigExtras.cmake.in @@ -0,0 +1 @@ +set(QT_GARAGE_TOOLS_CONFIG_EXTRAS_LOADED TRUE) diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/Qt6GarageToolsExtraInclude.cmake b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/Qt6GarageToolsExtraInclude.cmake new file mode 100644 index 00000000000..4997381e6f4 --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/Qt6GarageToolsExtraInclude.cmake @@ -0,0 +1 @@ +set(QT_GARAGE_TOOLS_EXTRA_INCLUDE_LOADED TRUE) diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/RunCMakeTest.cmake b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/RunCMakeTest.cmake new file mode 100644 index 00000000000..4581f694f5a --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/RunCMakeTest.cmake @@ -0,0 +1,56 @@ +# Copyright (C) 2025 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +include(QtRunCMake) + +set(build_case "build_and_install_tools_package") +set(consume_case "consume_tools_package") +set(consume_case_via_module "consume_tools_package_via_module") + +function(run_cmake_and_build case) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build) + + # Set an install prefix that is common to both projects. + set(cmake_install_prefix ${RunCMake_BINARY_DIR}/installed) + + set(options + "-DQt6_DIR=${Qt6_DIR}" + "-DQT_REPO_MODULE_VERSION=${QT_REPO_MODULE_VERSION}" + ) + + # For prefix builds, install into a separate dir rather than the Qt one. + # For non-prefix, files will end up being copied to the Qt dir. + if(QT_WILL_INSTALL) + list(APPEND options + "-DCMAKE_INSTALL_PREFIX=${cmake_install_prefix}" + "-DQT_ADDITIONAL_PACKAGES_PREFIX_PATH=${cmake_install_prefix}" + "-DQT_ADDITIONAL_HOST_PACKAGES_PREFIX_PATH=${cmake_install_prefix}" + ) + endif() + + # Merge output, because some of configure also outputs some stuff to stderr even when + # everything is fine and CMake treats it as an error. + set(RunCMake_TEST_OUTPUT_MERGE 1) + + # Configure. + run_cmake_with_options(${case} ${options}) + + # Do not remove the current RunCMake_TEST_BINARY_DIR for the next operations. + set(RunCMake_TEST_NO_CLEAN 1) + + # Build and install + run_cmake_command(${case}-build "${CMAKE_COMMAND}" --build .) + + if(QT_WILL_INSTALL) + run_cmake_command(${case}-install "${CMAKE_COMMAND}" --install .) + endif() +endfunction() + +# Build and install the tools package. +run_cmake_and_build("${build_case}") + +# Find the tools package. +run_cmake_and_build("${consume_case}") + +# Find the tools package via module. +run_cmake_and_build("${consume_case_via_module}") diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/build_and_install_tools_package.cmake b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/build_and_install_tools_package.cmake new file mode 100644 index 00000000000..7cc9ecc38d1 --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/build_and_install_tools_package.cmake @@ -0,0 +1,48 @@ +# Copyright (C) 2025 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +find_package(Qt6 REQUIRED COMPONENTS Core BuildInternals) + +# Avoid erorrs in CI about unsupported SDK and Xcode versions on older CI macOS versions. +if(APPLE) + set(QT_NO_APPLE_SDK_AND_XCODE_CHECK ON) +endif() + +qt_internal_project_setup() + +qt_build_repo_begin() + +set(base_name "Garage") +set(extra_file_base_path "${CMAKE_CURRENT_SOURCE_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}${base_name}") + +# Add a standalone tools package. +qt_internal_add_tools_package( + PACKAGE_BASE_NAME ${base_name} + EXTRA_CMAKE_FILES + "${extra_file_base_path}ToolsExtraInclude.cmake" + EXTRA_CMAKE_INCLUDES + "${QT_CMAKE_EXPORT_NAMESPACE}${base_name}ToolsExtraInclude.cmake" +) + +# Check that we can add third party dependencies to the tools package. +qt_internal_record_tools_package_extra_third_party_dependency( + PACKAGE_BASE_NAME ${base_name} + DEPENDENCY_PACKAGE_NAME WrapScrewdriver) + +# Add a module that should be look up the standalone tools package when the module itself is +# looked up. +qt_internal_add_module(Workshop + HEADER_MODULE + NO_MODULE_HEADERS + NO_PRIVATE_MODULE + NO_GENERATE_CPP_EXPORTS + NO_ADDITIONAL_TARGET_INFO + NO_GENERATE_METATYPES + NO_PACKAGE_CONFIG_FILE + NO_MODULE_JSON_FILE + NO_QMAKE_SUPPORT_FILES +) +qt_record_extra_qt_main_tools_package_dependency(Workshop GarageTools "6") + +qt_build_repo_post_process() +qt_build_repo_end() diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/cmake/FindWrapScrewdriver.cmake b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/cmake/FindWrapScrewdriver.cmake new file mode 100644 index 00000000000..484dc8f35d8 --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/cmake/FindWrapScrewdriver.cmake @@ -0,0 +1,2 @@ +set(WrapScrewdriver_FOUND TRUE) +set(QT_SCREW_DRIVER_LOADED TRUE) diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/consume_tools_package.cmake b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/consume_tools_package.cmake new file mode 100644 index 00000000000..9b37905d569 --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/consume_tools_package.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2025 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +find_package(Qt6 REQUIRED COMPONENTS GarageTools) + +if(NOT QT_GARAGE_TOOLS_CONFIG_EXTRAS_LOADED) + message(FATAL_ERROR "Qt6GarageToolsConfigExtras.cmake was not loaded.") +endif() + +if(NOT QT_GARAGE_TOOLS_EXTRA_INCLUDE_LOADED) + message(FATAL_ERROR "Qt6GarageToolsExtraInclude.cmake was not loaded.") +endif() + +if(NOT QT_SCREW_DRIVER_LOADED) + message(FATAL_ERROR "FindWrapScrewdriver.cmake was not loaded.") +endif() diff --git a/tests/auto/cmake/RunCMake/StandaloneToolsPackage/consume_tools_package_via_module.cmake b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/consume_tools_package_via_module.cmake new file mode 100644 index 00000000000..4fe592a1f69 --- /dev/null +++ b/tests/auto/cmake/RunCMake/StandaloneToolsPackage/consume_tools_package_via_module.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2025 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +find_package(Qt6 REQUIRED COMPONENTS Workshop) + +if(NOT QT_GARAGE_TOOLS_CONFIG_EXTRAS_LOADED) + message(FATAL_ERROR "Qt6GarageToolsConfigExtras.cmake was not loaded.") +endif() + +if(NOT QT_GARAGE_TOOLS_EXTRA_INCLUDE_LOADED) + message(FATAL_ERROR "Qt6GarageToolsExtraInclude.cmake was not loaded.") +endif() + +if(NOT QT_SCREW_DRIVER_LOADED) + message(FATAL_ERROR "FindWrapScrewdriver.cmake was not loaded.") +endif() diff --git a/tests/auto/corelib/text/qlocaledata/tst_qlocaledata.cpp b/tests/auto/corelib/text/qlocaledata/tst_qlocaledata.cpp index a63dea4c679..93024bb4a6c 100644 --- a/tests/auto/corelib/text/qlocaledata/tst_qlocaledata.cpp +++ b/tests/auto/corelib/text/qlocaledata/tst_qlocaledata.cpp @@ -260,7 +260,7 @@ void tst_QLocaleData::numericData_data() << u"\u00D7\u06F1\u06F0^"_s << GS(1, 3, 3) << U'\u06F0' << false; // Grouping separator variants: - QTest::newRow("gsw-Latn-CH/exp") // Right single quote for grouping: + QTest::newRow("gsw-Latn-CH/exp") // Uses apostrophe for grouping (matching C++): << LOCALE_DATA_PTR(SwissGerman, LatinScript, Switzerland) << QLocaleData::DoubleScientificMode << u"."_s << u"'"_s << u"\u2212"_s << u"+"_s << u"E"_s |
