From e7e557cea2f35031cf3a51fcb8fa7a275625830f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 29 Mar 2019 16:05:25 +0100 Subject: [PATCH] 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) --- src/corelib/plugin/qplugin_p.h | 6 ++++-- src/tools/moc/generator.cpp | 6 ++++++ src/tools/moc/moc.cpp | 4 ++++ src/tools/moc/moc.h | 1 + .../auto/corelib/plugin/qpluginloader/staticplugin/main.cpp | 2 +- .../auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp | 1 + 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/corelib/plugin/qplugin_p.h b/src/corelib/plugin/qplugin_p.h index 717129268ba..ce45ebf700c 100644 --- a/src/corelib/plugin/qplugin_p.h +++ b/src/corelib/plugin/qplugin_p.h @@ -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 diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 02c1fbd3940..ab7e400f47f 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -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(); diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 2f52dd6ca02..7f43917f7e7 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -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; } } diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 2bba8a5bb9d..bb1c9501fe2 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -167,6 +167,7 @@ struct ClassDef : BaseDef { struct PluginData { QByteArray iid; + QByteArray uri; QMap metaArgs; QJsonDocument metaData; } pluginData; diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp index d891839b1eb..6d163ea336a 100644 --- a/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp @@ -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() {} }; diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index 4316ea14ea6..b06000d9c4f 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -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"); }