aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/Qt6QmlMacros.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/Qt6QmlMacros.cmake')
-rw-r--r--src/qml/Qt6QmlMacros.cmake428
1 files changed, 382 insertions, 46 deletions
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake
index 5352f896f6..e37e99ea6a 100644
--- a/src/qml/Qt6QmlMacros.cmake
+++ b/src/qml/Qt6QmlMacros.cmake
@@ -13,6 +13,129 @@ set(__qt_qml_macros_module_base_dir "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "
include(GNUInstallDirs)
_qt_internal_add_deploy_support("${CMAKE_CURRENT_LIST_DIR}/Qt6QmlDeploySupport.cmake")
+# This function is used to parse DEPENDENCY and IMPORT entries passed to qt_add_qml_module
+# It takes the entry as a mandatory argument, and then sets the following
+# user provided properties in the callers scope
+# OUTPUT_URI <property>: the URI of the module; mandatory argument
+# OUTPUT_VERSION <property>: the requested version of the module; will potentially be empty; mandatory
+# OUTPUT_MODULE_LOCATION <property>: the folder in which the module is located; optional; can be used to extract potential import path
+# OUTPUT_MODULE_TARGET <property>: the target corresponding to the module
+
+function(_qt_internal_parse_qml_module_dependency dependency was_marked_as_target)
+ set(args_option "")
+ set(args_single OUTPUT_URI OUTPUT_VERSION OUTPUT_MODULE_LOCATION OUTPUT_MODULE_TARGET)
+ set(args_multi QML_FILES IMPORT_PATHS)
+
+ cmake_parse_arguments(PARSE_ARGV 2 arg
+ "${args_option}" "${args_single}" "${args_multi}"
+ )
+ if(arg_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown/unexpected arguments: ${arg_UNPARSED_ARGUMENTS}")
+ endif()
+
+ if(NOT arg_OUTPUT_URI)
+ message(FATAL_ERROR "Missing output URI variable")
+ endif()
+ if(NOT arg_OUTPUT_VERSION)
+ message(FATAL_ERROR "Missing output version variable")
+ endif()
+
+ set(dep_version "")
+ set(dep_target_or_uri "")
+ string(FIND "${dependency}" "/" slash_position REVERSE)
+ if(slash_position EQUAL -1)
+ set(dep_target_or_uri "${dependency}")
+ else()
+ string(SUBSTRING "${dependency}" 0 ${slash_position} dep_module)
+ math(EXPR slash_position "${slash_position} + 1")
+ string(SUBSTRING "${dependency}" ${slash_position} -1 dep_version)
+ if(NOT dep_version MATCHES "^([0-9]+(\\.[0-9]+)?|auto)$")
+ message(FATAL_ERROR
+ "Invalid module dependency version number. "
+ "Expected 'VersionMajor', 'VersionMajor.VersionMinor' or 'auto'."
+ )
+ endif()
+ set(dep_target_or_uri "${dep_module}")
+ endif()
+ if("${was_marked_as_target}" AND NOT TARGET ${dep_target_or_uri})
+ message(FATAL_ERROR "Argument ${dep_target_or_uri} is not a target!")
+ endif()
+ if("${was_marked_as_target}")
+ qt6_query_qml_module(${dep_target_or_uri}
+ URI dependency_uri
+ QMLDIR qmldir_location
+ )
+ set(dep_module ${dependency_uri})
+ else()
+ set(dep_module "${dep_target_or_uri}")
+ endif()
+ set(${arg_OUTPUT_URI} ${dep_module} PARENT_SCOPE)
+ set(${arg_OUTPUT_VERSION} ${dep_version} PARENT_SCOPE)
+ if(arg_OUTPUT_MODULE_LOCATION)
+ if(was_marked_as_target)
+ if(NOT qmldir_location)
+ message(FATAL_ERROR "module has no qmldir! Given target was ${dep_target_or_uri}")
+ endif()
+ set(module_location "${qmldir_location}")
+ string(REGEX MATCHALL "\\." matches "${dependency_uri}")
+ list(LENGTH matches go_up_count)
+ # inclusive, which is what we want here: go up once for the qmldir,
+ # and then once per separated component
+ foreach(i RANGE ${go_up_count})
+ get_filename_component(module_location "${module_location}" DIRECTORY)
+ endforeach()
+ set(${arg_OUTPUT_MODULE_LOCATION} "${module_location}" PARENT_SCOPE)
+ else()
+ set(${arg_OUTPUT_MODULE_LOCATION} "NOTFOUND" PARENT_SCOPE)
+ endif()
+ endif()
+ if (arg_OUTPUT_MODULE_TARGET AND was_marked_as_target)
+ set(${arg_OUTPUT_MODULE_TARGET} "${dep_target_or_uri}" PARENT_SCOPE)
+ else()
+ set(${arg_OUTPUT_MODULE_TARGET} "" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_qt_internal_write_deferred_builddir_qtconf folder)
+ set(qt_all_qml_output_dirs "")
+ get_directory_property(targets
+ DIRECTORY "${folder}"
+ QT_QML_TARGETS_FOR_DEFERRED_QTCONF_WRITEOUT
+ )
+ set(qtconf_file "${folder}/qt.conf")
+ foreach(target IN LISTS ${targets})
+ get_target_property(dependency_targets "${target}" QT_QML_DEPENDENT_QML_MODULE_TARGETS)
+ if(NOT dependency_targets)
+ continue()
+ endif()
+ foreach(dep_target ${dependency_targets})
+ qt6_query_qml_module(${dep_target}
+ QMLDIR qmldir_location
+ )
+ get_filename_component(module_location "${qmldir_location}" DIRECTORY)
+ get_filename_component(module_import_path "${module_location}" DIRECTORY)
+ list(APPEND qt_all_qml_output_dirs ${module_import_path})
+ endforeach()
+ endforeach()
+ if (NOT qt_all_qml_output_dirs)
+ return()
+ endif()
+
+ list(REMOVE_DUPLICATES qt_all_qml_output_dirs)
+ # lists are just strings containing semicolons;
+ # we replace them with "," to get the right format for qtconf.
+ # However, we need to add quotes to deal with whitespace
+ list(TRANSFORM qt_all_qml_output_dirs APPEND "\"")
+ list(TRANSFORM qt_all_qml_output_dirs PREPEND "\"")
+ list(JOIN qt_all_qml_output_dirs "," qt_all_qml_output_dirs)
+
+ configure_file(
+ ${__qt_qml_macros_module_base_dir}/Qt6qtconf.in ${qtconf_file}
+ @ONLY
+ )
+endfunction()
+
+
function(qt6_add_qml_module target)
set(args_option
STATIC
@@ -30,8 +153,6 @@ function(qt6_add_qml_module target)
NO_CACHEGEN
NO_RESOURCE_TARGET_PATH
NO_IMPORT_SCAN
- # TODO: Remove once all usages have also been removed
- SKIP_TYPE_REGISTRATION
ENABLE_TYPE_COMPILER
# Used to mark modules as having static side effects (i.e. if they install an image provider)
@@ -112,12 +233,6 @@ function(qt6_add_qml_module target)
)
endif()
- if(arg_SKIP_TYPE_REGISTRATION)
- message(AUTHOR_WARNING
- "SKIP_TYPE_REGISTRATION is no longer used and will be ignored."
- )
- endif()
-
# Mandatory arguments
if (NOT arg_URI)
message(FATAL_ERROR
@@ -399,53 +514,93 @@ function(qt6_add_qml_module target)
set(arg_TYPEINFO ${target}.qmltypes)
endif()
+ set(all_qml_import_paths "${arg_IMPORT_PATH}")
+ set(all_dependency_targets)
+
+ set(original_no_show_policy_value "${QT_NO_SHOW_OLD_POLICY_WARNINGS}")
+ # silent by default, we only warn if someone uses TARGET as a URI
+ set(QT_NO_SHOW_OLD_POLICY_WARNINGS TRUE)
+ __qt_internal_setup_policy(QTP0005 "6.8.0"
+ "" # intentionally empty as we silence the warning anyway
+ )
+ qt6_policy(GET QTP0005 allow_targets_for_dependencies_policy)
+ set(QT_NO_SHOW_OLD_POLICY_WARNINGS "${original_no_show_policy_value}")
+ string(COMPARE EQUAL "${allow_targets_for_dependencies_policy}" "NEW" target_is_keyword)
+
+
+ set(target_keyword_was_set FALSE)
foreach(import_set IN ITEMS IMPORTS OPTIONAL_IMPORTS DEFAULT_IMPORTS)
foreach(import IN LISTS arg_${import_set})
- string(FIND ${import} "/" slash_position REVERSE)
- if (slash_position EQUAL -1)
+ if (import STREQUAL "TARGET")
+ if (target_is_keyword)
+ set(target_keyword_was_set TRUE)
+ continue()
+ else()
+ message(AUTHOR_WARNING "TARGET is treated as a URI because QTP0005 is set to OLD. This is deprecated behavior. Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0005.html for policy details.")
+ set(target_keyword_was_set FALSE)
+ endif()
+ endif()
+ _qt_internal_parse_qml_module_dependency(${import} ${target_keyword_was_set}
+ OUTPUT_URI import_uri
+ OUTPUT_VERSION import_version
+ OUTPUT_MODULE_LOCATION module_location
+ OUTPUT_MODULE_TARGET dependency_target
+ )
+ get_filename_component(module_import_path "${module_location}" DIRECTORY)
+ list(APPEND all_qml_import_paths "${module_import_path}")
+
+ if (NOT "${import_version}" STREQUAL "")
set_property(TARGET ${target} APPEND PROPERTY
- QT_QML_MODULE_${import_set} "${import}"
+ QT_QML_MODULE_${import_set} "${import_uri} ${import_version}"
)
else()
- string(SUBSTRING ${import} 0 ${slash_position} import_module)
- math(EXPR slash_position "${slash_position} + 1")
- string(SUBSTRING ${import} ${slash_position} -1 import_version)
- if (import_version MATCHES "^([0-9]+(\\.[0-9]+)?|auto)$")
- set_property(TARGET ${target} APPEND PROPERTY
- QT_QML_MODULE_${import_set} "${import_module} ${import_version}"
- )
- else()
- message(FATAL_ERROR
- "Invalid module ${import} version number. "
- "Expected 'VersionMajor', 'VersionMajor.VersionMinor' or 'auto'."
- )
- endif()
+ set_property(TARGET ${target} APPEND PROPERTY
+ QT_QML_MODULE_${import_set} "${import_uri}"
+ )
endif()
+ if(TARGET "${dependency_target}")
+ list(APPEND all_dependency_targets "${dependency_target}")
+ endif()
+ set(target_keyword_was_set FALSE)
endforeach()
endforeach()
foreach(dependency IN LISTS arg_DEPENDENCIES)
- string(FIND ${dependency} "/" slash_position REVERSE)
- if (slash_position EQUAL -1)
+
+ if (dependency STREQUAL "TARGET")
+ if (target_is_keyword)
+ set(target_keyword_was_set TRUE)
+ continue()
+ else()
+ message(AUTHOR_WARNING "TARGET is treated as a URI because QTP0005 is set to OLD. This is deprecated behavior. Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0005.html for policy details.")
+ set(target_keyword_was_set FALSE)
+ endif()
+ endif()
+ _qt_internal_parse_qml_module_dependency(${dependency} "${target_keyword_was_set}"
+ OUTPUT_URI dep_uri
+ OUTPUT_VERSION dep_version
+ OUTPUT_MODULE_LOCATION module_location
+ OUTPUT_MODULE_TARGET dependency_target
+ )
+ get_filename_component(module_import_path "${module_location}" DIRECTORY)
+ list(APPEND all_qml_import_paths "${module_import_path}")
+ if (NOT "${dep_version}" STREQUAL "")
set_property(TARGET ${target} APPEND PROPERTY
- QT_QML_MODULE_DEPENDENCIES "${dependency}"
+ QT_QML_MODULE_DEPENDENCIES "${dep_uri} ${dep_version}"
)
else()
- string(SUBSTRING ${dependency} 0 ${slash_position} dep_module_uri)
- math(EXPR slash_position "${slash_position} + 1")
- string(SUBSTRING ${dependency} ${slash_position} -1 dep_version)
- if (dep_version MATCHES "^([0-9]+(\\.[0-9]+)?|auto)$")
- set_property(TARGET ${target} APPEND PROPERTY
- QT_QML_MODULE_DEPENDENCIES "${dep_module_uri} ${dep_version}"
- )
- else()
- message(FATAL_ERROR
- "Invalid module dependency version number. "
- "Expected 'VersionMajor', 'VersionMajor.VersionMinor' or 'auto'."
- )
- endif()
+ set_property(TARGET ${target} APPEND PROPERTY
+ QT_QML_MODULE_DEPENDENCIES "${dep_uri}"
+ )
+ endif()
+ set(target_keyword_was_set FALSE)
+ if(TARGET "${dependency_target}")
+ list(APPEND all_dependency_targets "${dependency_target}")
endif()
endforeach()
+ ### TODO: add support for transitive dependencies, too
+ list(REMOVE_DUPLICATES all_dependency_targets)
+ set_property(TARGET ${target} PROPERTY QT_QML_DEPENDENT_QML_MODULE_TARGETS "${all_dependency_targets}")
_qt_internal_collect_qml_module_dependencies(${target})
if(arg_AUTO_RESOURCE_PREFIX)
@@ -491,6 +646,8 @@ Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html for policy details."
endif()
endif()
+ list(REMOVE_DUPLICATES all_qml_import_paths)
+
set_target_properties(${target} PROPERTIES
QT_QML_MODULE_NO_LINT "${arg_NO_LINT}"
QT_QML_MODULE_NO_CACHEGEN "${arg_NO_CACHEGEN}"
@@ -520,7 +677,7 @@ Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html for policy details."
QT_QML_MODULE_PAST_MAJOR_VERSIONS "${arg_PAST_MAJOR_VERSIONS}"
# TODO: Check how this is used by qt6_android_generate_deployment_settings()
- QT_QML_IMPORT_PATH "${arg_IMPORT_PATH}"
+ QT_QML_IMPORT_PATH "${all_qml_import_paths}"
)
if(arg_TYPEINFO)
@@ -756,7 +913,7 @@ Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html for policy details."
cmake_language(DEFER GET_CALL qmlls_ini_generation_id call)
if("${call}" STREQUAL "")
cmake_language(EVAL CODE
- "cmake_language(DEFER ID qmlls_ini_generation_id CALL _qt_internal_write_deferred_qmlls_ini_file)"
+ "cmake_language(DEFER ID qmlls_ini_generation_id CALL _qt_internal_write_deferred_qmlls_ini_file ${target})"
)
endif()
else()
@@ -767,9 +924,91 @@ Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html for policy details."
endif()
endif()
endif()
+
+ if((backing_target_type STREQUAL "EXECUTABLE") AND (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0"))
+ set_property(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ APPEND
+ PROPERTY QT_QML_TARGETS_FOR_DEFERRED_QTCONF_WRITEOUT
+ ${target}
+ )
+ get_directory_property(is_qtconf_writeout_scheduled DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} QT_QML_BUILDDIR_QTCONF_DEFERRED)
+ if (NOT is_qtconf_writeout_scheduled)
+ set_property(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ PROPERTY QT_QML_BUILDDIR_QTCONF_DEFERRED TRUE
+ )
+
+ cmake_language(EVAL CODE "
+ cmake_language(DEFER DIRECTORY [[${PROJECT_SOURCE_DIR}]]
+ CALL _qt_internal_write_deferred_builddir_qtconf [[${CMAKE_CURRENT_BINARY_DIR}]])
+ ")
+ endif()
+ endif()
+
+ if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.19.0" AND NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ set(id qmlaotstats_aggregation)
+ cmake_language(DEFER DIRECTORY ${PROJECT_BINARY_DIR} GET_CALL ${id} call)
+
+ if("${call}" STREQUAL "")
+ cmake_language(EVAL CODE "cmake_language(DEFER DIRECTORY ${PROJECT_BINARY_DIR} "
+ "ID ${id} CALL _qt_internal_deferred_aggregate_aotstats_files ${target})")
+ endif()
+ else()
+ if(NOT TARGET all_aotstats)
+ if(CMAKE_GENERATOR STREQUAL "Xcode") #TODO: QTBUG-125995
+ add_custom_target(
+ all_aotstats
+ ${CMAKE_COMMAND} -E echo "aotstats is not supported on Xcode"
+ )
+ else()
+ add_custom_target(
+ all_aotstats
+ ${CMAKE_COMMAND} -E echo "aotstats is not supported on CMake versions < 3.19"
+ )
+ endif()
+ endif()
+ endif()
+endfunction()
+
+function(_qt_internal_deferred_aggregate_aotstats_files target)
+ get_property(module_aotstats_files GLOBAL PROPERTY "module_aotstats_files")
+ list(JOIN module_aotstats_files "\n" lines)
+ set(aotstats_list_file "${PROJECT_BINARY_DIR}/.rcc/qmlcache/all_aotstats.aotstatslist")
+ file(WRITE ${aotstats_list_file} ${lines})
+
+ set(all_aotstats_file ${PROJECT_BINARY_DIR}/.rcc/qmlcache/all_aotstats.aotstats)
+ set(formatted_stats_file ${PROJECT_BINARY_DIR}/.rcc/qmlcache/all_aotstats.txt)
+
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
+ add_custom_command(
+ OUTPUT
+ ${all_aotstats_file}
+ ${formatted_stats_file}
+ DEPENDS ${module_aotstats_files}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Qt6::qmlaotstats>
+ aggregate
+ ${aotstats_list_file}
+ ${all_aotstats_file}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Qt6::qmlaotstats>
+ format
+ ${all_aotstats_file}
+ ${formatted_stats_file}
+ )
+
+ if(NOT TARGET all_aotstats)
+ add_custom_target(all_aotstats
+ DEPENDS ${formatted_stats_file}
+ COMMAND ${CMAKE_COMMAND} -E cat ${formatted_stats_file}
+ )
+ endif()
endfunction()
-function(_qt_internal_write_deferred_qmlls_ini_file)
+function(_qt_internal_write_deferred_qmlls_ini_file target)
set(qmlls_ini_file "${CMAKE_CURRENT_SOURCE_DIR}/.qmlls.ini")
get_directory_property(_qmlls_ini_build_folders _qmlls_ini_build_folders)
list(REMOVE_DUPLICATES _qmlls_ini_build_folders)
@@ -780,8 +1019,11 @@ function(_qt_internal_write_deferred_qmlls_ini_file)
# cmake list separator and windows path separator are both ';', so no replacement needed
set(concatenated_build_dirs "${_qmlls_ini_build_folders}")
endif()
- set(file_content "[General]\nbuildDir=${concatenated_build_dirs}\nno-cmake-calls=false\n")
+ set(file_content "[General]\n")
+ string(APPEND file_content "buildDir=${concatenated_build_dirs}\n")
+ string(APPEND file_content "no-cmake-calls=false\n")
file(CONFIGURE OUTPUT "${qmlls_ini_file}" CONTENT "${file_content}")
+ _add_documentation_path_to_qmlls_ini_file(${target} ${qmlls_ini_file})
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
@@ -794,6 +1036,35 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
endfunction()
endif()
+function(_add_documentation_path_to_qmlls_ini_file target qmlls_ini_file)
+ get_target_property(qtpaths ${QT_CMAKE_EXPORT_NAMESPACE}::qtpaths LOCATION)
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
+ set(docPath "${CMAKE_CURRENT_BINARY_DIR}/.docPath.tmp")
+ add_custom_command(
+ OUTPUT
+ ${docPath}
+ COMMAND
+ ${CMAKE_COMMAND} -E echo_append "docDir=" >> ${docPath};
+ COMMAND
+ ${tool_wrapper}
+ ${qtpaths}
+ --query QT_INSTALL_DOCS >> ${docPath}
+ COMMENT "Querying Qt documentation path"
+ VERBATIM
+ )
+ add_custom_target(${target}_custom ALL
+ DEPENDS ${docPath}
+ COMMAND
+ ${CMAKE_COMMAND} -E cat ${docPath} >> ${qmlls_ini_file}
+ COMMAND
+ ${CMAKE_COMMAND} -E rm -rf -- ${docPath}
+ COMMENT "Adding Qt documentation path to .qmlls.ini"
+ VERBATIM
+ )
+ add_dependencies(${target} ${target}_custom)
+
+endfunction()
+
# Make the prefix conform to the following:
# - Starts with a "/"
# - Does not end with a "/" unless the prefix is exactly "/"
@@ -2403,6 +2674,8 @@ function(qt6_target_qml_sources target)
"$<${have_direct_calls}:--direct-calls>"
"$<${have_arguments}:${arguments}>"
${qrc_resource_args}
+ "--dump-aot-stats"
+ "--module-id=${arg_URI}(${target})"
)
# For direct evaluation in if() below
@@ -2613,6 +2886,17 @@ function(qt6_target_qml_sources target)
set_property(TARGET ${target} APPEND_STRING PROPERTY
_qt_internal_qmldir_content "${qmldir_file_contents}"
)
+
+ if(ANDROID AND QT_ANDROID_GENERATE_JAVA_QML_COMPONENTS)
+ get_source_file_property(qml_file_generate_java_classes ${qml_file_src}
+ QT_QML_GENERATE_JAVA_CLASS
+ )
+ if(qml_file_generate_java_classes)
+ get_target_property(qml_module_uri ${target} QT_QML_MODULE_URI)
+ set_property(TARGET ${target} APPEND PROPERTY
+ _qt_qml_files_for_java_generator "${qml_module_uri}.${qml_file_typename}")
+ endif()
+ endif()
endif()
endif()
@@ -2649,9 +2933,17 @@ function(qt6_target_qml_sources target)
set(qmlcachegen_cmd "${qmlcachegen}")
endif()
+ set(aotstats_file "")
+ if("${qml_file_src}" MATCHES ".+\\.qml")
+ set(aotstats_file "${compiled_file}.aotstats")
+ list(APPEND aotstats_files ${aotstats_file})
+ endif()
+
_qt_internal_get_tool_wrapper_script_path(tool_wrapper)
add_custom_command(
- OUTPUT ${compiled_file}
+ OUTPUT
+ ${compiled_file}
+ ${aotstats_file}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir}
COMMAND
${tool_wrapper}
@@ -2695,6 +2987,29 @@ function(qt6_target_qml_sources target)
endif()
endforeach()
+ if(NOT "${arg_URI}" STREQUAL "")
+ list(JOIN aotstats_files "\n" aotstats_files_lines)
+ set(module_aotstats_list_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/module_${arg_URI}.aotstatslist")
+ file(WRITE ${module_aotstats_list_file} ${aotstats_files_lines})
+
+ # Aggregate qml file aotstats into module-level aotstats
+ _qt_internal_get_tool_wrapper_script_path(tool_wrapper)
+ set(output "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/module_${arg_URI}.aotstats")
+ add_custom_command(
+ OUTPUT ${output}
+ DEPENDS ${aotstats_files}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Qt6::qmlaotstats>
+ aggregate
+ ${module_aotstats_list_file}
+ ${output}
+ )
+
+ # Collect module-level aotstats files for later aggregation at the project level
+ set_property(GLOBAL APPEND PROPERTY "module_aotstats_files" ${output})
+ endif()
+
if(ANDROID)
_qt_internal_collect_qml_root_paths("${target}" ${arg_QML_FILES})
endif()
@@ -3825,9 +4140,30 @@ endif()")
# imports deployed to the bundle anyway, the build RPATHs will allow
# the regular libraries, frameworks and non-QML plugins to still be
# found, even if they are outside the app bundle.
+
+ # Support Xcode, which places the application build dir into a configuration specific
+ # subdirectory. Override both the deploy prefix and install prefix, because we
+ # differentiate them in the qml installation implementation due to ENV{DESTDIR}
+ # handling.
+ set(deploy_path_suffix "")
+ get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ set(deploy_path_suffix "/$<CONFIG>")
+ endif()
+
+ set(target_binary_dir_with_config_prefix
+ "$<TARGET_PROPERTY:${arg_TARGET},BINARY_DIR>${deploy_path_suffix}")
+
+ set(post_build_install_prefix
+ "CMAKE_INSTALL_PREFIX=${target_binary_dir_with_config_prefix}")
+
+ set(post_build_deploy_prefix
+ "QT_DEPLOY_PREFIX=${target_binary_dir_with_config_prefix}")
+
add_custom_command(TARGET ${arg_TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND}
- -D "QT_DEPLOY_PREFIX=$<TARGET_PROPERTY:${arg_TARGET},BINARY_DIR>"
+ -D "${post_build_install_prefix}"
+ -D "${post_build_deploy_prefix}"
-D "__QT_DEPLOY_IMPL_DIR=${deploy_impl_dir}"
-D "__QT_DEPLOY_POST_BUILD=TRUE"
-P "${post_build_deploy_script}"