diff options
| author | Ulf Hermann <[email protected]> | 2015-06-19 13:29:55 +0200 |
|---|---|---|
| committer | Simon Hausmann <[email protected]> | 2015-08-18 19:59:46 +0000 |
| commit | 6c76fdc7616ac3b62c5750600bd6d5985dbceb20 (patch) | |
| tree | 5f8ec6d8b0b444d07d9fe3780acf77996157c890 | |
| parent | 1f437e7540cbdfca8adcad0b69ae26237846ab23 (diff) | |
Allow loading of static plugins if QT_NO_LIBRARY is set.
We keep two symbols from QPluginLoader defined, even if QT_NO_LIBRARY
is set in order to be able to locate static plugins. This doesn't
constitute any loading of shared libraries or plugins from external
files at runtime.
Using these symbols we can enable most of QFactoryLoader even if
QT_NO_LIBRARY is set. Only update(), refreshAll(), library() and
the dtor make no sense then. This way QGenericPlugin also becomes
useful with QT_NO_LIBRARY.
Task-number: QTBUG-3045
Change-Id: Ib7842ce5799e8e2caa46431d95fddd1adda0fc41
Reviewed-by: Thiago Macieira <[email protected]>
| -rw-r--r-- | src/corelib/plugin/qfactoryloader.cpp | 19 | ||||
| -rw-r--r-- | src/corelib/plugin/qfactoryloader_p.h | 21 | ||||
| -rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 4 | ||||
| -rw-r--r-- | src/corelib/plugin/qlibrary_p.h | 25 | ||||
| -rw-r--r-- | src/corelib/plugin/qpluginloader.cpp | 15 | ||||
| -rw-r--r-- | src/corelib/plugin/qpluginloader.h | 15 | ||||
| -rw-r--r-- | src/gui/kernel/qgenericplugin.cpp | 4 | ||||
| -rw-r--r-- | src/gui/kernel/qgenericplugin.h | 5 | ||||
| -rw-r--r-- | tests/auto/corelib/plugin/qfactoryloader/test/test.pro | 5 | ||||
| -rw-r--r-- | tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp | 8 |
10 files changed, 77 insertions, 44 deletions
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index daecf0d3b0a..f7545b5bcb0 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -33,7 +33,7 @@ #include "qfactoryloader_p.h" -#ifndef QT_NO_LIBRARY +#ifndef QT_NO_QOBJECT #include "qfactoryinterface.h" #include "qmap.h" #include <qdir.h> @@ -66,6 +66,7 @@ class QFactoryLoaderPrivate : public QObjectPrivate public: QFactoryLoaderPrivate(){} QByteArray iid; +#ifndef QT_NO_LIBRARY ~QFactoryLoaderPrivate(); mutable QMutex mutex; QList<QLibraryPrivate*> libraryList; @@ -73,8 +74,11 @@ public: QString suffix; Qt::CaseSensitivity cs; QStringList loadedPaths; +#endif }; +#ifndef QT_NO_LIBRARY + Q_GLOBAL_STATIC(QList<QFactoryLoader *>, qt_factory_loaders) Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_factoryloader_mutex, (QMutex::Recursive)) @@ -226,6 +230,8 @@ void QFactoryLoader::refreshAll() } } +#endif // QT_NO_LIBRARY + QFactoryLoader::QFactoryLoader(const char *iid, const QString &suffix, Qt::CaseSensitivity cs) @@ -234,21 +240,28 @@ QFactoryLoader::QFactoryLoader(const char *iid, moveToThread(QCoreApplicationPrivate::mainThread()); Q_D(QFactoryLoader); d->iid = iid; +#ifndef QT_NO_LIBRARY d->cs = cs; d->suffix = suffix; QMutexLocker locker(qt_factoryloader_mutex()); update(); qt_factory_loaders()->append(this); +#else + Q_UNUSED(suffix); + Q_UNUSED(cs); +#endif } QList<QJsonObject> QFactoryLoader::metaData() const { Q_D(const QFactoryLoader); QList<QJsonObject> metaData; +#ifndef QT_NO_LIBRARY QMutexLocker locker(&d->mutex); for (int i = 0; i < d->libraryList.size(); ++i) metaData.append(d->libraryList.at(i)->metaData); +#endif foreach (const QStaticPlugin &plugin, QPluginLoader::staticPlugins()) { const QJsonObject object = plugin.metaData(); @@ -265,6 +278,7 @@ QObject *QFactoryLoader::instance(int index) const if (index < 0) return 0; +#ifndef QT_NO_LIBRARY if (index < d->libraryList.size()) { QLibraryPrivate *library = d->libraryList.at(index); if (library->instance || library->loadPlugin()) { @@ -280,6 +294,7 @@ QObject *QFactoryLoader::instance(int index) const return 0; } index -= d->libraryList.size(); +#endif QVector<QStaticPlugin> staticPlugins = QPluginLoader::staticPlugins(); for (int i = 0; i < staticPlugins.count(); ++i) { @@ -330,4 +345,4 @@ int QFactoryLoader::indexOf(const QString &needle) const QT_END_NAMESPACE -#endif // QT_NO_LIBRARY +#endif // QT_NO_QOBJECT diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h index 1c48491b0db..ee07084180d 100644 --- a/src/corelib/plugin/qfactoryloader_p.h +++ b/src/corelib/plugin/qfactoryloader_p.h @@ -45,17 +45,18 @@ // We mean it. // +#include "QtCore/qglobal.h" +#ifndef QT_NO_QOBJECT + #include "QtCore/qobject.h" #include "QtCore/qstringlist.h" #include "QtCore/qjsonobject.h" #include "QtCore/qmap.h" #include "private/qlibrary_p.h" -#ifndef QT_NO_LIBRARY QT_BEGIN_NAMESPACE class QFactoryLoaderPrivate; - class Q_CORE_EXPORT QFactoryLoader : public QObject { Q_OBJECT @@ -65,21 +66,23 @@ public: explicit QFactoryLoader(const char *iid, const QString &suffix = QString(), Qt::CaseSensitivity = Qt::CaseSensitive); + +#ifndef QT_NO_LIBRARY ~QFactoryLoader(); - QList<QJsonObject> metaData() const; - QObject *instance(int index) const; + void update(); + static void refreshAll(); #if defined(Q_OS_UNIX) && !defined (Q_OS_MAC) QLibraryPrivate *library(const QString &key) const; -#endif +#endif // Q_OS_UNIX && !Q_OS_MAC +#endif // !QT_NO_LIBRARY QMultiMap<int, QString> keyMap() const; int indexOf(const QString &needle) const; - void update(); - - static void refreshAll(); + QList<QJsonObject> metaData() const; + QObject *instance(int index) const; }; template <class PluginInterface, class FactoryInterface> @@ -112,6 +115,6 @@ PluginInterface *qLoadPlugin1(const QFactoryLoader *loader, QT_END_NAMESPACE -#endif // QT_NO_LIBRARY +#endif // QT_NO_QOBJECT #endif // QFACTORYLOADER_P_H diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 920e02ae5a3..763f0fb1e95 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -302,7 +302,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) if (pos >= 0) { if (hasMetaData) { const char *data = filedata + pos; - QJsonDocument doc = QLibraryPrivate::fromRawMetaData(data); + QJsonDocument doc = qJsonFromRawLibraryMetaData(data); lib->metaData = doc.object(); if (qt_debug_component()) qWarning("Found metadata in lib %s, metadata=\n%s\n", @@ -677,7 +677,7 @@ static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryP if (!szData) return false; - QJsonDocument doc = QLibraryPrivate::fromRawMetaData(szData); + QJsonDocument doc = qJsonFromRawLibraryMetaData(szData); if (doc.isNull()) return false; priv->metaData = doc.object(); diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h index ada90d7bfd6..11b0cb1eb9c 100644 --- a/src/corelib/plugin/qlibrary_p.h +++ b/src/corelib/plugin/qlibrary_p.h @@ -57,9 +57,20 @@ # include "QtCore/qt_windows.h" #endif +QT_BEGIN_NAMESPACE + +// Needed also in case of QT_NO_LIBRARY, for static plugin loading. +inline QJsonDocument qJsonFromRawLibraryMetaData(const char *raw) +{ + raw += strlen("QTMETADATA "); + // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h), + // but doesn't include the size of the header (8 bytes) + QByteArray json(raw, qFromLittleEndian<uint>(*(const uint *)(raw + 8)) + 8); + return QJsonDocument::fromBinaryData(json); +} + #ifndef QT_NO_LIBRARY -QT_BEGIN_NAMESPACE bool qt_debug_component(); @@ -104,14 +115,6 @@ public: void updatePluginState(); bool isPlugin(); - static inline QJsonDocument fromRawMetaData(const char *raw) { - raw += strlen("QTMETADATA "); - // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h), - // but doesn't include the size of the header (8 bytes) - QByteArray json(raw, qFromLittleEndian<uint>(*(const uint *)(raw + 8)) + 8); - return QJsonDocument::fromBinaryData(json); - } - private: explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints); ~QLibraryPrivate(); @@ -132,8 +135,8 @@ private: friend class QLibraryStore; }; -QT_END_NAMESPACE - #endif // QT_NO_LIBRARY +QT_END_NAMESPACE + #endif // QLIBRARY_P_H diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 292ad305258..b95f7539f6b 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -41,10 +41,10 @@ #include "qdebug.h" #include "qdir.h" -#ifndef QT_NO_LIBRARY - QT_BEGIN_NAMESPACE +#ifndef QT_NO_LIBRARY + /*! \class QPluginLoader \inmodule QtCore @@ -382,9 +382,6 @@ QString QPluginLoader::errorString() const return (!d || d->errorString.isEmpty()) ? tr("Unknown error") : d->errorString; } -typedef QVector<QStaticPlugin> StaticPluginList; -Q_GLOBAL_STATIC(StaticPluginList, staticPluginList) - /*! \since 4.4 \property QPluginLoader::loadHints @@ -413,6 +410,11 @@ QLibrary::LoadHints QPluginLoader::loadHints() const return d ? d->loadHints() : QLibrary::LoadHints(); } +#endif // QT_NO_LIBRARY + +typedef QVector<QStaticPlugin> StaticPluginList; +Q_GLOBAL_STATIC(StaticPluginList, staticPluginList) + /*! \relates QPluginLoader \since 5.0 @@ -465,9 +467,8 @@ QVector<QStaticPlugin> QPluginLoader::staticPlugins() */ QJsonObject QStaticPlugin::metaData() const { - return QLibraryPrivate::fromRawMetaData(rawMetaData()).object(); + return qJsonFromRawLibraryMetaData(rawMetaData()).object(); } QT_END_NAMESPACE -#endif // QT_NO_LIBRARY diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h index 0ab25bbb078..5dc7d1b66cd 100644 --- a/src/corelib/plugin/qpluginloader.h +++ b/src/corelib/plugin/qpluginloader.h @@ -37,10 +37,10 @@ #include <QtCore/qlibrary.h> #include <QtCore/qplugin.h> -#ifndef QT_NO_LIBRARY - QT_BEGIN_NAMESPACE +#ifndef QT_NO_LIBRARY + class QLibraryPrivate; class QJsonObject; @@ -78,8 +78,17 @@ private: Q_DISABLE_COPY(QPluginLoader) }; -QT_END_NAMESPACE +#else + +class Q_CORE_EXPORT QPluginLoader +{ +public: + static QObjectList staticInstances(); + static QVector<QStaticPlugin> staticPlugins(); +}; #endif // QT_NO_LIBRARY +QT_END_NAMESPACE + #endif //QPLUGINLOADER_H diff --git a/src/gui/kernel/qgenericplugin.cpp b/src/gui/kernel/qgenericplugin.cpp index 47f3ea58118..ae423b93e37 100644 --- a/src/gui/kernel/qgenericplugin.cpp +++ b/src/gui/kernel/qgenericplugin.cpp @@ -33,8 +33,6 @@ #include "qgenericplugin.h" -#ifndef QT_NO_LIBRARY - QT_BEGIN_NAMESPACE /*! @@ -90,5 +88,3 @@ QGenericPlugin::~QGenericPlugin() */ QT_END_NAMESPACE - -#endif // QT_NO_LIBRARY diff --git a/src/gui/kernel/qgenericplugin.h b/src/gui/kernel/qgenericplugin.h index 03c1df7fba5..21ae97f0451 100644 --- a/src/gui/kernel/qgenericplugin.h +++ b/src/gui/kernel/qgenericplugin.h @@ -39,9 +39,6 @@ QT_BEGIN_NAMESPACE - -#ifndef QT_NO_LIBRARY - #define QGenericPluginFactoryInterface_iid "org.qt-project.Qt.QGenericPluginFactoryInterface" class Q_GUI_EXPORT QGenericPlugin : public QObject @@ -54,8 +51,6 @@ public: virtual QObject* create(const QString& name, const QString &spec) = 0; }; -#endif // QT_NO_LIBRARY - QT_END_NAMESPACE #endif // QGENERICPLUGIN_H diff --git a/tests/auto/corelib/plugin/qfactoryloader/test/test.pro b/tests/auto/corelib/plugin/qfactoryloader/test/test.pro index d8dfaac29e9..5e7f44c005a 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/test/test.pro +++ b/tests/auto/corelib/plugin/qfactoryloader/test/test.pro @@ -20,3 +20,8 @@ win32 { mac: CONFIG -= app_bundle DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +load(qfeatures) +contains(QT_DISABLED_FEATURES, library) { + LIBS += -L ../bin/ -lplugin1 -lplugin2 +} diff --git a/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp index 474f4e98685..92a4dda252f 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp +++ b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp @@ -38,6 +38,11 @@ #include "plugin1/plugininterface1.h" #include "plugin2/plugininterface2.h" +#ifdef QT_NO_LIBRARY +Q_IMPORT_PLUGIN(Plugin1) +Q_IMPORT_PLUGIN(Plugin2) +#endif + class tst_QFactoryLoader : public QObject { Q_OBJECT @@ -54,8 +59,9 @@ void tst_QFactoryLoader::initTestCase() { const QString binFolder = QFINDTESTDATA(binFolderC); QVERIFY2(!binFolder.isEmpty(), "Unable to locate 'bin' folder"); - +#ifndef QT_NO_LIBRARY QCoreApplication::setLibraryPaths(QStringList(QFileInfo(binFolder).absolutePath())); +#endif } void tst_QFactoryLoader::usingTwoFactoriesFromSameDir() |
