ExtensionSystem: Add support for static plugins

Loads all plugins that are known via Q_IMPORT_PLUGIN()

Change-Id: I3c1fe223ce6e4dcdb7729f5ab3e782e78bca5afc
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Eike Ziller
2022-04-27 16:19:10 +02:00
parent b425273ea8
commit 5dcfe401a3
4 changed files with 77 additions and 31 deletions

View File

@@ -1694,11 +1694,20 @@ void PluginManagerPrivate::readPluginPaths()
// default // default
pluginCategories.insert(QString(), QVector<PluginSpec *>()); pluginCategories.insert(QString(), QVector<PluginSpec *>());
// from the file system
for (const QString &pluginFile : pluginFiles(pluginPaths)) { for (const QString &pluginFile : pluginFiles(pluginPaths)) {
PluginSpec *spec = PluginSpec::read(pluginFile); PluginSpec *spec = PluginSpec::read(pluginFile);
if (!spec) // not a Qt Creator plugin if (spec) // Qt Creator plugin
continue; 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 // defaultDisabledPlugins and defaultEnabledPlugins from install settings
// is used to override the defaults read from the plugin spec // is used to override the defaults read from the plugin spec
if (spec->isEnabledByDefault() && defaultDisabledPlugins.contains(spec->name())) { if (spec->isEnabledByDefault() && defaultDisabledPlugins.contains(spec->name())) {
@@ -1714,7 +1723,6 @@ void PluginManagerPrivate::readPluginPaths()
spec->d->setEnabledBySettings(false); spec->d->setEnabledBySettings(false);
pluginCategories[spec->category()].append(spec); pluginCategories[spec->category()].append(spec);
pluginSpecs.append(spec);
} }
resolveDependencies(); resolveDependencies();
enableDependenciesIndirectly(); enableDependenciesIndirectly();

View File

@@ -558,6 +558,16 @@ PluginSpec *PluginSpec::read(const QString &filePath)
return spec; 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================== //==========PluginSpecPrivate==================
namespace { namespace {
@@ -592,9 +602,28 @@ namespace {
*/ */
PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec) PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
: q(spec) : q(spec)
{}
void PluginSpecPrivate::reset()
{ {
if (Utils::HostOsInfo::isMacHost()) name.clear();
loader.setLoadHints(QLibrary::ExportExternalSymbolsHint); 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) bool PluginSpecPrivate::read(const QString &fileName)
{ {
qCDebug(pluginLog) << "\nReading meta data of" << fileName; qCDebug(pluginLog) << "\nReading meta data of" << fileName;
name reset();
= version
= compatVersion
= vendor
= copyright
= license
= description
= url
= category
= location
= QString();
state = PluginSpec::Invalid;
hasError = false;
errorString.clear();
dependencies.clear();
metaData = QJsonObject();
QFileInfo fileInfo(fileName); QFileInfo fileInfo(fileName);
location = fileInfo.absolutePath(); location = fileInfo.absolutePath();
filePath = fileInfo.absoluteFilePath(); filePath = fileInfo.absoluteFilePath();
loader.setFileName(filePath); loader.emplace();
if (loader.fileName().isEmpty()) { if (Utils::HostOsInfo::isMacHost())
loader->setLoadHints(QLibrary::ExportExternalSymbolsHint);
loader->setFileName(filePath);
if (loader->fileName().isEmpty()) {
qCDebug(pluginLog) << "Cannot open file"; qCDebug(pluginLog) << "Cannot open file";
return false; 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; return false;
state = PluginSpec::Read; state = PluginSpec::Read;
@@ -1050,17 +1079,19 @@ bool PluginSpecPrivate::loadLibrary()
hasError = true; hasError = true;
return false; return false;
} }
if (!loader.load()) { if (loader && !loader->load()) {
hasError = true; hasError = true;
errorString = QDir::toNativeSeparators(filePath) errorString = QDir::toNativeSeparators(filePath) + QString::fromLatin1(": ")
+ QString::fromLatin1(": ") + loader.errorString(); + loader->errorString();
return false; return false;
} }
auto *pluginObject = qobject_cast<IPlugin*>(loader.instance()); auto *pluginObject = loader ? qobject_cast<IPlugin *>(loader->instance())
: qobject_cast<IPlugin *>(staticPlugin->instance());
if (!pluginObject) { if (!pluginObject) {
hasError = true; hasError = true;
errorString = QCoreApplication::translate("PluginSpec", "Plugin is not valid (does not derive from IPlugin)"); errorString = QCoreApplication::translate("PluginSpec", "Plugin is not valid (does not derive from IPlugin)");
loader.unload(); if (loader)
loader->unload();
return false; return false;
} }
state = PluginSpec::Loaded; state = PluginSpec::Loaded;

View File

@@ -29,8 +29,9 @@
#include <utils/porting.h> #include <utils/porting.h>
#include <QString>
#include <QHash> #include <QHash>
#include <QStaticPlugin>
#include <QString>
#include <QVector> #include <QVector>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -135,6 +136,7 @@ public:
void setEnabledBySettings(bool value); void setEnabledBySettings(bool value);
static PluginSpec *read(const QString &filePath); static PluginSpec *read(const QString &filePath);
static PluginSpec *read(const QStaticPlugin &plugin);
private: private:
PluginSpec(); PluginSpec();

View File

@@ -28,6 +28,8 @@
#include "pluginspec.h" #include "pluginspec.h"
#include "iplugin.h" #include "iplugin.h"
#include <utils/optional.h>
#include <QJsonObject> #include <QJsonObject>
#include <QObject> #include <QObject>
#include <QPluginLoader> #include <QPluginLoader>
@@ -50,7 +52,9 @@ class EXTENSIONSYSTEM_EXPORT PluginSpecPrivate : public QObject
public: public:
PluginSpecPrivate(PluginSpec *spec); PluginSpecPrivate(PluginSpec *spec);
void reset();
bool read(const QString &fileName); bool read(const QString &fileName);
bool read(const QStaticPlugin &plugin);
bool provides(const QString &pluginName, const QString &version) const; bool provides(const QString &pluginName, const QString &version) const;
bool resolveDependencies(const QVector<PluginSpec *> &specs); bool resolveDependencies(const QVector<PluginSpec *> &specs);
bool loadLibrary(); bool loadLibrary();
@@ -65,7 +69,8 @@ public:
void setForceEnabled(bool value); void setForceEnabled(bool value);
void setForceDisabled(bool value); void setForceDisabled(bool value);
QPluginLoader loader; Utils::optional<QPluginLoader> loader;
Utils::optional<QStaticPlugin> staticPlugin;
QString name; QString name;
QString version; QString version;