aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier De Cannière <[email protected]>2024-10-30 13:40:55 +0100
committerOlivier De Cannière <[email protected]>2024-11-04 15:21:09 +0100
commit318ac440653a570d2bd18fc3d25e1b2fc8af88fa (patch)
treeb20109a0333f44538565c69a4d69cd0683495133
parent09f51978f4ab03f9dcaa36aba4f0c861f59b890c (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.cmake44
-rw-r--r--src/qmlcompiler/qqmljscompilerstats.cpp6
-rw-r--r--src/qmlcompiler/qqmljscompilerstats_p.h1
-rw-r--r--src/qmlcompiler/qqmljscompilerstatsreporter.cpp12
-rw-r--r--src/qmlcompiler/qqmljscompilerstatsreporter_p.h5
-rw-r--r--tools/qmlaotstats/main.cpp17
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp5
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;