diff options
author | Leander Beernaert <leander.beernaert@qt.io> | 2019-12-04 14:14:44 +0100 |
---|---|---|
committer | Leander Beernaert <leander.beernaert@qt.io> | 2020-01-24 12:30:10 +0000 |
commit | a58a246657442846150c31ebcfdc75148b7c6ee7 (patch) | |
tree | 8f9e4093dd330de2d28203d9d66e14091bc7090a | |
parent | 7c229d3cf80d66c0261f7e63ac9b918e2cea4e57 (diff) |
Support for QML Types Registrar
Change-Id: Iff5da66ae179601fbfd369b9bc31005554df5873
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r-- | src/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/qml/Qt6QmlMacros.cmake | 134 | ||||
-rw-r--r-- | src/qmltyperegistrar/CMakeLists.txt | 39 |
3 files changed, 179 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e05abad20..fae670d4ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,11 @@ # Generated from src.pro. # special case skip regeneration + +if (NOT QT_FEATURE_commandlineparser) + message(FATAL_ERROR "QT_FEATURE_commandlineparser required to compile qmltyperegistrar") +endif() + +add_subdirectory(qmltyperegistrar) add_subdirectory(qml) add_subdirectory(qmlmodels) diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index 71e6b2230c..8b8ec045d3 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -72,6 +72,7 @@ function(qt6_add_qml_module target) set(args_optional + GENERATE_QMLTYPES DESIGNER_SUPPORTED DO_NOT_INSTALL_METADATA SKIP_TYPE_REGISTRATION @@ -310,6 +311,11 @@ function(qt6_add_qml_module target) ${target_output_dir} ) endif() + + # Generate meta types data + if (arg_GENERATE_QMLTYPES) + qt6_qml_type_registration(${target}) + endif() endfunction() @@ -409,3 +415,131 @@ function(qt6_target_qml_files target) endforeach() file(APPEND ${qmldir_file} ${file_contents}) endfunction() + +function(__qt6_extract_dependencies target out_list) + set(dep_list) + get_target_property(link_dependencies ${target} INTERFACE_LINK_LIBRARIES) + foreach(dep IN LISTS link_dependencies) + string(FIND ${dep} "Qt::" qt_loc) + if (NOT ${qt_loc} EQUAL -1) + + if (NOT ${qt_loc} EQUAL 0) + # probably stuck in a generator expression + string(SUBSTRING "${dep}" ${qt_loc} -1 dep_fixed) + string(FIND ${dep_fixed} ">" qt_loc) + if (${qt_loc} EQUAL -1) + message(FATAL_ERROR "Expected generator expression for ${target}' depdency ${dep}") + endif() + string(SUBSTRING ${dep_fixed} 0 ${qt_loc} dep) + endif() + + list(APPEND dep_list ${dep}) + __qt6_extract_dependencies(${dep} recurse_list) + list(APPEND dep_list ${recurse_list}) + endif() + endforeach() + set(${out_list} ${dep_list} PARENT_SCOPE) +endfunction() + +function(qt6_qml_type_registration target) + get_target_property(import_name ${target} QT_QML_MODULE_URI) + if (NOT import_name) + message(FATAL_ERROR "Target ${target} is not a QML module") + endif() + + qt6_generate_meta_types_json_file(${target}) + + get_target_property(import_version ${target} QT_QML_MODULE_VERSION) + get_target_property(target_source_dir ${target} SOURCE_DIR) + get_target_property(target_binary_dir ${target} BINARY_DIR) + + # Extract major and minor version + if (NOT import_version MATCHES "[0-9]+\\.[0-9]+") + message(FATAL_ERROR "Invalid module dependency version number. Expected VersionMajor.VersionMinor.") + endif() + string(FIND "${import_version}" "." dot_location) + string(SUBSTRING ${import_version} 0 ${dot_location} major_version) + math(EXPR dot_location "${dot_location}+1") + string(SUBSTRING ${import_version} ${dot_location} -1 minor_version) + + set(cmd_args) + set(plugin_types_file ${target_binary_dir}/plugin.types) + set_target_properties(${target} PROPERTIES + QT_QML_MODULE_PLUGIN_TYPES_FILE ${plugin_types_file} + ) + list(APPEND cmd_args + --generate-qmltypes=${plugin_types_file} + --import-name=${import_name} + --major-version=${major_version} + --minor-version=${minor_version} + ) + + # Extra metatypes.json + set(foreign_types) + set(link_dependencies) + __qt6_extract_dependencies(${target} link_dependencies) + list(REMOVE_DUPLICATES link_dependencies) + foreach(dep IN LISTS link_dependencies) + string(SUBSTRING ${dep} 4 -1 module_name) + string(TOLOWER "qt6${module_name}_${CMAKE_BUILD_TYPE}_metatypes.json" metatypes_file) + + set(module_metatypes_file "${CMAKE_BINARY_DIR}/lib/metatypes/${metatypes_file}") + set(installed_metatypes_file "${Qt6_DIR}/../../metatypes/${metatypes_file}") + if (EXISTS ${module_metatypes_file}) + list(APPEND foreign_types ${module_metatypes_file}) + elseif (EXISTS ${installed_metatypes_file}) + list(APPEND foreign_types ${installed_metatypes_file}) + endif() + endforeach() + + list(REMOVE_DUPLICATES foreign_types) + string(REPLACE ";" "," foreign_types_list "${foreign_types}") + list(APPEND cmd_args + "--foreign-types=${foreign_types_list}" + ) + + set(dependencies_json_file "${target_source_dir}/dependencies.json") + if (EXISTS ${dependencies_json_file}) + list(APPEND cmd_args --dependencies=${dependencies_json_file}) + endif() + + if (TARGET ${target}Private) + list(APPEND cmd_args --private-includes) + endif() + + get_target_property(target_metatypes_json_file ${target} QT_MODULE_META_TYPES_FILE) + if (NOT target_metatypes_json_file) + message(FATAL_ERROR "Need target metatypes.json file") + endif() + string(TOLOWER "${target}_qmltyperegistrations.cpp" type_registration_cpp_file) + + set(type_registration_cpp_file "${target_binary_dir}/${type_registration_cpp_file}") + + add_custom_command(OUTPUT ${type_registration_cpp_file} + DEPENDS ${foreign_types} ${target_metatypes_json_file} + COMMAND + ${CMAKE_COMMAND} -E env PATH=${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR} + $<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmltyperegistrar> + ${cmd_args} + -o ${type_registration_cpp_file} + ${target_metatypes_json_file} + COMMENT "Automatic QML type registration for target ${target}" + COMMAND_EXPAND_LISTS + ) + + target_sources(${target} PRIVATE ${type_registration_cpp_file}) + set_source_files_properties(${type_registration_cpp_file} PROPERTIES + SKIP_AUTOGEN ON + ) + + # Only install qml types if necessary + get_target_property(install_qmltypes ${target} QT_QML_MODULE_INSTALL_QMLTYPES) + if (install_qmltypes) + get_target_property(qml_install_dir ${target} QT_QML_MODULE_INSTALL_DIR) + install(FILES ${plugin_types_file} DESTINATION ${qml_install_dir}) + endif() + + target_include_directories(${target} PRIVATE + $<TARGET_PROPERTY:Qt::QmlPrivate,INTERFACE_INCLUDE_DIRECTORIES> + ) +endfunction() diff --git a/src/qmltyperegistrar/CMakeLists.txt b/src/qmltyperegistrar/CMakeLists.txt new file mode 100644 index 0000000000..b9683257bc --- /dev/null +++ b/src/qmltyperegistrar/CMakeLists.txt @@ -0,0 +1,39 @@ +# Generated from qmltyperegistrar.pro. + +##################################################################### +## qmltyperegistrar Tool: +##################################################################### + +qt_add_tool(qmltyperegistrar + SOURCES + ../../tools/shared/qmlstreamwriter.cpp ../../tools/shared/qmlstreamwriter.h + ../../tools/shared/resourcefilemapper.cpp ../../tools/shared/resourcefilemapper.h + qmltyperegistrar.cpp + qmltypesclassdescription.cpp qmltypesclassdescription.h + qmltypescreator.cpp qmltypescreator.h + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + INCLUDE_DIRECTORIES + ../../tools/shared + LIBRARIES + Qt::CorePrivate +) + +#### Keys ignored in scope 1:.:.:qmltyperegistrar.pro:<TRUE>: +# QMAKE_TARGET_DESCRIPTION = "QML" "Types" "Registrar" +# _OPTION = "host_build" +# build_integration.files = "qmltypes.prf" +# build_integration.path = "$$[QT_HOST_DATA]/mkspecs/features" + +## Scopes: +##################################################################### + +#### Keys ignored in scope 2:.:.:qmltyperegistrar.pro:prefix_build: +# COPIES = "qmltypes_to_builddir" +# INSTALLS = "build_integration" +# qmltypes_to_builddir.files = "qmltypes.prf" +# qmltypes_to_builddir.path = "$$MODULE_BASE_OUTDIR/mkspecs/features" + +#### Keys ignored in scope 3:.:.:qmltyperegistrar.pro:else: +# COPIES = "build_integration" |