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 <thiago.macieira@intel.com>bb10
parent
1f437e7540
commit
6c76fdc761
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue