moc: Add a standard way of specifying a URI as part of Q_PLUGIN_METADATA
Usually, when you load a plugin, you don't want to load just any plugin that fulfills a given interface, but rather a specific one. When loading dynamic plugins you can differentiate the plugins by file name. This doesn't work in the static case, and file names are also separate from the plugin metadata shipped inside the plugin files. To solve this problem, different hacks have been developed in various places. QML extension plugins add a special property "uri" via the -M option of moc, QML debug plugins expect you to add a json file with an array of "Keys", Qt Creator plugins have a "Name" in their json files, etc. By allowing the identifier for the plugin to be specified inline with the metadata declaration we can make many of the above workarounds obsolete and provide a clean way for users to find their plugins. Task-number: QTBUG-74775 Change-Id: Ie2af16c49d4c5aa5a77fab0fae1e0a4449bd7a39 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
217f3d83d7
commit
e7e557cea2
@ -60,7 +60,8 @@ enum class QtPluginMetaDataKeys {
|
||||
Requirements,
|
||||
IID,
|
||||
ClassName,
|
||||
MetaData
|
||||
MetaData,
|
||||
URI
|
||||
};
|
||||
|
||||
// F(IntKey, StringKey, Description)
|
||||
@ -68,7 +69,8 @@ enum class QtPluginMetaDataKeys {
|
||||
#define QT_PLUGIN_FOREACH_METADATA(F) \
|
||||
F(QtPluginMetaDataKeys::IID, "IID", "Plugin's Interface ID") \
|
||||
F(QtPluginMetaDataKeys::ClassName, "className", "Plugin class name") \
|
||||
F(QtPluginMetaDataKeys::MetaData, "MetaData", "Other meta data")
|
||||
F(QtPluginMetaDataKeys::MetaData, "MetaData", "Other meta data") \
|
||||
F(QtPluginMetaDataKeys::URI, "URI", "Plugin URI")
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -1652,6 +1652,12 @@ void Generator::generatePluginMetaData()
|
||||
jsonObjectToCbor(&map, o);
|
||||
}
|
||||
|
||||
if (!cdef->pluginData.uri.isEmpty()) {
|
||||
dev.nextItem("\"URI\"");
|
||||
cbor_encode_int(&map, int(QtPluginMetaDataKeys::URI));
|
||||
cbor_encode_text_string(&map, cdef->pluginData.uri.constData(), cdef->pluginData.uri.size());
|
||||
}
|
||||
|
||||
// Add -M args from the command line:
|
||||
for (auto it = cdef->pluginData.metaArgs.cbegin(), end = cdef->pluginData.metaArgs.cend(); it != end; ++it) {
|
||||
const QJsonArray &a = it.value();
|
||||
|
@ -1311,6 +1311,9 @@ void Moc::parsePluginData(ClassDef *def)
|
||||
if (l == "IID") {
|
||||
next(STRING_LITERAL);
|
||||
def->pluginData.iid = unquotedLexem();
|
||||
} else if (l == "URI") {
|
||||
next(STRING_LITERAL);
|
||||
def->pluginData.uri = unquotedLexem();
|
||||
} else if (l == "FILE") {
|
||||
next(STRING_LITERAL);
|
||||
QByteArray metaDataFile = unquotedLexem();
|
||||
@ -1351,6 +1354,7 @@ void Moc::parsePluginData(ClassDef *def)
|
||||
+ " does not contain a valid JSON object. Declaration will be ignored";
|
||||
warning(msg.constData());
|
||||
def->pluginData.iid = QByteArray();
|
||||
def->pluginData.uri = QByteArray();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ struct ClassDef : BaseDef {
|
||||
|
||||
struct PluginData {
|
||||
QByteArray iid;
|
||||
QByteArray uri;
|
||||
QMap<QString, QJsonArray> metaArgs;
|
||||
QJsonDocument metaData;
|
||||
} pluginData;
|
||||
|
@ -31,7 +31,7 @@
|
||||
class StaticPlugin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "SomeIID")
|
||||
Q_PLUGIN_METADATA(IID "SomeIID" URI "qt.test.pluginloader.staticplugin")
|
||||
public:
|
||||
StaticPlugin() {}
|
||||
};
|
||||
|
@ -552,6 +552,7 @@ void tst_QPluginLoader::staticPlugins()
|
||||
QCOMPARE(metaData.value("version").toInt(), QT_VERSION);
|
||||
QCOMPARE(metaData.value("IID").toString(), "SomeIID");
|
||||
QCOMPARE(metaData.value("ExtraMetaData"), QJsonArray({ "StaticPlugin", "foo" }));
|
||||
QCOMPARE(metaData.value("URI").toString(), "qt.test.pluginloader.staticplugin");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user