From 330d05eabc56aee0ad42544e47f79ad473156c7e Mon Sep 17 00:00:00 2001 From: Arno Rehn Date: Mon, 25 Sep 2023 13:11:58 +0200 Subject: [PATCH] windeployqt: Don't copy files from unneeded QML modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, windeployqt would recurse into subdirectories when copying QML modules, even if those subdirectories were a nested QML module that was not needed for deployment. Since most QML modules are nested in the QtQuick and QtQml modules, the old code effectively always copied *all* QML modules. This patch adds guards that prevent recursing into subdirectories if those subdirectories represent QML modules. These nested modules will still be deployed, but only if referenced from the QML application (as determined by qmlimportscanner). Fixes: QTBUG-117459 Change-Id: I4c0dfc15956ff40a0e8caec3fa334df10cc92ccd Reviewed-by: Timothée Keller Reviewed-by: Joerg Bornemann (cherry picked from commit a1e052a2918b6863dada64cba1a67c16762cde85) Reviewed-by: Qt Cherry-pick Bot --- src/tools/windeployqt/main.cpp | 25 ++++++++++++++++++++++--- src/tools/windeployqt/qmlutils.cpp | 3 ++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/tools/windeployqt/main.cpp b/src/tools/windeployqt/main.cpp index b1c02599532..689a0cd83a8 100644 --- a/src/tools/windeployqt/main.cpp +++ b/src/tools/windeployqt/main.cpp @@ -776,13 +776,19 @@ public: SkipSources = 0x2 }; - explicit QmlDirectoryFileEntryFunction(Platform platform, DebugMatchMode debugMatchMode, unsigned flags) + explicit QmlDirectoryFileEntryFunction( + const QString &moduleSourcePath, Platform platform, DebugMatchMode debugMatchMode, unsigned flags) : m_flags(flags), m_qmlNameFilter(QmlDirectoryFileEntryFunction::qmlNameFilters(flags)) - , m_dllFilter(platform, debugMatchMode) + , m_dllFilter(platform, debugMatchMode), m_moduleSourcePath(moduleSourcePath) {} QStringList operator()(const QDir &dir) const { + if (moduleSourceDir(dir).canonicalPath() != m_moduleSourcePath) { + // If we're in a different module, return nothing. + return {}; + } + QStringList result; const QStringList &libraries = m_dllFilter(dir); for (const QString &library : libraries) { @@ -798,6 +804,17 @@ public: } private: + static QDir moduleSourceDir(const QDir &dir) + { + QDir moduleSourceDir = dir; + while (!moduleSourceDir.exists(QStringLiteral("qmldir"))) { + if (!moduleSourceDir.cdUp()) { + return {}; + } + } + return moduleSourceDir; + } + static inline QStringList qmlNameFilters(unsigned flags) { QStringList result; @@ -814,6 +831,7 @@ private: const unsigned m_flags; NameFilterFileEntryFunction m_qmlNameFilter; DllDirectoryFileEntryFunction m_dllFilter; + QString m_moduleSourcePath; }; static qint64 qtModule(QString module, const QString &infix) @@ -1526,7 +1544,8 @@ static DeployResult deploy(const Options &options, const QMap unsigned qmlDirectoryFileFlags = 0; if (options.deployPdb) qmlDirectoryFileFlags |= QmlDirectoryFileEntryFunction::DeployPdb; - if (!updateFile(module.sourcePath, QmlDirectoryFileEntryFunction(options.platform, + if (!updateFile(module.sourcePath, QmlDirectoryFileEntryFunction(module.sourcePath, + options.platform, debugMatchMode, qmlDirectoryFileFlags), installPath, updateFileFlags, options.json, errorMessage)) { diff --git a/src/tools/windeployqt/qmlutils.cpp b/src/tools/windeployqt/qmlutils.cpp index 5104af01949..a7e63e74705 100644 --- a/src/tools/windeployqt/qmlutils.cpp +++ b/src/tools/windeployqt/qmlutils.cpp @@ -67,7 +67,8 @@ static void findFileRecursion(const QDir &directory, Platform platform, const QFileInfoList &subDirs = directory.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); for (const QFileInfo &subDirFi : subDirs) { QDir subDirectory(subDirFi.absoluteFilePath()); - if (subDirectory.isReadable()) + // Don't enter other QML modules when recursing! + if (subDirectory.isReadable() && !subDirectory.exists(QStringLiteral("qmldir"))) findFileRecursion(subDirectory, platform, debugMatchMode, matches); } }