aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtDeclarativeSetup.cmake10
-rw-r--r--src/qml/Qt6QmlMacros.cmake95
-rw-r--r--src/qml/Qt6QmlResolveMetatypesDependencies.cmake60
-rw-r--r--src/qmltyperegistrar/qmltyperegistrar.cpp35
4 files changed, 150 insertions, 50 deletions
diff --git a/cmake/QtDeclarativeSetup.cmake b/cmake/QtDeclarativeSetup.cmake
index 2cd6f56127..116b6013a0 100644
--- a/cmake/QtDeclarativeSetup.cmake
+++ b/cmake/QtDeclarativeSetup.cmake
@@ -46,3 +46,13 @@ function(qt_declarative_generate_reg_exp_jit_tables consuming_target)
target_sources(${consuming_target} PRIVATE ${output_file})
target_include_directories(${consuming_target} PRIVATE $<BUILD_INTERFACE:${generate_dir}>)
endfunction()
+
+# special case to set the qmltype resolve dependencies script at build time
+set(QT_QMTYPES_RESOLVE_DEPENDENCIES_SCRIPT
+ "${CMAKE_CURRENT_SOURCE_DIR}/src/qml/Qt6QmlResolveMetatypesDependencies.cmake"
+)
+
+# install QmlResolveDependency script
+qt_copy_or_install(FILES "src/qml/Qt6QmlResolveMetatypesDependencies.cmake"
+ DESTINATION "${QT_CONFIG_INSTALL_DIR}/${INSTALL_CMAKE_NAMESPACE}Qml"
+)
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake
index 8b8ec045d3..dfd556375e 100644
--- a/src/qml/Qt6QmlMacros.cmake
+++ b/src/qml/Qt6QmlMacros.cmake
@@ -416,42 +416,33 @@ function(qt6_target_qml_files target)
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})
+ cmake_parse_arguments(args "COPY_OVER_INSTALL" "INSTALL_DIR" "" ${ARGN})
+
+ set(meta_types_args)
+ if (arg_INSTALL_DIR)
+ list(APPEND meta_types_args INSTALL_DIR "${arg_INSTALL_DIR}")
+ endif()
+ if (arg_COPY_OVER_INSTALL)
+ list(APPEND meta_types_args COPY_OVER_INSTALL)
+ endif()
+
+ qt6_generate_meta_types_json_file(${target} ${meta_types_args})
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)
+ get_target_property(target_metatypes_dep_file ${target} INTERFACE_QT_META_TYPES_BUILD_DEP_FILE)
+ get_target_property(target_metatypes_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE)
+ if (NOT target_metatypes_dep_file)
+ message(FATAL_ERROR "Target ${target} does not have a meta types dependency file")
+ endif()
# Extract major and minor version
if (NOT import_version MATCHES "[0-9]+\\.[0-9]+")
@@ -474,28 +465,34 @@ function(qt6_qml_type_registration target)
--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()
+ # Run a script to recursively evaluate all the metatypes.json files in order
+ # to collect all foreign types.
+ set(foreign_types_file "${target_binary_dir}/qmltypes/foreign_types.txt")
+ set(foreign_types_file_tmp "${target_binary_dir}/qmltypes/foreign_types.txt.tmp")
+
+ if (NOT QT_QMTYPES_RESOLVE_DEPENDENCIES_SCRIPT)
+ set("${Qt6Qml_DIR}/Qt6QmlResolveMetatypesDependencies.cmake")
+ endif()
+
+ add_custom_target(${target}_resolve_foreign_types
+ DEPENDS ${target_metatypes_file}
+ COMMAND ${CMAKE_COMMAND}
+ -DOUTPUT_FILE:PATH="${foreign_types_file_tmp}"
+ -DMAIN_DEP_FILE:PATH="${target_metatypes_dep_file}"
+ -DQT_INSTALL_DIR:PATH="${Qt6_DIR}/../../.."
+ -P "${QT_QMTYPES_RESOLVE_DEPENDENCIES_SCRIPT}"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${foreign_types_file_tmp}"
+ "${foreign_types_file}"
+ BYPRODUCTS ${foreign_types_file}
+ COMMAND_EXPAND_LISTS
+ COMMENT "Resolving foreign type dependencies for target ${target}"
+ )
+
+ add_dependencies(${target}_resolve_foreign_types ${target}_autogen)
- list(REMOVE_DUPLICATES foreign_types)
- string(REPLACE ";" "," foreign_types_list "${foreign_types}")
list(APPEND cmd_args
- "--foreign-types=${foreign_types_list}"
+ "@${foreign_types_file}"
)
set(dependencies_json_file "${target_source_dir}/dependencies.json")
@@ -507,7 +504,7 @@ function(qt6_qml_type_registration target)
list(APPEND cmd_args --private-includes)
endif()
- get_target_property(target_metatypes_json_file ${target} QT_MODULE_META_TYPES_FILE)
+ get_target_property(target_metatypes_json_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE)
if (NOT target_metatypes_json_file)
message(FATAL_ERROR "Need target metatypes.json file")
endif()
@@ -516,15 +513,15 @@ function(qt6_qml_type_registration target)
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}
+ DEPENDS ${foreign_types_file} ${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
+ COMMENT "Automatic QML type registration for target ${target}"
)
target_sources(${target} PRIVATE ${type_registration_cpp_file})
diff --git a/src/qml/Qt6QmlResolveMetatypesDependencies.cmake b/src/qml/Qt6QmlResolveMetatypesDependencies.cmake
new file mode 100644
index 0000000000..0626b18a62
--- /dev/null
+++ b/src/qml/Qt6QmlResolveMetatypesDependencies.cmake
@@ -0,0 +1,60 @@
+#
+# Resolve dependencies
+#
+
+if (NOT MAIN_DEP_FILE)
+ message(FATAL_ERROR "MAIN_DEP_FILE file not specified")
+endif()
+
+if (NOT QT_INSTALL_DIR)
+ message(FATAL_ERROR "QT_INSTALL_DIR was not specified")
+endif()
+
+if (NOT OUTPUT_FILE)
+ message(FATAL_ERROR "OUTPUT_FILE not specified")
+endif()
+
+# Read main dep file
+if (NOT EXISTS "${MAIN_DEP_FILE}")
+ message(FATAL_ERROR "${MAIN_DEP_FILE} does not exist")
+endif()
+
+file(STRINGS "${MAIN_DEP_FILE}" remaining)
+set(metatypes_list)
+while(remaining)
+
+ # Pop element off the list
+ list(POP_FRONT remaining current)
+
+ string(REPLACE "=" ";" file_list "${current}")
+ list(GET file_list 0 metatypes_file)
+ list(GET file_list 1 metatypes_dep_file)
+
+ if (NOT IS_ABSOLUTE "${metatypes_file}")
+ set(metatypes_file "${QT_INSTALL_DIR}/${metatypes_file}")
+ set(metatypes_dep_file "${QT_INSTALL_DIR}/${metatypes_dep_file}")
+ endif()
+
+ if (NOT EXISTS "${metatypes_file}")
+ message(FATAL_ERROR "${metatypes_file} does not exist")
+ endif()
+ if (NOT EXISTS "${metatypes_dep_file}")
+ message(FATAL_ERROR "${metatypes_dep_file} does not exist")
+ endif()
+
+ list(APPEND metatypes_list "${metatypes_file}")
+
+ file(STRINGS ${metatypes_dep_file} dep_string)
+ if (dep_string)
+ list(APPEND remaining "${dep_string}")
+ endif()
+endwhile()
+
+list(REMOVE_DUPLICATES metatypes_list)
+list(JOIN metatypes_list "," metatypes)
+
+if (metatypes)
+ file(WRITE ${OUTPUT_FILE} "--foreign-types=${metatypes}\n")
+else()
+ file(WRITE ${OUTPUT_FILE} "\n")
+endif()
diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp
index 49c9fccb66..4738e28314 100644
--- a/src/qmltyperegistrar/qmltyperegistrar.cpp
+++ b/src/qmltyperegistrar/qmltyperegistrar.cpp
@@ -57,6 +57,35 @@ static bool acceptClassForQmlTypeRegistration(const QJsonObject &classDef)
return false;
}
+static bool argumentsFromCommandLineAndFile(QStringList &allArguments, const QStringList &arguments)
+{
+ allArguments.reserve(arguments.size());
+ for (const QString &argument : arguments) {
+ // "@file" doesn't start with a '-' so we can't use QCommandLineParser for it
+ if (argument.startsWith(QLatin1Char('@'))) {
+ QString optionsFile = argument;
+ optionsFile.remove(0, 1);
+ if (optionsFile.isEmpty()) {
+ fprintf(stderr, "The @ option requires an input file");
+ return false;
+ }
+ QFile f(optionsFile);
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ fprintf(stderr, "Cannot open options file specified with @");
+ return false;
+ }
+ while (!f.atEnd()) {
+ QString line = QString::fromLocal8Bit(f.readLine().trimmed());
+ if (!line.isEmpty())
+ allArguments << line;
+ }
+ } else {
+ allArguments << argument;
+ }
+ }
+ return true;
+}
+
static QVector<QJsonObject> foreignRelatedTypes(const QVector<QJsonObject> &types,
const QVector<QJsonObject> &foreignTypes)
{
@@ -229,7 +258,11 @@ int main(int argc, char **argv)
parser.addPositionalArgument(QStringLiteral("[MOC generated json file]"),
QStringLiteral("MOC generated json output."));
- parser.process(app);
+ QStringList arguments;
+ if (!argumentsFromCommandLineAndFile(arguments, app.arguments()))
+ return EXIT_FAILURE;
+
+ parser.process(arguments);
FILE *output = stdout;
QScopedPointer<FILE, ScopedPointerFileCloser> outputFile;