diff options
-rw-r--r-- | src/qml/CMakeLists.txt | 11 | ||||
-rw-r--r-- | src/qml/Qt6QmlImportScannerTemplate.cpp.in (renamed from tools/qmlimportscanner/Qt5QmlImportScannerTemplate.cpp.in) | 2 | ||||
-rw-r--r-- | src/qml/Qt6QmlMacros.cmake | 132 | ||||
-rw-r--r-- | tools/qmlimportscanner/CMakeLists.txt | 45 | ||||
-rw-r--r-- | tools/qmlimportscanner/Qt5QmlImportScannerConfig.cmake.in | 194 | ||||
-rw-r--r-- | tools/qmlimportscanner/Qt6QmlImportScannerConfig.cmake.in | 5 | ||||
-rw-r--r-- | tools/qmlimportscanner/qmlimportscanner.pro | 19 |
7 files changed, 203 insertions, 205 deletions
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt index 461b2b8d7c..65f59e0247 100644 --- a/src/qml/CMakeLists.txt +++ b/src/qml/CMakeLists.txt @@ -658,3 +658,14 @@ set_target_properties(Qml PROPERTIES qt6_qml_type_registration(Qml) include(Qt6QmlBuildInternals.cmake) # special case + +# special case begin +# Install Qml import scanner template cpp file. +set(target "Qml") +set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}") +qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix}) +qt_copy_or_install(FILES + "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}ImportScannerTemplate.cpp.in" + DESTINATION "${config_install_dir}" +) +# special case end diff --git a/tools/qmlimportscanner/Qt5QmlImportScannerTemplate.cpp.in b/src/qml/Qt6QmlImportScannerTemplate.cpp.in index 4ed747a555..715dd87cb2 100644 --- a/tools/qmlimportscanner/Qt5QmlImportScannerTemplate.cpp.in +++ b/src/qml/Qt6QmlImportScannerTemplate.cpp.in @@ -2,4 +2,4 @@ // static plugins used by QML imports. #include <QtPlugin> -@qt5_qml_import_cpp_file_content@ +@qt_qml_import_cpp_file_content@ diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index 24a5eb533b..bf59fba446 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -429,7 +429,8 @@ function(qt6_target_qml_files target) math(EXPR new_count "${resource_count} + 1") set_target_properties(${target} PROPERTIES QT6_QML_MODULE_ADD_QML_FILES_COUNT ${new_count}) - qt6_add_resources(${target} "qml_files${new_count}" + # TODO: Fix this if it blows up on Windows due to too long target name. + qt6_add_resources(${target} "${target}_qml_files_resource_${new_count}" FILES ${arg_FILES} OUTPUT_TARGETS resource_targets ) @@ -833,3 +834,132 @@ function(qt6_quick_compiler_process_resources target resource_name) set(${arg_OUTPUT_REMAINING_RESOURCES} ${resource_files} PARENT_SCOPE) set(${arg_OUTPUT_RESOURCE_NAME} ${resource_name} PARENT_SCOPE) endfunction() + +include(CMakeParseArguments) + +function(qt6_import_qml_plugins target) + if(${QT_CMAKE_EXPORT_NAMESPACE}_IS_SHARED_LIBS_BUILD) + return() + endif() + set(options) + set(oneValueArgs "PATH_TO_SCAN") + set(multiValueArgs) + + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT arg_PATH_TO_SCAN) + set(arg_PATH_TO_SCAN "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + # Find location of qmlimportscanner. + get_target_property(tool_path ${QT_CMAKE_EXPORT_NAMESPACE}::qmlimportscanner IMPORTED_LOCATION) + if(NOT tool_path) + set(configs "RELWITHDEBINFO;RELEASE;MINSIZEREL;DEBUG") + foreach(config ${configs}) + get_target_property(tool_path Qt6::qmlimportscanner IMPORTED_LOCATION_${config}) + if(tool_path) + break() + endif() + endforeach() + endif() + + if(NOT EXISTS "${tool_path}") + message(FATAL_ERROR "The package \"QmlImportScanner\" references the file + \"${tool_path}\" +but this file does not exist. Possible reasons include: +* The file was deleted, renamed, or moved to another location. +* An install or uninstall procedure did not complete successfully. +* The installation package was faulty. +") + endif() + + # Find location of qml dir. + # TODO: qt.prf implies that there might be more than one qml import path to pass to + # qmlimportscanner. + set(qml_path "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}") + + # Small macro to avoid duplicating code in two different loops. + macro(_qt6_QmlImportScanner_parse_entry) + set(entry_name "qml_import_scanner_import_${idx}") + cmake_parse_arguments("entry" + "" + "CLASSNAME;NAME;PATH;PLUGIN;RELATIVEPATH;TYPE;VERSION;" "" + ${${entry_name}}) + endmacro() + + # Run qmlimportscanner and include the generated cmake file. + set(qml_imports_file_path + "${CMAKE_CURRENT_BINARY_DIR}/Qt6_QmlPlugins_Imports_${target}.cmake") + + # TODO: QTBUG-85994 Figure out how to handle resources like in fix for QTBUG-82873. + message(STATUS "Running qmlimportscanner to find used QML plugins. ") + execute_process(COMMAND + "${tool_path}" "${arg_PATH_TO_SCAN}" -importPath "${qml_path}" + -cmake-output + OUTPUT_FILE "${qml_imports_file_path}") + + include("${qml_imports_file_path}" OPTIONAL RESULT_VARIABLE qml_imports_file_path_found) + if(NOT qml_imports_file_path_found) + message(FATAL_ERROR "Could not find ${qml_imports_file_path} which was supposed to be generated by qmlimportscanner.") + endif() + + # Parse the generated cmake file. + # It is possible for the scanner to find no usage of QML, in which case the import count is 0. + if(qml_import_scanner_imports_count) + set(added_plugins "") + foreach(idx RANGE "${qml_import_scanner_imports_count}") + _qt6_QmlImportScanner_parse_entry() + if(entry_PATH AND entry_PLUGIN) + # Sometimes a plugin appears multiple times with different versions. + # Make sure to process it only once. + list(FIND added_plugins "${entry_PLUGIN}" _index) + if(NOT _index EQUAL -1) + continue() + endif() + list(APPEND added_plugins "${entry_PLUGIN}") + + # Link against the Qml plugin. The assumption is that all Qml plugins are already + # find_package()'d by the Qml package, so we can safely link against the target. + target_link_libraries("${target}" PRIVATE + "${QT_CMAKE_EXPORT_NAMESPACE}::${entry_PLUGIN}") + endif() + endforeach() + + # Generate content for plugin initialization cpp file. + set(added_imports "") + set(qt_qml_import_cpp_file_content "") + foreach(idx RANGE "${qml_import_scanner_imports_count}") + _qt6_QmlImportScanner_parse_entry() + if(entry_PLUGIN) + if(entry_CLASSNAME) + list(FIND added_imports "${entry_PLUGIN}" _index) + if(_index EQUAL -1) + string(APPEND qt_qml_import_cpp_file_content + "Q_IMPORT_PLUGIN(${entry_CLASSNAME})\n") + list(APPEND added_imports "${entry_PLUGIN}") + endif() + else() + message(FATAL_ERROR + "Plugin ${entry_PLUGIN} is missing a classname entry, please add one to the qmldir file.") + endif() + endif() + endforeach() + + # Write to the generated file, and include it as a source for the given target. + set(generated_import_cpp_path + "${CMAKE_CURRENT_BINARY_DIR}/Qt6_QmlPlugins_Imports_${target}.cpp") + configure_file("${Qt6Qml_DIR}/Qt6QmlImportScannerTemplate.cpp.in" + "${generated_import_cpp_path}" + @ONLY) + target_sources(${target} PRIVATE "${generated_import_cpp_path}") + endif() +endfunction() + +if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) + function(qt_import_qml_plugins) + if(QT_DEFAULT_MAJOR_VERSION EQUAL 5) + qt5_import_qml_plugins(${ARGV}) + elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6) + qt6_import_qml_plugins(${ARGV}) + endif() + endfunction() +endif() diff --git a/tools/qmlimportscanner/CMakeLists.txt b/tools/qmlimportscanner/CMakeLists.txt index dfe24cfc26..eaf5a9f3cb 100644 --- a/tools/qmlimportscanner/CMakeLists.txt +++ b/tools/qmlimportscanner/CMakeLists.txt @@ -20,6 +20,51 @@ qt_add_tool(${target_name} Qt::QmlDevToolsPrivate ) +# special case begin +# Create a dummy package that will just find Qml package, for backwards compatibility reasons. +set(target "QmlImportScanner") +set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}") +qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix}) +qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix}) + +# Configure and install Config and version file. +configure_package_config_file( + "${CMAKE_CURRENT_LIST_DIR}/Qt6QmlImportScannerConfig.cmake.in" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" + INSTALL_DESTINATION "${config_install_dir}" +) + +write_basic_package_version_file( + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) +qt_install(FILES + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + DESTINATION "${config_install_dir}" + COMPONENT Devel +) + +# Configure and install ModuleDependencies file. +set(third_party_deps "") +set(main_module_tool_deps "") +set(target_deps "${INSTALL_CMAKE_NAMESPACE}Qml\;${PROJECT_VERSION}") +set(qt_module_dependencies "Qml") +configure_file( + "${QT_CMAKE_DIR}/QtModuleDependencies.cmake.in" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake" + @ONLY +) + +qt_install(FILES + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake" + DESTINATION "${config_install_dir}" + COMPONENT Devel +) + +# special case end + #### Keys ignored in scope 1:.:.:qmlimportscanner.pro:<TRUE>: # CMAKE_BIN_DIR = "$$cmakeRelativePath($$[QT_HOST_BINS], $$[QT_INSTALL_PREFIX])" # CMAKE_DEBUG_TYPE = <EMPTY> diff --git a/tools/qmlimportscanner/Qt5QmlImportScannerConfig.cmake.in b/tools/qmlimportscanner/Qt5QmlImportScannerConfig.cmake.in deleted file mode 100644 index f92b8d295d..0000000000 --- a/tools/qmlimportscanner/Qt5QmlImportScannerConfig.cmake.in +++ /dev/null @@ -1,194 +0,0 @@ -include(CMakeParseArguments) - -function(QT5_IMPORT_QML_PLUGINS target) -!!IF !isEmpty(CMAKE_STATIC_TYPE) - set(options) - set(oneValueArgs \"PATH_TO_SCAN\") - set(multiValueArgs) - - cmake_parse_arguments(arg \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN}) - if(NOT arg_PATH_TO_SCAN) - set(arg_PATH_TO_SCAN \"${CMAKE_CURRENT_SOURCE_DIR}\") - endif() - - # Find location of qmlimportscanner. - find_package(Qt5 COMPONENTS Core) -!!IF isEmpty(CMAKE_BIN_DIR_IS_ABSOLUTE) - set(tool_path - \"${_qt5Core_install_prefix}/$${CMAKE_BIN_DIR}qmlimportscanner$$CMAKE_BIN_SUFFIX\") -!!ELSE - set(tool_path \"$${CMAKE_BIN_DIR}qmlimportscanner$$CMAKE_BIN_SUFFIX\") -!!ENDIF - if(NOT EXISTS \"${tool_path}\" ) - message(FATAL_ERROR \"The package \\\"Qt5QmlImportScannerConfig\\\" references the file - \\\"${tool_path}\\\" -but this file does not exist. Possible reasons include: -* The file was deleted, renamed, or moved to another location. -* An install or uninstall procedure did not complete successfully. -* The installation package was faulty. -\") - endif() - - # Find location of qml dir. -!!IF isEmpty(CMAKE_QML_DIR_IS_ABSOLUTE) - set(qml_path \"${_qt5Core_install_prefix}/$${CMAKE_QML_DIR}\") -!!ELSE - set(qml_path \"$${CMAKE_QML_DIR}\") -!!ENDIF - - # Small macro to avoid duplicating code in two different loops. - macro(_qt5_QmlImportScanner_parse_entry) - set(entry_name \"qml_import_scanner_import_${idx}\") - cmake_parse_arguments(\"entry\" - \"\" - \"CLASSNAME;NAME;PATH;PLUGIN;RELATIVEPATH;TYPE;VERSION;\" \"\" - ${${entry_name}}) - endmacro() - - # Macro used to populate the dependency link flags for a certain configuriation (debug vs - # release) of a plugin. - macro(_qt5_link_to_QmlImportScanner_library_dependencies Plugin Configuration PluginLocation - IsDebugAndRelease) - - set_property(TARGET \"${Plugin}\" APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) - set(_imported_location \"${PluginLocation}\") - _qt5_Core_check_file_exists(\"${_imported_location}\") - set_target_properties(\"${Plugin}\" PROPERTIES - \"IMPORTED_LOCATION_${Configuration}\" \"${_imported_location}\" - ) - - set(_static_deps - ${_Qt5${entry_PLUGIN}_STATIC_${Configuration}_LIB_DEPENDENCIES} - ) - - if(NOT "${IsDebugAndRelease}") - set(_genex_condition \"1\") - else() - if("${Configuration}" STREQUAL "DEBUG") - set(_genex_condition \"$<CONFIG:Debug>\") - else() - set(_genex_condition \"$<NOT:$<CONFIG:Debug>>\") - endif() - endif() - if(_static_deps) - set(_static_deps_genex \"$<${_genex_condition}:${_static_deps}>\") - target_link_libraries(${imported_target} INTERFACE \"${_static_deps_genex}\") - endif() - - set(_static_link_flags \"${_Qt5${entry_PLUGIN}_STATIC_${Configuration}_LINK_FLAGS}\") - if(NOT CMAKE_VERSION VERSION_LESS \"3.13\" AND _static_link_flags) - set(_static_link_flags_genex \"$<${_genex_condition}:${_static_link_flags}>\") - target_link_options(${imported_target} INTERFACE \"${_static_link_flags_genex}\") - endif() - endmacro() - - # Run qmlimportscanner and include the generated cmake file. - set(qml_imports_file_path - \"${CMAKE_CURRENT_BINARY_DIR}/Qt5_QmlPlugins_Imports_${target}.cmake\") - - message(STATUS \"Running qmlimportscanner to find used QML plugins. \") - execute_process(COMMAND - \"${tool_path}\" \"${arg_PATH_TO_SCAN}\" -importPath \"${qml_path}\" - -cmake-output - OUTPUT_FILE \"${qml_imports_file_path}\") - - include(\"${qml_imports_file_path}\" OPTIONAL RESULT_VARIABLE qml_imports_file_path_found) - if(NOT qml_imports_file_path_found) - message(FATAL_ERROR \"Could not find ${qml_imports_file_path} which was supposed to be generated by qmlimportscanner.\") - endif() - - # Parse the generate cmake file. - # It is possible for the scanner to find no usage of QML, in which case the import count is 0. - if(qml_import_scanner_imports_count) - set(added_plugins \"\") - foreach(idx RANGE \"${qml_import_scanner_imports_count}\") - _qt5_QmlImportScanner_parse_entry() - if(entry_PATH AND entry_PLUGIN) - # Sometimes a plugin appears multiple times with different versions. - # Make sure to process it only once. - list(FIND added_plugins \"${entry_PLUGIN}\" _index) - if(NOT _index EQUAL -1) - continue() - endif() - list(APPEND added_plugins \"${entry_PLUGIN}\") - - # Add an imported target that will contain the link libraries and link options read - # from one plugin prl file. This target will point to the actual plugin and contain - # static dependency libraries and link flags. - # By creating a target for each qml plugin, CMake will take care of link flag - # deduplication. - set(imported_target \"${target}_QmlImport_${entry_PLUGIN}\") - add_library(\"${imported_target}\" MODULE IMPORTED) - target_link_libraries(\"${target}\" PRIVATE \"${imported_target}\") - - # Read static library dependencies from the plugin .prl file. - # And then set the link flags to the library dependencies extracted from the .prl - # file. -!!IF !isEmpty(CMAKE_RELEASE_TYPE) - _qt5_Core_process_prl_file( - \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_RELEASE}.prl\" RELEASE - _Qt5${entry_PLUGIN}_STATIC_RELEASE_LIB_DEPENDENCIES - _Qt5${entry_PLUGIN}_STATIC_RELEASE_LINK_FLAGS - ) - _qt5_link_to_QmlImportScanner_library_dependencies( - \"${imported_target}\" - RELEASE - \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_RELEASE}.$$QMAKE_EXTENSION_STATICLIB\" - $${CMAKE_DEBUG_AND_RELEASE}) -!!ENDIF - -!!IF !isEmpty(CMAKE_DEBUG_TYPE) - _qt5_Core_process_prl_file( - \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_DEBUG}.prl\" DEBUG - _Qt5${entry_PLUGIN}_STATIC_DEBUG_LIB_DEPENDENCIES - _Qt5${entry_PLUGIN}_STATIC_DEBUG_LINK_FLAGS - ) - _qt5_link_to_QmlImportScanner_library_dependencies( - \"${imported_target}\" - DEBUG - \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_DEBUG}.$$QMAKE_EXTENSION_STATICLIB\" - $${CMAKE_DEBUG_AND_RELEASE}) -!!ENDIF - endif() - endforeach() - - # Generate content for plugin initialization cpp file. - set(added_imports \"\") - set(qt5_qml_import_cpp_file_content \"\") - foreach(idx RANGE \"${qml_import_scanner_imports_count}\") - _qt5_QmlImportScanner_parse_entry() - if(entry_PLUGIN) - if(entry_CLASSNAME) - list(FIND added_imports \"${entry_PLUGIN}\" _index) - if(_index EQUAL -1) - string(APPEND qt5_qml_import_cpp_file_content - \"Q_IMPORT_PLUGIN(${entry_CLASSNAME})\n\") - list(APPEND added_imports \"${entry_PLUGIN}\") - endif() - else() - message(FATAL_ERROR - \"Plugin ${entry_PLUGIN} is missing a classname entry, please add one to the qmldir file.\") - endif() - endif() - endforeach() - - # Write to the generated file, and include it as a source for the given target. - set(generated_import_cpp_path - \"${CMAKE_CURRENT_BINARY_DIR}/Qt5_QmlPlugins_Imports_${target}.cpp\") - configure_file(\"${Qt5QmlImportScanner_DIR}/Qt5QmlImportScannerTemplate.cpp.in\" - \"${generated_import_cpp_path}\" - @ONLY) - target_sources(${target} PRIVATE \"${generated_import_cpp_path}\") - endif() -!!ENDIF // !isEmpty(CMAKE_STATIC_TYPE) -endfunction() - -if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) - function(qt_import_qml_plugins) - if(QT_DEFAULT_MAJOR_VERSION EQUAL 5) - qt5_import_qml_plugins(${ARGV}) - elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6) - qt6_import_qml_plugins(${ARGV}) - endif() - endfunction() -endif() diff --git a/tools/qmlimportscanner/Qt6QmlImportScannerConfig.cmake.in b/tools/qmlimportscanner/Qt6QmlImportScannerConfig.cmake.in new file mode 100644 index 0000000000..0383b547ad --- /dev/null +++ b/tools/qmlimportscanner/Qt6QmlImportScannerConfig.cmake.in @@ -0,0 +1,5 @@ +# The functionality that was provided in the Qt5 package was moved to the Qml package. +# Defers to that package and it macros. +include(CMakeFindDependencyMacro) +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake") +set("@INSTALL_CMAKE_NAMESPACE@@target@_FOUND" TRUE) diff --git a/tools/qmlimportscanner/qmlimportscanner.pro b/tools/qmlimportscanner/qmlimportscanner.pro index 9fd2a38956..0d2dc22ea2 100644 --- a/tools/qmlimportscanner/qmlimportscanner.pro +++ b/tools/qmlimportscanner/qmlimportscanner.pro @@ -47,15 +47,16 @@ qtConfig(debug_and_release) { CMAKE_DEBUG_AND_RELEASE = FALSE } -equals(QMAKE_HOST.os, Windows): CMAKE_BIN_SUFFIX = ".exe" -cmake_config_file.input = $$PWD/Qt5QmlImportScannerConfig.cmake.in -cmake_config_file.output = $$MODULE_BASE_OUTDIR/lib/cmake/Qt5QmlImportScanner/Qt5QmlImportScannerConfig.cmake -QMAKE_SUBSTITUTES += cmake_config_file - -cmake_build_integration.files = $$cmake_config_file.output $$PWD/Qt5QmlImportScannerTemplate.cpp.in -cmake_build_integration.path = $$[QT_INSTALL_LIBS]/cmake/Qt5QmlImportScanner -prefix_build: INSTALLS += cmake_build_integration -else: COPIES += cmake_build_integration +# The qml import scanner CMake files are now only created by the Qt 6 CMake build. +#equals(QMAKE_HOST.os, Windows): CMAKE_BIN_SUFFIX = ".exe" +#cmake_config_file.input = $$PWD/Qt5QmlImportScannerConfig.cmake.in +#cmake_config_file.output = $$MODULE_BASE_OUTDIR/lib/cmake/Qt5QmlImportScanner/Qt5QmlImportScannerConfig.cmake +#QMAKE_SUBSTITUTES += cmake_config_file + +#cmake_build_integration.files = $$cmake_config_file.output $$PWD/Qt5QmlImportScannerTemplate.cpp.in +#cmake_build_integration.path = $$[QT_INSTALL_LIBS]/cmake/Qt5QmlImportScanner +#prefix_build: INSTALLS += cmake_build_integration +#else: COPIES += cmake_build_integration QMAKE_TARGET_DESCRIPTION = QML Import Scanner |