summaryrefslogtreecommitdiffstats
path: root/cmake/QtSyncQtHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtSyncQtHelpers.cmake')
-rw-r--r--cmake/QtSyncQtHelpers.cmake471
1 files changed, 296 insertions, 175 deletions
diff --git a/cmake/QtSyncQtHelpers.cmake b/cmake/QtSyncQtHelpers.cmake
index 84a8e93d80..0188b87c6a 100644
--- a/cmake/QtSyncQtHelpers.cmake
+++ b/cmake/QtSyncQtHelpers.cmake
@@ -1,203 +1,324 @@
-function(qt_ensure_perl)
- find_program(HOST_PERL "perl" DOC "Perl binary")
- if (NOT HOST_PERL)
- message(FATAL_ERROR "Perl needs to be available to build Qt.")
- endif()
-endfunction()
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
-function(qt_ensure_sync_qt)
- qt_ensure_perl()
- if(DEFINED QT_SYNCQT)
- return()
+# The function generates the Qt module header structure in build directory and creates install
+# rules. Apart the lists of header files the function takes into account
+# QT_REPO_PUBLIC_NAMESPACE_REGEX cache variable, that can be set by repository in .cmake.conf file.
+# The variable tells the syncqt program, what namespaces are treated as public. Symbols in public
+# namespaces are considered when generating CaMeL case header files.
+function(qt_internal_target_sync_headers target module_headers module_headers_generated)
+ if(NOT TARGET ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt)
+ message(FATAL_ERROR "${QT_CMAKE_EXPORT_NAMESPACE}::syncqt is not a target.")
endif()
-
- get_property(QT_SYNCQT GLOBAL PROPERTY _qt_syncqt)
- if(NOT "${QT_SYNCQT}" STREQUAL "")
- set(QT_SYNCQT "${QT_SYNCQT}" PARENT_SCOPE)
+ get_target_property(has_headers ${target} _qt_module_has_headers)
+ if(NOT has_headers)
return()
endif()
- # When building qtbase, use the source syncqt, otherwise use the installed one.
- set(SYNCQT_FROM_SOURCE "${QtBase_SOURCE_DIR}/libexec/syncqt.pl")
- if(NOT ("${QtBase_SOURCE_DIR}" STREQUAL "") AND EXISTS "${SYNCQT_FROM_SOURCE}")
- set(syncqt_absolute_path "${SYNCQT_FROM_SOURCE}")
- message(STATUS "Using source syncqt found at: ${syncqt_absolute_path}")
-
- qt_path_join(syncqt_install_dir ${QT_INSTALL_DIR} ${INSTALL_LIBEXECDIR})
- qt_copy_or_install(PROGRAMS "${SYNCQT_FROM_SOURCE}"
- DESTINATION "${syncqt_install_dir}")
- elseif(NOT "${QT_HOST_PATH}" STREQUAL "")
- get_filename_component(syncqt_absolute_path
- "${QT_HOST_PATH}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBEXECDIR}/syncqt.pl"
- ABSOLUTE)
- message(STATUS "Using host syncqt found at: ${syncqt_absolute_path}")
- else()
- get_filename_component(syncqt_absolute_path
- "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}/syncqt.pl"
- ABSOLUTE)
- message(STATUS "Using installed syncqt found at: ${syncqt_absolute_path}")
+ qt_internal_module_info(module "${target}")
+
+ get_target_property(sync_source_directory ${target} _qt_sync_source_directory)
+ set(syncqt_timestamp "${CMAKE_CURRENT_BINARY_DIR}/${target}_syncqt_timestamp")
+ set(syncqt_outputs "${syncqt_timestamp}")
+
+ set(is_interface_lib FALSE)
+ get_target_property(type ${target} TYPE)
+ if(type STREQUAL "INTERFACE_LIBRARY")
+ set(is_interface_lib TRUE)
endif()
- set(QT_SYNCQT "${syncqt_absolute_path}" PARENT_SCOPE)
- set_property(GLOBAL PROPERTY _qt_syncqt "${syncqt_absolute_path}")
-endfunction()
+ set(version_script_private_content_file "")
+ if(NOT is_interface_lib)
+ list(APPEND syncqt_outputs
+ "${module_build_interface_include_dir}/${module}Version"
+ "${module_build_interface_include_dir}/qt${module_lower}version.h")
+ if(TEST_ld_version_script)
+ set(version_script_private_content_file
+ "${CMAKE_CURRENT_BINARY_DIR}/${target}.version.private_content")
+ set(version_script_args
+ "-versionScript" "${version_script_private_content_file}")
+ list(APPEND syncqt_outputs "${version_script_private_content_file}")
+ qt_internal_add_linker_version_script(${target}
+ PRIVATE_CONTENT_FILE "${version_script_private_content_file}")
+ endif()
+ endif()
-function(qt_install_injections target build_dir install_dir)
- set(injections ${ARGN})
- qt_internal_module_info(module ${target})
- get_target_property(target_type ${target} TYPE)
- if (target_type STREQUAL "INTERFACE_LIBRARY")
- set(is_framework FALSE)
+ # Check for _qt_module_is_3rdparty_header_library flag to detect non-Qt modules and
+ # indicate this to syncqt.
+ get_target_property(is_3rd_party_library ${target} _qt_module_is_3rdparty_header_library)
+ set(non_qt_module_argument "")
+ if(is_3rd_party_library)
+ set(non_qt_module_argument "-nonQt")
else()
+ list(APPEND syncqt_outputs "${module_build_interface_include_dir}/${module}")
+ get_target_property(no_headersclean_check ${target} _qt_no_headersclean_check)
+ if(NOT no_headersclean_check)
+ list(APPEND syncqt_outputs
+ "${CMAKE_CURRENT_BINARY_DIR}/${module}_header_check_exceptions")
+ endif()
+ endif()
+
+ set(is_framework FALSE)
+ if(NOT is_interface_lib)
get_target_property(is_framework ${target} FRAMEWORK)
endif()
- # examples:
- # SYNCQT.INJECTIONS = src/corelib/global/qconfig.h:qconfig.h:QtConfig src/corelib/global/qconfig_p.h:5.12.0/QtCore/private/qconfig_p.h
- # SYNCQT.INJECTIONS = src/gui/vulkan/qvulkanfunctions.h:^qvulkanfunctions.h:QVulkanFunctions:QVulkanDeviceFunctions src/gui/vulkan/qvulkanfunctions_p.h:^5.12.0/QtGui/private/qvulkanfunctions_p.h
- # The are 3 parts to the assignment, divded by colons ':'.
- # The first part contains a path to a generated file in a build folder.
- # The second part contains the file name that the forwarding header should have, which points
- # to the file in the first part.
- # The third part contains multiple UpperCaseFileNames that should be forwarding headers to the
- # header specified in the second part.
- separate_arguments(injections UNIX_COMMAND "${injections}")
- foreach(injection ${injections})
- string(REPLACE ":" ";" injection ${injection})
- # Part 1.
- list(GET injection 0 file)
- # Part 2.
- list(GET injection 1 destination)
- string(REGEX REPLACE "^\\^" "" destination "${destination}")
- list(REMOVE_AT injection 0 1)
- # Part 3.
- set(fwd_hdrs ${injection})
- get_filename_component(destinationdir ${destination} DIRECTORY)
- get_filename_component(destinationname ${destination} NAME)
- get_filename_component(original_file_name ${file} NAME)
-
- # This describes a concrete example for easier comprehension:
- # A file 'qtqml-config.h' is generated by qt_internal_feature_write_file into
- # ${qtdeclarative_build_dir}/src/{module_include_name}/qtqml-config.h (part 1).
- #
- # Generate a lower case forwarding header (part 2) 'qtqml-config.h' at the following
- # location:
- # ${some_prefix}/include/${module_include_name}/qtqml-config.h.
- #
- # Inside this file, we #include the originally generated file,
- # ${qtdeclarative_build_dir}/src/{module_include_name}/qtqml-config.h.
- #
- # ${some_prefix}'s value depends on the build type.
- # If doing a prefix build, it should point to
- # ${current_repo_build_dir} which is ${qtdeclarative_build_dir}.
- # If doing a non-prefix build, it should point to
- # ${qtbase_build_dir}.
- #
- # In the code below, ${some_prefix} == ${build_dir}.
- set(lower_case_forwarding_header_path "${build_dir}/include/${module_include_name}")
- if(destinationdir)
- string(APPEND lower_case_forwarding_header_path "/${destinationdir}")
- endif()
- set(current_repo_build_dir "${PROJECT_BINARY_DIR}")
- file(RELATIVE_PATH relpath
- "${lower_case_forwarding_header_path}"
- "${current_repo_build_dir}/${file}")
- set(main_contents "#include \"${relpath}\"")
+ qt_internal_get_qt_all_known_modules(known_modules)
- qt_configure_file(OUTPUT "${lower_case_forwarding_header_path}/${original_file_name}"
- CONTENT "${main_contents}")
+ get_target_property(is_internal_module ${target} _qt_is_internal_module)
+ set(internal_module_argument "")
+ if(is_internal_module)
+ set(internal_module_argument "-internal")
+ endif()
- if(is_framework)
- if(file MATCHES "_p\\.h$")
- set(header_type PRIVATE)
- else()
- set(header_type PUBLIC)
- endif()
- qt_copy_framework_headers(${target} ${header_type}
- ${current_repo_build_dir}/${file})
+ get_target_property(qpa_filter_regex ${target} _qt_module_qpa_headers_filter_regex)
+ get_target_property(rhi_filter_regex ${target} _qt_module_rhi_headers_filter_regex)
+ get_target_property(ssg_filter_regex ${target} _qt_module_ssg_headers_filter_regex)
+ get_target_property(private_filter_regex ${target} _qt_module_private_headers_filter_regex)
+
+ # We need to use the real paths since otherwise it may lead to the invalid work of the
+ # std::filesystem API
+ get_filename_component(source_dir_real "${sync_source_directory}" REALPATH)
+ get_filename_component(binary_dir_real "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
+
+ if(QT_REPO_PUBLIC_NAMESPACE_REGEX)
+ set(public_namespaces_filter -publicNamespaceFilter "${QT_REPO_PUBLIC_NAMESPACE_REGEX}")
+ endif()
+
+ if(qpa_filter_regex)
+ set(qpa_filter_argument
+ -qpaHeadersFilter "${qpa_filter_regex}"
+ )
+ endif()
+
+ if(rhi_filter_regex)
+ set(rhi_filter_argument
+ -rhiHeadersFilter "${rhi_filter_regex}"
+ )
+ endif()
+
+ if(ssg_filter_regex)
+ set(ssg_filter_argument
+ -ssgHeadersFilter "${ssg_filter_regex}"
+ )
+ endif()
+
+ set(common_syncqt_arguments
+ -module "${module}"
+ -sourceDir "${source_dir_real}"
+ -binaryDir "${binary_dir_real}"
+ -privateHeadersFilter "${private_filter_regex}"
+ -includeDir "${module_build_interface_include_dir}"
+ -privateIncludeDir "${module_build_interface_private_include_dir}"
+ -qpaIncludeDir "${module_build_interface_qpa_include_dir}"
+ -rhiIncludeDir "${module_build_interface_rhi_include_dir}"
+ -ssgIncludeDir "${module_build_interface_ssg_include_dir}"
+ -generatedHeaders ${module_headers_generated}
+ ${qpa_filter_argument}
+ ${rhi_filter_argument}
+ ${ssg_filter_argument}
+ ${public_namespaces_filter}
+ ${non_qt_module_argument}
+ ${internal_module_argument}
+ )
+
+ if(QT_INTERNAL_ENABLE_SYNCQT_DEBUG_OUTPUT)
+ list(APPEND common_syncqt_arguments -debug)
+ endif()
+
+ set(build_time_syncqt_arguments "")
+ if(WARNINGS_ARE_ERRORS)
+ if(is_interface_lib)
+ set(warnings_are_errors_enabled_genex 1)
else()
- # Copy the actual injected (generated) header file (not the just created forwarding one)
- # to its install location when doing a prefix build. In an non-prefix build, the qt_install
- # will be a no-op.
- qt_path_join(install_destination
- ${install_dir} ${INSTALL_INCLUDEDIR}
- ${module_include_name} ${destinationdir})
- qt_install(FILES ${current_repo_build_dir}/${file}
- DESTINATION ${install_destination}
- RENAME ${destinationname} OPTIONAL)
+ set(warnings_are_errors_enabled_genex
+ "$<NOT:$<BOOL:$<TARGET_PROPERTY:${target},QT_SKIP_WARNINGS_ARE_ERRORS>>>")
endif()
+ list(APPEND build_time_syncqt_arguments
+ "$<${warnings_are_errors_enabled_genex}:-warningsAreErrors>")
+ endif()
- # Generate UpperCaseNamed forwarding headers (part 3).
- foreach(fwd_hdr ${fwd_hdrs})
- set(upper_case_forwarding_header_path "include/${module_include_name}")
- if(destinationdir)
- string(APPEND upper_case_forwarding_header_path "/${destinationdir}")
- endif()
+ if(is_framework)
+ list(REMOVE_ITEM module_headers "${CMAKE_CURRENT_BINARY_DIR}/${target}_fake_header.h")
+ endif()
+
+ # Filter the generated ui_ header files and header files located in the 'doc/' subdirectory.
+ list(FILTER module_headers EXCLUDE REGEX
+ "(.+/(ui_)[^/]+\\.h|${CMAKE_CURRENT_SOURCE_DIR}(/.+)?/doc/+\\.h)")
- # Generate upper case forwarding header like QVulkanFunctions or QtConfig.
- qt_configure_file(OUTPUT "${build_dir}/${upper_case_forwarding_header_path}/${fwd_hdr}"
- CONTENT "#include \"${destinationname}\"\n")
-
- if(is_framework)
- # Copy the forwarding header to the framework's Headers directory.
- qt_copy_framework_headers(${target} PUBLIC
- "${build_dir}/${upper_case_forwarding_header_path}/${fwd_hdr}")
- else()
- # Install the forwarding header.
- qt_path_join(install_destination "${install_dir}" "${INSTALL_INCLUDEDIR}"
- ${module_include_name})
- qt_install(FILES "${build_dir}/${upper_case_forwarding_header_path}/${fwd_hdr}"
- DESTINATION ${install_destination} OPTIONAL)
+ set(syncqt_staging_dir "${module_build_interface_include_dir}/.syncqt_staging")
+
+ set(syncqt_args "${common_syncqt_arguments}")
+ list(APPEND syncqt_args
+ -headers ${module_headers}
+ -stagingDir "${syncqt_staging_dir}"
+ -knownModules ${known_modules}
+ ${version_script_args}
+ )
+ list(JOIN syncqt_args "\n" syncqt_args_string)
+ set(syncqt_args_rsp "${binary_dir_real}/${target}_syncqt_args")
+ qt_configure_file(OUTPUT "${syncqt_args_rsp}" CONTENT "${syncqt_args_string}")
+
+ get_target_property(external_headers_dir ${target} _qt_external_headers_dir)
+ if(external_headers_dir)
+ if(NOT IS_ABSOLUTE "${external_headers_dir}")
+ get_filename_component(external_headers_dir "${external_headers_dir}" ABSOLUTE)
+ endif()
+ if(EXISTS "${external_headers_dir}")
+ set(external_headers_dir_copy_cmd
+ COMMAND
+ ${CMAKE_COMMAND}
+ -E copy_directory
+ "${external_headers_dir}"
+ "${module_build_interface_include_dir}"
+ )
+ endif()
+ endif()
+ add_custom_command(
+ OUTPUT
+ ${syncqt_outputs}
+ COMMAND
+ ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
+ "@${syncqt_args_rsp}"
+ ${build_time_syncqt_arguments}
+ ${external_headers_dir_copy_cmd}
+ COMMAND
+ ${CMAKE_COMMAND} -E touch "${syncqt_timestamp}"
+ DEPENDS
+ ${syncqt_args_rsp}
+ ${module_headers}
+ ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
+ "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_internal_sync_headers_deps>>"
+ COMMENT
+ "Running syncqt.cpp for module: ${module}"
+ VERBATIM
+ )
+
+ set(add_sync_headers_to_all "")
+ if(is_interface_lib)
+ set(add_sync_headers_to_all ALL)
+ endif()
+
+ add_custom_target(${target}_sync_headers
+ ${add_sync_headers_to_all}
+ DEPENDS
+ ${syncqt_outputs}
+ )
+ add_dependencies(sync_headers ${target}_sync_headers)
+ set_target_properties(${target}
+ PROPERTIES _qt_internal_sync_headers_target ${target}_sync_headers)
+
+ if(is_3rd_party_library)
+ add_dependencies(thirdparty_sync_headers ${target}_sync_headers)
+ endif()
+ # This target is required when building docs, to make all header files and their aliases
+ # available for qdoc.
+ # ${target}_sync_headers is added as dependency to make sure that
+ # ${target}_sync_all_public_headers is running after ${target}_sync_headers, when building docs.
+ set(syncqt_all_args "${common_syncqt_arguments};-all")
+ list(JOIN syncqt_all_args "\n" syncqt_all_args_string)
+ set(syncqt_all_args_rsp "${binary_dir_real}/${target}_syncqt_all_args")
+ qt_configure_file(OUTPUT "${syncqt_all_args_rsp}" CONTENT "${syncqt_all_args_string}")
+ add_custom_target(${target}_sync_all_public_headers
+ COMMAND
+ ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
+ "@${syncqt_all_args_rsp}"
+ ${external_headers_dir_copy_cmd}
+ DEPENDS
+ ${module_headers}
+ ${syncqt_all_args_rsp}
+ ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
+ ${target}_sync_headers
+ VERBATIM
+ )
+
+ if(NOT TARGET sync_all_public_headers)
+ add_custom_target(sync_all_public_headers)
+ endif()
+ add_dependencies(sync_all_public_headers ${target}_sync_all_public_headers)
+
+ if(NOT is_3rd_party_library AND NOT is_framework AND module_headers)
+ # Install all the CaMeL style aliases of header files from the staging directory in one rule
+ qt_install(DIRECTORY "${syncqt_staging_dir}/"
+ DESTINATION "${module_install_interface_include_dir}"
+ )
+ endif()
+
+ if(NOT is_interface_lib)
+ set_property(TARGET ${target}
+ APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "${target}_sync_headers")
+ endif()
+ add_dependencies(${target} "${target}_sync_headers")
+
+
+ get_target_property(private_module_target ${target} _qt_private_module_target_name)
+ if(private_module_target)
+ add_dependencies(${private_module_target} "${target}_sync_headers")
+ endif()
+
+ # Run sync Qt first time at configure step to make all header files available for the code model
+ # of IDEs.
+ get_property(synced_modules GLOBAL PROPERTY _qt_synced_modules)
+ if(NOT "${module}" IN_LIST synced_modules AND QT_SYNC_HEADERS_AT_CONFIGURE_TIME)
+ message(STATUS "Running syncqt.cpp for module: ${module}")
+ get_target_property(syncqt_location ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt LOCATION)
+ execute_process(
+ COMMAND
+ ${syncqt_location}
+ "@${syncqt_args_rsp}"
+ RESULT_VARIABLE syncqt_result
+ OUTPUT_VARIABLE syncqt_output
+ ERROR_VARIABLE syncqt_output
+ )
+ if(NOT syncqt_result EQUAL 0)
+ if(syncqt_output STREQUAL "")
+ string(JOIN "" syncqt_output "The syncqt process exited with code ${syncqt_result}"
+ " and without any useful output. This can happen if syncqt crashes due to the"
+ " incompatibilities with the standard C++ library located by either PATH or"
+ " LD_LIBRARY_PATH environment variables. Please make sure that PATH or"
+ " LD_LIBRARY_PATH don't point to the standard libraries different from the one you"
+ " use for building Qt.")
endif()
- endforeach()
- endforeach()
+ message(FATAL_ERROR
+ "syncqt.cpp failed for module ${module}:\n${syncqt_output}")
+ endif()
+ if(syncqt_output)
+ message(WARNING "${syncqt_output}")
+ endif()
+ set_property(GLOBAL APPEND PROPERTY _qt_synced_modules ${module})
+ endif()
endfunction()
-function(qt_read_headers_pri module_include_dir resultVarPrefix)
- file(STRINGS "${module_include_dir}/headers.pri" headers_pri_contents)
- foreach(line ${headers_pri_contents})
- if("${line}" MATCHES "SYNCQT.HEADER_FILES = (.*)")
- set(public_module_headers "${CMAKE_MATCH_1}")
- separate_arguments(public_module_headers UNIX_COMMAND "${public_module_headers}")
- elseif("${line}" MATCHES "SYNCQT.PRIVATE_HEADER_FILES = (.*)")
- set(private_module_headers "${CMAKE_MATCH_1}")
- separate_arguments(private_module_headers UNIX_COMMAND "${private_module_headers}")
- elseif("${line}" MATCHES "SYNCQT.GENERATED_HEADER_FILES = (.*)")
- set(generated_module_headers "${CMAKE_MATCH_1}")
- separate_arguments(generated_module_headers UNIX_COMMAND "${generated_module_headers}")
- foreach(generated_header ${generated_module_headers})
- list(APPEND public_module_headers "${module_include_dir}/${generated_header}")
- endforeach()
- elseif("${line}" MATCHES "SYNCQT.INJECTIONS = (.*)")
- set(injections "${CMAKE_MATCH_1}")
- elseif("${line}" MATCHES "SYNCQT.([A-Z_]+)_HEADER_FILES = (.+)")
- set(prefix "${CMAKE_MATCH_1}")
- string(TOLOWER "${prefix}" prefix)
- set(entries "${CMAKE_MATCH_2}")
- separate_arguments(entries UNIX_COMMAND "${entries}")
- set("${resultVarPrefix}_${prefix}" "${entries}" PARENT_SCOPE)
+function(qt_internal_collect_sync_header_dependencies out_var skip_non_existing)
+ list(LENGTH ARGN sync_headers_target_count)
+ if(sync_headers_target_count EQUAL 0)
+ message(FATAL_ERROR "Invalid use of qt_internal_collect_sync_header_dependencies,"
+ " dependencies are not specified")
+ endif()
+
+ set(${out_var} "")
+ foreach(sync_headers_target IN LISTS ARGN)
+ set(sync_headers_target "${sync_headers_target}_sync_headers")
+ if(NOT skip_non_existing OR TARGET ${sync_headers_target})
+ list(APPEND ${out_var} ${sync_headers_target})
endif()
endforeach()
- set(${resultVarPrefix}_public "${public_module_headers}" PARENT_SCOPE)
- set(${resultVarPrefix}_private "${private_module_headers}" PARENT_SCOPE)
- set(${resultVarPrefix}_injections "${injections}" PARENT_SCOPE)
-endfunction()
-
-function(qt_compute_injection_forwarding_header target)
- qt_parse_all_arguments(arg "qt_compute_injection_forwarding_header"
- "PRIVATE" "SOURCE;OUT_VAR" "" ${ARGN})
- qt_internal_module_info(module "${target}")
- get_filename_component(file_name "${arg_SOURCE}" NAME)
+ list(REMOVE_DUPLICATES ${out_var})
- set(source_absolute_path "${CMAKE_CURRENT_BINARY_DIR}/${arg_SOURCE}")
- file(RELATIVE_PATH relpath "${PROJECT_BINARY_DIR}" "${source_absolute_path}")
+ set(${out_var} "${${out_var}}" PARENT_SCOPE)
+endfunction()
- if (arg_PRIVATE)
- set(fwd "${PROJECT_VERSION}/${module_include_name}/private/${file_name}")
- else()
- set(fwd "${file_name}")
+function(qt_internal_add_sync_header_dependencies target)
+ qt_internal_collect_sync_header_dependencies(sync_headers_targets FALSE ${ARGN})
+ if(sync_headers_targets)
+ add_dependencies(${target} ${sync_headers_targets})
endif()
+endfunction()
- string(APPEND ${arg_OUT_VAR} " ${relpath}:${fwd}")
- set(${arg_OUT_VAR} ${${arg_OUT_VAR}} PARENT_SCOPE)
+function(qt_internal_add_autogen_sync_header_dependencies target)
+ qt_internal_collect_sync_header_dependencies(sync_headers_targets TRUE ${ARGN})
+ foreach(sync_headers_target IN LISTS sync_headers_targets)
+ set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS
+ "${sync_headers_target}")
+ endforeach()
endfunction()