From 5dcfe401a3d30d20334fe85adc7480b8920b66d5 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 27 Apr 2022 16:19:10 +0200 Subject: [PATCH] ExtensionSystem: Add support for static plugins Loads all plugins that are known via Q_IMPORT_PLUGIN() Change-Id: I3c1fe223ce6e4dcdb7729f5ab3e782e78bca5afc Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Cristian Adam --- src/libs/extensionsystem/pluginmanager.cpp | 14 +++- src/libs/extensionsystem/pluginspec.cpp | 83 +++++++++++++++------- src/libs/extensionsystem/pluginspec.h | 4 +- src/libs/extensionsystem/pluginspec_p.h | 7 +- 4 files changed, 77 insertions(+), 31 deletions(-) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index fe2902e24bc..16180a9358f 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1694,11 +1694,20 @@ void PluginManagerPrivate::readPluginPaths() // default pluginCategories.insert(QString(), QVector()); + // from the file system for (const QString &pluginFile : pluginFiles(pluginPaths)) { PluginSpec *spec = PluginSpec::read(pluginFile); - if (!spec) // not a Qt Creator plugin - continue; + if (spec) // Qt Creator plugin + pluginSpecs.append(spec); + } + // static + for (const QStaticPlugin &plugin : QPluginLoader::staticPlugins()) { + PluginSpec *spec = PluginSpec::read(plugin); + if (spec) // Qt Creator plugin + pluginSpecs.append(spec); + } + for (PluginSpec *spec : pluginSpecs) { // defaultDisabledPlugins and defaultEnabledPlugins from install settings // is used to override the defaults read from the plugin spec if (spec->isEnabledByDefault() && defaultDisabledPlugins.contains(spec->name())) { @@ -1714,7 +1723,6 @@ void PluginManagerPrivate::readPluginPaths() spec->d->setEnabledBySettings(false); pluginCategories[spec->category()].append(spec); - pluginSpecs.append(spec); } resolveDependencies(); enableDependenciesIndirectly(); diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 92c7095efd6..311d0d07770 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -558,6 +558,16 @@ PluginSpec *PluginSpec::read(const QString &filePath) return spec; } +PluginSpec *PluginSpec::read(const QStaticPlugin &plugin) +{ + auto spec = new PluginSpec; + if (!spec->d->read(plugin)) { // not a Qt Creator plugin + delete spec; + return nullptr; + } + return spec; +} + //==========PluginSpecPrivate================== namespace { @@ -592,9 +602,28 @@ namespace { */ PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec) : q(spec) +{} + +void PluginSpecPrivate::reset() { - if (Utils::HostOsInfo::isMacHost()) - loader.setLoadHints(QLibrary::ExportExternalSymbolsHint); + name.clear(); + version.clear(); + compatVersion.clear(); + vendor.clear(); + copyright.clear(); + license.clear(); + description.clear(); + url.clear(); + category.clear(); + location.clear(); + filePath.clear(); + state = PluginSpec::Invalid; + hasError = false; + errorString.clear(); + dependencies.clear(); + metaData = QJsonObject(); + loader.reset(); + staticPlugin.reset(); } /*! @@ -604,32 +633,32 @@ PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec) bool PluginSpecPrivate::read(const QString &fileName) { qCDebug(pluginLog) << "\nReading meta data of" << fileName; - name - = version - = compatVersion - = vendor - = copyright - = license - = description - = url - = category - = location - = QString(); - state = PluginSpec::Invalid; - hasError = false; - errorString.clear(); - dependencies.clear(); - metaData = QJsonObject(); + reset(); QFileInfo fileInfo(fileName); location = fileInfo.absolutePath(); filePath = fileInfo.absoluteFilePath(); - loader.setFileName(filePath); - if (loader.fileName().isEmpty()) { + loader.emplace(); + if (Utils::HostOsInfo::isMacHost()) + loader->setLoadHints(QLibrary::ExportExternalSymbolsHint); + loader->setFileName(filePath); + if (loader->fileName().isEmpty()) { qCDebug(pluginLog) << "Cannot open file"; return false; } - if (!readMetaData(loader.metaData())) + if (!readMetaData(loader->metaData())) + return false; + + state = PluginSpec::Read; + return true; +} + +bool PluginSpecPrivate::read(const QStaticPlugin &plugin) +{ + qCDebug(pluginLog) << "\nReading meta data of static plugin"; + reset(); + staticPlugin = plugin; + if (!readMetaData(plugin.metaData())) return false; state = PluginSpec::Read; @@ -1050,17 +1079,19 @@ bool PluginSpecPrivate::loadLibrary() hasError = true; return false; } - if (!loader.load()) { + if (loader && !loader->load()) { hasError = true; - errorString = QDir::toNativeSeparators(filePath) - + QString::fromLatin1(": ") + loader.errorString(); + errorString = QDir::toNativeSeparators(filePath) + QString::fromLatin1(": ") + + loader->errorString(); return false; } - auto *pluginObject = qobject_cast(loader.instance()); + auto *pluginObject = loader ? qobject_cast(loader->instance()) + : qobject_cast(staticPlugin->instance()); if (!pluginObject) { hasError = true; errorString = QCoreApplication::translate("PluginSpec", "Plugin is not valid (does not derive from IPlugin)"); - loader.unload(); + if (loader) + loader->unload(); return false; } state = PluginSpec::Loaded; diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index c8737c8abaf..22b06364349 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -29,8 +29,9 @@ #include -#include #include +#include +#include #include QT_BEGIN_NAMESPACE @@ -135,6 +136,7 @@ public: void setEnabledBySettings(bool value); static PluginSpec *read(const QString &filePath); + static PluginSpec *read(const QStaticPlugin &plugin); private: PluginSpec(); diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h index 09e410ef63c..4b08c5659f2 100644 --- a/src/libs/extensionsystem/pluginspec_p.h +++ b/src/libs/extensionsystem/pluginspec_p.h @@ -28,6 +28,8 @@ #include "pluginspec.h" #include "iplugin.h" +#include + #include #include #include @@ -50,7 +52,9 @@ class EXTENSIONSYSTEM_EXPORT PluginSpecPrivate : public QObject public: PluginSpecPrivate(PluginSpec *spec); + void reset(); bool read(const QString &fileName); + bool read(const QStaticPlugin &plugin); bool provides(const QString &pluginName, const QString &version) const; bool resolveDependencies(const QVector &specs); bool loadLibrary(); @@ -65,7 +69,8 @@ public: void setForceEnabled(bool value); void setForceDisabled(bool value); - QPluginLoader loader; + Utils::optional loader; + Utils::optional staticPlugin; QString name; QString version;