windeployqt: Don't copy files from unneeded QML modules

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 <timothee.keller@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit a1e052a2918b6863dada64cba1a67c16762cde85)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Arno Rehn 2023-09-25 13:11:58 +02:00 committed by Qt Cherry-pick Bot
parent 24fffd93a2
commit 330d05eabc
2 changed files with 24 additions and 4 deletions

View File

@ -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<QString, QString>
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)) {

View File

@ -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);
}
}