From b743323602babb9580149ca2b881ce4bc85e0584 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Tue, 17 Nov 2020 18:46:49 +0100 Subject: CMake: Replace 'file' with 'configure_file' in 'qmldir' generation Collect content of 'qmldir' file that is generated by 'qt6_add_qml_module' and 'qt6_target_qml_files' functions, instead of write content to file immediately. Use 'cmake_language(DEFER CALL)' to call 'configure_file' write whole 'qmldir', when finalizing CMAKE_CURRENT_SOURCE_DIR scope. This way a reconfiguration will not rewrite the files, touch the timestamps, and thus needlessly rebuild. Task-number: QTBUG-88172 Change-Id: Idca68e4ceed13d0aa7eac443e769d5677557b880 Reviewed-by: Alexandru Croitor --- src/qml/CMakeLists.txt | 2 ++ src/qml/Qt6QmlMacros.cmake | 43 +++++++++++++++++++++++++++++++++++--- src/qml/Qt6qmldirTemplate.cmake.in | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/qml/Qt6qmldirTemplate.cmake.in (limited to 'src') diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt index 596a8fdfc0..8e977687cc 100644 --- a/src/qml/CMakeLists.txt +++ b/src/qml/CMakeLists.txt @@ -355,6 +355,8 @@ qt_internal_add_module(Qml Qt::Core PRIVATE_MODULE_INTERFACE Qt::CorePrivate + EXTRA_CMAKE_FILES + "${CMAKE_CURRENT_SOURCE_DIR}/Qt6qmldirTemplate.cmake.in" ) # special case begin remove the block, handled manually diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index e8a440c5b5..dcdff7ca0f 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -362,7 +362,7 @@ function(qt6_add_qml_module target) endif() endforeach() - file(WRITE ${qmldir_file} ${qmldir_file_contents}) + _qt_internal_qmldir_defer_file(WRITE "${qmldir_file}" "${qmldir_file_contents}") # Process qml files if (arg_QML_FILES) @@ -419,7 +419,9 @@ function(qt6_add_qml_module target) set_target_properties(${target} PROPERTIES QT_QML_MODULE_PLUGIN_TYPES_FILE "${target_plugin_qmltypes}" ) - file(APPEND ${qmldir_file} "typeinfo plugins.qmltypes\n") + + _qt_internal_qmldir_defer_file(APPEND "${qmldir_file}" "typeinfo plugins.qmltypes\n") + if (NOT arg_DO_NOT_INSTALL_METADATA AND should_install) install(FILES "${target_plugin_qmltypes}" DESTINATION "${arg_INSTALL_LOCATION}" @@ -639,7 +641,7 @@ function(qt6_target_qml_files target) endif() endforeach() - file(APPEND ${qmldir_file} ${file_contents}) + _qt_internal_qmldir_defer_file(APPEND "${qmldir_file}" "${file_contents}") endfunction() if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) @@ -1141,3 +1143,38 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) endif() endfunction() endif() + +# Wrapper around configure_file. Passes content collected in $directory-scoped property. +function(_qt_internal_configure_qmldir directory) + get_property(__qt_qmldir_content DIRECTORY "${directory}" PROPERTY _qt_internal_qmldir_content) + configure_file(${ARGN} @ONLY) +endfunction() + +# Collects content for target $filepath and use deferred call of 'configure_file' to avoid +# rebuilding of targets that depend on provided qmldir. +# Note: For cmake versions < 3.19.0 plain 'file' function call will be used. +function(_qt_internal_qmldir_defer_file command filepath content) + if(${CMAKE_VERSION} VERSION_LESS "3.19.0") + file(${ARGV}) + else() + if("${command}" STREQUAL "WRITE") + # Wrap with EVAL CODE to evaluate and expand arguments + cmake_language(EVAL CODE + "cmake_language(DEFER DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\" CALL + \"_qt_internal_configure_qmldir\" + \"${CMAKE_CURRENT_SOURCE_DIR}\" + \"${__qt_qml_macros_module_base_dir}/Qt6qmldirTemplate.cmake.in\" + \"${filepath}\")") + set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + PROPERTY _qt_internal_qmldir_content "${content}") + elseif("${command}" STREQUAL "APPEND") + set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + APPEND_STRING + PROPERTY _qt_internal_qmldir_content "${content}") + else() + message(FATAL_ERROR "Unknown command ${command}. \ + _qt_internal_qmldir_defer_file only accepts \ + WRITE and APPEND commands.") + endif() + endif() +endfunction() diff --git a/src/qml/Qt6qmldirTemplate.cmake.in b/src/qml/Qt6qmldirTemplate.cmake.in new file mode 100644 index 0000000000..7155d2fec2 --- /dev/null +++ b/src/qml/Qt6qmldirTemplate.cmake.in @@ -0,0 +1 @@ +@__qt_qmldir_content@ -- cgit v1.2.3