diff options
author | Michał Policht <michpolicht@gmail.com> | 2024-01-28 10:52:40 +0100 |
---|---|---|
committer | Michał Policht <michpolicht@gmail.com> | 2024-03-07 23:42:41 +0100 |
commit | 5010eda5345bdbfc12e134d6fb3ae5b7370e2185 (patch) | |
tree | bc105fee9c798b3331fbd9024549dca2559bd9d7 /src/tools/windeployqt/main.cpp | |
parent | d8f6425fef1050525480afec662a417a7645c22e (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.cpp | 62 |
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; } |