diff options
author | Olivier De Cannière <[email protected]> | 2024-10-30 13:40:55 +0100 |
---|---|---|
committer | Olivier De Cannière <[email protected]> | 2024-11-04 15:21:09 +0100 |
commit | 318ac440653a570d2bd18fc3d25e1b2fc8af88fa (patch) | |
tree | b20109a0333f44538565c69a4d69cd0683495133 | |
parent | 09f51978f4ab03f9dcaa36aba4f0c861f59b890c (diff) |
aotstats: Support --only-bytecode and modules with no qml files
It is possible to pass --only-bytecode to qmlcachegen. As the name
implies, this only generates the bytecode for the qml files and does not
compile them. This case was not taken into account which could lead to
files commands depend upon not being generated.
Therefore, keep track of empty and only-bytecode modules in files
generated by cmake and pass them to qmlaotstats upon aggregation such
that it can include that information in the report.
Also, only pass the arguments specific to aotstats to qmlcachegen if
--only-bytecode is not set for that module.
Fixes: QTBUG-130084
Task-number: QTBUG-124667
Pick-to: 6.8
Change-Id: I44b4a80e8a6fd2f9bc16ae1bb2c8d540ff3b697b
Reviewed-by: Sami Shalayel <[email protected]>
-rw-r--r-- | src/qml/Qt6QmlMacros.cmake | 44 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljscompilerstats.cpp | 6 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljscompilerstats_p.h | 1 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljscompilerstatsreporter.cpp | 12 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljscompilerstatsreporter_p.h | 5 | ||||
-rw-r--r-- | tools/qmlaotstats/main.cpp | 17 | ||||
-rw-r--r-- | tools/qmlcachegen/qmlcachegen.cpp | 5 |
7 files changed, 78 insertions, 12 deletions
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index 23572bb3e8..f6fcb6345b 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -1092,6 +1092,8 @@ endfunction() function(_qt_internal_deferred_aotstats_setup) get_property(module_targets GLOBAL PROPERTY _qt_qml_aotstats_module_targets) + set(onlybytecode_modules "") + set(empty_modules "") set(module_aotstats_targets "") set(module_aotstats_files "") @@ -1102,6 +1104,14 @@ function(_qt_internal_deferred_aotstats_setup) get_target_property(aotstats_files ${module_target} QT_QML_MODULE_AOTSTATS_FILES) get_target_property(rcc_qmlcache_path ${module_target} QT_QML_MODULE_RCC_QMLCACHE_PATH) + if("--only-bytecode" IN_LIST qmlcachegen_args) + list(APPEND onlybytecode_modules "${uri}(${module_target})") + continue() + elseif(NOT aotstats_files) + list(APPEND empty_modules "${uri}(${module_target})") + continue() + endif() + list(JOIN aotstats_files "\n" aotstats_files_lines) set(module_aotstats_list_file "${rcc_qmlcache_path}/module_${module_target}.aotstatslist") file(WRITE ${module_aotstats_list_file} "${aotstats_files_lines}") @@ -1134,12 +1144,28 @@ function(_qt_internal_deferred_aotstats_setup) endforeach() + set(project_rcc_qmlcache "${PROJECT_BINARY_DIR}/.rcc/qmlcache") + + set(qmlaotstats_options "") + if(onlybytecode_modules) + set(onlybytecode_modules_file "${project_rcc_qmlcache}/aotstats_onlybytecode_modules.txt") + list(JOIN onlybytecode_modules "\n" onlybytecode_modules_lines) + file(WRITE ${onlybytecode_modules_file} "${onlybytecode_modules_lines}") + list(APPEND qmlaotstats_options "--only-bytecode-modules" "${onlybytecode_modules_file}") + endif() + if(empty_modules) + set(empty_modules_file "${project_rcc_qmlcache}/aotstats_empty_modules.txt") + list(JOIN empty_modules "\n" empty_modules_lines) + file(WRITE ${empty_modules_file} "${empty_modules_lines}") + list(APPEND qmlaotstats_options "--empty-modules" "${empty_modules_file}") + endif() + list(JOIN module_aotstats_files "\n" module_aotstats_lines) - set(aotstats_list_file "${PROJECT_BINARY_DIR}/.rcc/qmlcache/all_aotstats.aotstatslist") + set(aotstats_list_file "${project_rcc_qmlcache}/all_aotstats.aotstatslist") file(WRITE "${aotstats_list_file}" "${module_aotstats_lines}") - set(all_aotstats_file "${PROJECT_BINARY_DIR}/.rcc/qmlcache/all_aotstats.aotstats") - set(formatted_stats_file "${PROJECT_BINARY_DIR}/.rcc/qmlcache/all_aotstats.txt") + set(all_aotstats_file "${project_rcc_qmlcache}/all_aotstats.aotstats") + set(formatted_stats_file "${project_rcc_qmlcache}/all_aotstats.txt") _qt_internal_get_tool_wrapper_script_path(tool_wrapper) add_custom_command( @@ -1159,6 +1185,8 @@ function(_qt_internal_deferred_aotstats_setup) format "${all_aotstats_file}" "${formatted_stats_file}" + "${qmlaotstats_options}" + COMMAND_EXPAND_LISTS ) if(NOT TARGET all_aotstats) @@ -2723,6 +2751,10 @@ function(qt6_target_qml_sources target) message(FATAL_ERROR "Unknown/unexpected arguments: ${arg_UNPARSED_ARGUMENTS}") endif() + if(NOT arg_QML_FILES) + set_property(GLOBAL APPEND PROPERTY _qt_qml_aotstats_module_targets ${target}) + endif() + get_target_property(no_lint ${target} QT_QML_MODULE_NO_LINT) if(NOT arg_QML_FILES AND NOT arg_RESOURCES) if(NOT arg_NO_LINT AND NOT no_lint) @@ -2846,8 +2878,10 @@ function(qt6_target_qml_sources target) "$<${have_direct_calls}:--direct-calls>" "$<${have_arguments}:${arguments}>" ${qrc_resource_args} - "--dump-aot-stats" - "--module-id=${arg_URI}(${target})" + # The --only-bytecode argument is mutually exclusive with aotstats and can + # be added after qt_add_qml_module. Conditionally add aotstats flags via genex. + "$<$<NOT:$<IN_LIST:--only-bytecode,${arguments}>>:--dump-aot-stats>" + "$<$<NOT:$<IN_LIST:--only-bytecode,${arguments}>>:--module-id=${uri}(${target})>" ) # For direct evaluation in if() below diff --git a/src/qmlcompiler/qqmljscompilerstats.cpp b/src/qmlcompiler/qqmljscompilerstats.cpp index 7cef0f39c3..1932ec7d0b 100644 --- a/src/qmlcompiler/qqmljscompilerstats.cpp +++ b/src/qmlcompiler/qqmljscompilerstats.cpp @@ -33,9 +33,9 @@ void AotStats::insert(const AotStats &other) } } -std::optional<QList<QString>> extractAotstatsFilesList(const QString &aotstatsListPath) +std::optional<QList<QString>> AotStats::readAllLines(const QString &path) { - QFile aotstatsListFile(aotstatsListPath); + QFile aotstatsListFile(path); if (!aotstatsListFile.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug().noquote() << u"Could not open \"%1\" for reading"_s.arg(aotstatsListFile.fileName()); return std::nullopt; @@ -62,7 +62,7 @@ std::optional<AotStats> AotStats::parseAotstatsFile(const QString &aotstatsPath) std::optional<AotStats> AotStats::aggregateAotstatsList(const QString &aotstatsListPath) { - const auto aotstatsFiles = extractAotstatsFilesList(aotstatsListPath); + const auto aotstatsFiles = readAllLines(aotstatsListPath); if (!aotstatsFiles.has_value()) return std::nullopt; diff --git a/src/qmlcompiler/qqmljscompilerstats_p.h b/src/qmlcompiler/qqmljscompilerstats_p.h index 53ebb9f777..31f09473a5 100644 --- a/src/qmlcompiler/qqmljscompilerstats_p.h +++ b/src/qmlcompiler/qqmljscompilerstats_p.h @@ -53,6 +53,7 @@ public: void addEntry(const QString &moduleId, const QString &filepath, const AotStatsEntry &entry); void insert(const AotStats &other); + static std::optional<QStringList> readAllLines(const QString &path); bool saveToDisk(const QString &filepath) const; static std::optional<AotStats> parseAotstatsFile(const QString &aotstatsPath); diff --git a/src/qmlcompiler/qqmljscompilerstatsreporter.cpp b/src/qmlcompiler/qqmljscompilerstatsreporter.cpp index 1cb17f71fe..4684b8d1a5 100644 --- a/src/qmlcompiler/qqmljscompilerstatsreporter.cpp +++ b/src/qmlcompiler/qqmljscompilerstatsreporter.cpp @@ -11,7 +11,9 @@ namespace QQmlJS { using namespace Qt::StringLiterals; -AotStatsReporter::AotStatsReporter(const AotStats &aotstats) : m_aotstats(aotstats) +AotStatsReporter::AotStatsReporter(const AotStats &aotstats, const QStringList &emptyModules, + const QStringList &onlyBytecodeModules) + : m_aotstats(aotstats), m_emptyModules(emptyModules), m_onlyBytecodeModules(onlyBytecodeModules) { for (const auto &[moduleUri, fileEntries] : aotstats.entries().asKeyValueRange()) { for (const auto &[filepath, statsEntries] : fileEntries.asKeyValueRange()) { @@ -68,7 +70,7 @@ void AotStatsReporter::formatDetailedStats(QTextStream &s) const void AotStatsReporter::formatSummary(QTextStream &s) const { s << "############ AOT COMPILATION STATS SUMMARY ############\n"; - if (m_totalCounters.codegens == 0) { + if (m_totalCounters.codegens == 0 && m_emptyModules.empty() && m_onlyBytecodeModules.empty()) { s << "No attempted compilations to Cpp for bindings or functions.\n"; return; } @@ -79,6 +81,12 @@ void AotStatsReporter::formatSummary(QTextStream &s) const << formatSuccessRate(counters.codegens, counters.successes) << "\n"; } + for (const auto &module : m_emptyModules) + s << u"Module %1: No .qml files to compile.\n"_s.arg(module); + + for (const auto &module : m_onlyBytecodeModules) + s << u"Module %1: No .qml files compiled (--only-bytecode).\n"_s.arg(module); + s << "Total results: " << formatSuccessRate(m_totalCounters.codegens, m_totalCounters.successes); s << "\n"; diff --git a/src/qmlcompiler/qqmljscompilerstatsreporter_p.h b/src/qmlcompiler/qqmljscompilerstatsreporter_p.h index 9acf4adac8..1b29b63321 100644 --- a/src/qmlcompiler/qqmljscompilerstatsreporter_p.h +++ b/src/qmlcompiler/qqmljscompilerstatsreporter_p.h @@ -27,7 +27,8 @@ namespace QQmlJS { class Q_QMLCOMPILER_EXPORT AotStatsReporter { public: - AotStatsReporter(const QQmlJS::AotStats &); + AotStatsReporter(const QQmlJS::AotStats &stats, const QStringList &emptyModules, + const QStringList &onlyBytecodeModules); QString format() const; @@ -37,6 +38,8 @@ private: QString formatSuccessRate(int codegens, int successes) const; const AotStats &m_aotstats; + const QStringList &m_emptyModules; + const QStringList &m_onlyBytecodeModules; struct Counters { diff --git a/tools/qmlaotstats/main.cpp b/tools/qmlaotstats/main.cpp index 24b34efec3..42ef263979 100644 --- a/tools/qmlaotstats/main.cpp +++ b/tools/qmlaotstats/main.cpp @@ -54,6 +54,10 @@ int main(int argc, char **argv) parser.addPositionalArgument("output", "Aggregate mode: the path where to store the " "aggregated aotstats. Format mode: the the path where " "the formatted output will be saved."); + QCommandLineOption emptyModulesOption("empty-modules", QCoreApplication::translate("main", "Format mode: File containing a list of modules with no QML files."), "file"); + parser.addOption(emptyModulesOption); + QCommandLineOption onlyBytecodeModulesOption("only-bytecode-modules", QCoreApplication::translate("main", "Format mode: File containing a list of modules for which only the bytecode is generated."), "file"); + parser.addOption(onlyBytecodeModulesOption); parser.process(app); const auto &positionalArgs = parser.positionalArguments(); @@ -74,7 +78,18 @@ int main(int argc, char **argv) const auto aotstats = QQmlJS::AotStats::parseAotstatsFile(positionalArgs[1]); if (!aotstats.has_value()) return EXIT_FAILURE; - const QQmlJS::AotStatsReporter reporter(aotstats.value()); + + const auto emptyModules = parser.isSet(emptyModulesOption) + ? QQmlJS::AotStats::readAllLines(parser.value(emptyModulesOption)) + : QStringList(); + const auto onlyBytecodeModules = parser.isSet(onlyBytecodeModulesOption) + ? QQmlJS::AotStats::readAllLines(parser.value(onlyBytecodeModulesOption)) + : QStringList(); + if (!emptyModules || !onlyBytecodeModules) + return EXIT_FAILURE; + + const QQmlJS::AotStatsReporter reporter(aotstats.value(), emptyModules.value(), + onlyBytecodeModules.value()); if (!saveFormattedStats(reporter.format(), positionalArgs[2])) return EXIT_FAILURE; } diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index 3b8fe5bad4..aebca5f2fc 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -257,6 +257,11 @@ int main(int argc, char **argv) error.augment("Error compiling qml file: "_L1).print(); return EXIT_FAILURE; } + + if (parser.isSet(onlyBytecode)) { + QQmlJS::AotStats emptyStats; + emptyStats.saveToDisk(outputFileName + u".aotstats"_s); + } } else { QStringList importPaths; |