diff options
Diffstat (limited to 'src/qml/Qt6QmlMacros.cmake')
-rw-r--r-- | src/qml/Qt6QmlMacros.cmake | 132 |
1 files changed, 131 insertions, 1 deletions
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() |