summaryrefslogtreecommitdiffstats
path: root/src/tools/windeployqt/main.cpp
diff options
context:
space:
mode:
authorMichał Policht <michpolicht@gmail.com>2024-01-28 10:52:40 +0100
committerMichał Policht <michpolicht@gmail.com>2024-03-07 23:42:41 +0100
commit5010eda5345bdbfc12e134d6fb3ae5b7370e2185 (patch)
treebc105fee9c798b3331fbd9024549dca2559bd9d7 /src/tools/windeployqt/main.cpp
parentd8f6425fef1050525480afec662a417a7645c22e (diff)
Windeployqt: introduce --include-soft-plugins command line option
Some plugins may have dependencies on additional Qt modules. This is handled by deployPlugin() function. Existing code does not look for plugins associated with these modules however, because the loop iterates over plugin directories only once. This change introduces an option that will make windeployqt take into account all such soft dependencies by making recursive calls to findQtPlugins(). Pick-to: 6.7 Task-number: QTBUG-121583 Change-Id: Id6535426a47f9b92a3035e864dfdd7577b82c9ad Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Timothée Keller <timothee.keller@qt.io>
Diffstat (limited to 'src/tools/windeployqt/main.cpp')
-rw-r--r--src/tools/windeployqt/main.cpp62
1 files changed, 42 insertions, 20 deletions
diff --git a/src/tools/windeployqt/main.cpp b/src/tools/windeployqt/main.cpp
index c3a89400d4..abee6e13c1 100644
--- a/src/tools/windeployqt/main.cpp
+++ b/src/tools/windeployqt/main.cpp
@@ -182,7 +182,7 @@ struct Options {
bool compilerRunTime = false;
bool softwareRasterizer = true;
bool ffmpeg = true;
- PluginLists pluginSelections;
+ PluginSelections pluginSelections;
Platform platform = WindowsDesktopMsvc;
ModuleBitset additionalLibraries;
ModuleBitset disabledLibraries;
@@ -399,6 +399,10 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
QStringLiteral("Skip plugin deployment."));
parser->addOption(noPluginsOption);
+ QCommandLineOption includeSoftPluginsOption(QStringLiteral("include-soft-plugins"),
+ QStringLiteral("Include in the deployment all relevant plugins by taking into account all soft dependencies."));
+ parser->addOption(includeSoftPluginsOption);
+
QCommandLineOption skipPluginTypesOption(QStringLiteral("skip-plugin-types"),
QStringLiteral("A comma-separated list of plugin types that are not deployed (qmltooling,generic)."),
QStringLiteral("plugin types"));
@@ -559,6 +563,8 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
return CommandLineParseError;
}
+ options->pluginSelections.includeSoftPlugins = parser->isSet(includeSoftPluginsOption);
+
if (parser->isSet(skipPluginTypesOption))
options->pluginSelections.disabledPluginTypes = parser->value(skipPluginTypesOption).split(u',');
@@ -930,9 +936,9 @@ static qint64 qtModule(QString module, const QString &infix)
// Return the path if a plugin is to be deployed
static QString deployPlugin(const QString &plugin, const QDir &subDir, const bool dueToModule,
- const DebugMatchMode &debugMatchMode, ModuleBitset *usedQtModules,
+ const DebugMatchMode &debugMatchMode, ModuleBitset *pluginNeededQtModules,
const ModuleBitset &disabledQtModules,
- const PluginLists &pluginSelections, const QString &libraryLocation,
+ const PluginSelections &pluginSelections, const QString &libraryLocation,
const QString &infix, Platform platform,
bool deployInsightTrackerPlugin)
{
@@ -986,44 +992,35 @@ static QString deployPlugin(const QString &plugin, const QDir &subDir, const boo
return pluginPath;
QStringList dependentQtLibs;
- ModuleBitset neededModules;
QString errorMessage;
if (findDependentQtLibraries(libraryLocation, pluginPath, platform,
&errorMessage, &dependentQtLibs)) {
for (int d = 0; d < dependentQtLibs.size(); ++d) {
const qint64 module = qtModule(dependentQtLibs.at(d), infix);
if (module >= 0)
- neededModules[module] = 1;
+ (*pluginNeededQtModules)[module] = 1;
}
} else {
std::wcerr << "Warning: Cannot determine dependencies of "
<< QDir::toNativeSeparators(pluginPath) << ": " << errorMessage << '\n';
}
- ModuleBitset missingModules;
- missingModules = neededModules & disabledQtModules;
- if (missingModules.any()) {
+ ModuleBitset disabledNeededQtModules;
+ disabledNeededQtModules = *pluginNeededQtModules & disabledQtModules;
+ if (disabledNeededQtModules.any()) {
if (optVerboseLevel) {
std::wcout << "Skipping plugin " << plugin
<< " due to disabled dependencies ("
- << formatQtModules(missingModules).constData() << ").\n";
+ << formatQtModules(disabledNeededQtModules).constData() << ").\n";
}
return {};
}
- missingModules = (neededModules & ~*usedQtModules);
- if (missingModules.any()) {
- *usedQtModules |= missingModules;
- if (optVerboseLevel) {
- std::wcout << "Adding " << formatQtModules(missingModules).constData()
- << " for " << plugin << " from plugin type: " << subDirName << '\n';
- }
- }
return pluginPath;
}
static bool needsPluginType(const QString &subDirName, const PluginInformation &pluginInfo,
- const PluginLists &pluginSelections)
+ const PluginSelections &pluginSelections)
{
bool needsTypeForPlugin = false;
for (const QString &plugin: pluginSelections.includedPlugins) {
@@ -1034,7 +1031,7 @@ static bool needsPluginType(const QString &subDirName, const PluginInformation &
}
QStringList findQtPlugins(ModuleBitset *usedQtModules, const ModuleBitset &disabledQtModules,
- const PluginInformation &pluginInfo, const PluginLists &pluginSelections,
+ const PluginInformation &pluginInfo, const PluginSelections &pluginSelections,
const QString &qtPluginsDirName, const QString &libraryLocation,
const QString &infix, DebugMatchMode debugMatchModeIn, Platform platform,
QString *platformPlugin, bool deployInsightTrackerPlugin)
@@ -1043,6 +1040,7 @@ QStringList findQtPlugins(ModuleBitset *usedQtModules, const ModuleBitset &disab
return QStringList();
QDir pluginsDir(qtPluginsDirName);
QStringList result;
+ bool missingQtModulesAdded = false;
const QFileInfoList &pluginDirs = pluginsDir.entryInfoList(QStringList(u"*"_s), QDir::Dirs | QDir::NoDotAndDotDot);
for (const QFileInfo &subDirFi : pluginDirs) {
const QString subDirName = subDirFi.fileName();
@@ -1065,18 +1063,42 @@ QStringList findQtPlugins(ModuleBitset *usedQtModules, const ModuleBitset &disab
const QStringList plugins =
findSharedLibraries(subDir, platform, debugMatchMode, QString());
for (const QString &plugin : plugins) {
+ ModuleBitset pluginNeededQtModules;
const QString pluginPath =
- deployPlugin(plugin, subDir, dueToModule, debugMatchMode, usedQtModules,
+ deployPlugin(plugin, subDir, dueToModule, debugMatchMode, &pluginNeededQtModules,
disabledQtModules, pluginSelections, libraryLocation, infix,
platform, deployInsightTrackerPlugin);
if (!pluginPath.isEmpty()) {
if (isPlatformPlugin && plugin.startsWith(u"qwindows"))
*platformPlugin = subDir.absoluteFilePath(plugin);
result.append(pluginPath);
+
+ const ModuleBitset missingModules = (pluginNeededQtModules & ~*usedQtModules);
+ if (missingModules.any()) {
+ *usedQtModules |= missingModules;
+ missingQtModulesAdded = true;
+ if (optVerboseLevel) {
+ std::wcout << "Adding " << formatQtModules(missingModules).constData()
+ << " for " << plugin << " from plugin type: " << subDirName << '\n';
+ }
+ }
}
} // for filter
} // type matches
} // for plugin folder
+
+ // If missing Qt modules were added during plugin deployment make additional pass, because we may need
+ // additional plugins.
+ if (pluginSelections.includeSoftPlugins && missingQtModulesAdded) {
+ if (optVerboseLevel) {
+ std::wcout << "Performing additional pass of finding Qt plugins due to updated Qt module list: "
+ << formatQtModules(*usedQtModules).constData() << "\n";
+ }
+ return findQtPlugins(usedQtModules, disabledQtModules, pluginInfo, pluginSelections, qtPluginsDirName,
+ libraryLocation, infix, debugMatchModeIn, platform, platformPlugin,
+ deployInsightTrackerPlugin);
+ }
+
return result;
}