Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qplugin.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2021 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QPLUGIN_H
6#define QPLUGIN_H
7
8#if 0
9#pragma qt_class(QtPlugin)
10#endif
11
12#include <QtCore/qobject.h>
13#include <QtCore/qpointer.h>
14#include <QtCore/qjsonobject.h>
15
16#include <QtCore/q20algorithm.h>
17
19
20// Used up to Qt 6.2
21inline constexpr unsigned char qPluginArchRequirements()
22{
23 return 0
24#ifndef QT_NO_DEBUG
25 | 1
26#endif
27#ifdef __AVX2__
28 | 2
29# ifdef __AVX512F__
30 | 4
31# endif
32#endif
33 ;
34}
35
38{
39 static constexpr quint8 CurrentMetaDataVersion = 1;
40 static constexpr char MagicString[] = {
41 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!'
42 };
43
44 template <size_t OSize, typename OO, size_t ISize, typename II>
45 static constexpr void copy(OO (&out)[OSize], II (&in)[ISize])
46 {
47 static_assert(OSize <= ISize, "Output would not be fully initialized");
48 q20::copy_n(in, OSize, out);
49 }
50
51 static constexpr quint8 archRequirements()
52 {
53 quint8 v = 0;
54#if defined(__AVX512F__)
55 v = 4; // x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ and AVX512VL
56#elif defined(__AVX__) || defined(__BMI__) || defined(__BMI2__) || defined(__MOVBE__)
57 v = 3; // x86-64-v3: AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE
58#elif defined(__SSE3__)
59 v = 2; // x86-64-v2: POPCNT, SSE3, SSSE3, SSE4.1 and SSE4.2.
60#elif defined(__SSE__) || defined(__MMX___)
61 v = 1; // x86-64 baseline: SSE and SSE2
62#endif
63#ifndef QT_NO_DEBUG
64 v |= 0x80;
65#endif
66 return v;
67 }
68
75 static_assert(alignof(Header) == 1, "Alignment of header incorrect with this compiler");
76
82 static_assert(alignof(MagicHeader) == 1, "Alignment of header incorrect with this compiler");
83
85 static constexpr quint32 NoteType = 0x74510001;
86 static constexpr char NoteName[] = "qt-project!";
87
88 // ELF note header
92 char name[sizeof(NoteName)] = {};
93
94 // payload
95 alignas(void *) // mandatory alignment as per ELF note requirements
97 constexpr ElfNoteHeader(quint32 payloadSize) : n_descsz(sizeof(header) + payloadSize)
98 { QPluginMetaData::copy(name, NoteName); }
99 };
100 static_assert(alignof(ElfNoteHeader) == alignof(void*), "Alignment of header incorrect with this compiler");
101 static_assert((sizeof(ElfNoteHeader::name) % 4) == 0, "ELF note name length not a multiple of 4");
102
103 const void *data;
105};
106typedef QPluginMetaData (*QtPluginMetaDataFunction)();
107
108
109struct Q_CORE_EXPORT QStaticPlugin
110{
111public:
112 constexpr QStaticPlugin(QtPluginInstanceFunction i, QtPluginMetaDataFunction m)
113 : instance(i), rawMetaDataSize(m().size), rawMetaData(m().data)
114 {}
115 QtPluginInstanceFunction instance;
116 QJsonObject metaData() const;
117
118private:
119 qsizetype rawMetaDataSize;
120 const void *rawMetaData;
121 friend class QFactoryLoader;
122};
123Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
124
125void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
126
127#if defined(Q_OF_ELF) || (defined(Q_OS_WIN) && (defined (Q_CC_GNU) || defined(Q_CC_CLANG)))
128# define QT_PLUGIN_METADATA_SECTION
129 __attribute__ ((section (".qtmetadata"))) __attribute__((used))
130#elif defined(Q_OS_DARWIN)
131# define QT_PLUGIN_METADATA_SECTION
132 __attribute__ ((section ("__TEXT,qtmetadata"))) __attribute__((used))
133#elif defined(Q_CC_MSVC)
134// TODO: Implement section parsing for MSVC
135#pragma section(".qtmetadata",read,shared)
136# define QT_PLUGIN_METADATA_SECTION
137 __declspec(allocate(".qtmetadata"))
138#else
139# define QT_PLUGIN_METADATA_SECTION
140#endif
141
142// Since Qt 6.3
143template <auto (&PluginMetaData)> class QPluginMetaDataV2
144{
145 struct ElfNotePayload : QPluginMetaData::ElfNoteHeader {
146 static constexpr size_t HeaderOffset = offsetof(QPluginMetaData::ElfNoteHeader, header);
147 quint8 payload[sizeof(PluginMetaData)] = {};
148 constexpr ElfNotePayload() : ElfNoteHeader(sizeof(PluginMetaData))
149 { QPluginMetaData::copy(payload, PluginMetaData); }
150 };
151
152 struct RegularPayload : QPluginMetaData::MagicHeader {
153 static constexpr size_t HeaderOffset = offsetof(QPluginMetaData::MagicHeader, header);
154 quint8 payload[sizeof(PluginMetaData)] = {};
155 constexpr RegularPayload() { QPluginMetaData::copy(payload, PluginMetaData); }
156 };
157
158 struct StaticPayload {
159 static constexpr size_t HeaderOffset = 0;
160 QPluginMetaData::Header header = {};
161 quint8 payload[sizeof(PluginMetaData)] = {};
162 constexpr StaticPayload() { QPluginMetaData::copy(payload, PluginMetaData); }
163 };
164
165#if defined(QT_STATICPLUGIN)
166# define QT_PLUGIN_METADATAV2_SECTION
167 using Payload = StaticPayload;
168#elif defined(Q_OF_ELF)
169# ifdef Q_CC_CLANG
170# define QT_PLUGIN_METADATAV2_SECTION
171 __attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *)),
172 no_sanitize("address")))
173# else
174# define QT_PLUGIN_METADATAV2_SECTION
175 __attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *))))
176# endif
177 using Payload = ElfNotePayload;
178#else
179# define QT_PLUGIN_METADATAV2_SECTION QT_PLUGIN_METADATA_SECTION
180 using Payload = RegularPayload;
181#endif
182
183 Payload payload = {};
184
185public:
187 {
188 Q_ASSERT(reinterpret_cast<const char *>(&payload) + Payload::HeaderOffset ==
189 reinterpret_cast<const char *>(&payload.header));
190 return { &payload.header, sizeof(payload) - Payload::HeaderOffset };
191 }
192};
193
194#define Q_IMPORT_PLUGIN(PLUGIN)
195 extern const QT_PREPEND_NAMESPACE(QStaticPlugin) QT_MANGLE_NAMESPACE(qt_static_plugin_##PLUGIN)();
196 namespace {
197 struct Static##PLUGIN##PluginInstance {
198 Static##PLUGIN##PluginInstance() {
199 qRegisterStaticPluginFunction(QT_MANGLE_NAMESPACE(qt_static_plugin_##PLUGIN)());
200 }
201 };
202 } /* namespace */
203 /* QTBUG-139615: static, to work around bug in clazy-non-pod-global-static */
204 static Static##PLUGIN##PluginInstance static##PLUGIN##Instance;
205
206#if defined(QT_PLUGIN_RESOURCE_INIT_FUNCTION)
207# define QT_PLUGIN_RESOURCE_INIT
208 extern void QT_PLUGIN_RESOURCE_INIT_FUNCTION();
209 QT_PLUGIN_RESOURCE_INIT_FUNCTION();
210#else
211# define QT_PLUGIN_RESOURCE_INIT
212#endif
213
214#define Q_PLUGIN_INSTANCE(IMPLEMENTATION)
215 {
216 static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance;
217 if (!_instance) {
219 _instance = new IMPLEMENTATION;
220 }
221 return _instance;
222 }
223
224#if defined(QT_STATICPLUGIN)
225# define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
226 static QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance_##MANGLEDNAME()
227 Q_PLUGIN_INSTANCE(PLUGINCLASS)
228 const QT_PREPEND_NAMESPACE(QStaticPlugin) QT_MANGLE_NAMESPACE(qt_static_plugin_##MANGLEDNAME)()
229 { return { qt_plugin_instance_##MANGLEDNAME, qt_plugin_query_metadata_##MANGLEDNAME}; }
230 /**/
231
232# define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME)
233 static QPluginMetaData qt_plugin_query_metadata_##PLUGINCLASSNAME()
234 { return { qt_pluginMetaData_##PLUGINCLASSNAME, sizeof qt_pluginMetaData_##PLUGINCLASSNAME }; }
235 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, PLUGINCLASSNAME)
236
237# define QT_MOC_EXPORT_PLUGIN_V2(PLUGINCLASS, MANGLEDNAME, MD)
238 static QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_##MANGLEDNAME()
239 { static constexpr QPluginMetaDataV2<MD> md{}; return md; }
240 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
241#else
242# define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
243 extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance()
244 Q_PLUGIN_INSTANCE(PLUGINCLASS)
245 /**/
246
247# define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME)
248 extern "C" Q_DECL_EXPORT
249 QPluginMetaData qt_plugin_query_metadata()
250 { return { qt_pluginMetaData_##PLUGINCLASSNAME, sizeof qt_pluginMetaData_##PLUGINCLASSNAME }; }
251 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, PLUGINCLASSNAME)
252
253# define QT_MOC_EXPORT_PLUGIN_V2(PLUGINCLASS, MANGLEDNAME, MD)
254 extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_v2()
255 { static constexpr QT_PLUGIN_METADATAV2_SECTION QPluginMetaDataV2<MD> md{}; return md; }
256 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
257#endif
258
259#define Q_EXPORT_PLUGIN(PLUGIN)
260 Q_EXPORT_PLUGIN2(PLUGIN, PLUGIN)
261# define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS)
262 static_assert(false, "Old plugin system used")
263
264# define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS)
265 static_assert(false, "Old plugin system used")
266
267
268QT_END_NAMESPACE
269
270#endif // Q_PLUGIN_H
\inmodule QtCore\reentrant
void setExtraSearchPath(const QString &path)
int indexOf(const QString &needle) const
QMultiMap< int, QString > keyMap() const
MetaDataList metaData() const
QList< QCborArray > metaDataKeys() const
QObject * instance(int index) const
operator QPluginMetaData() const
Definition qplugin.h:186
Q_DECLARE_TYPEINFO(QByteArrayView, Q_PRIMITIVE_TYPE)
QT_REQUIRE_CONFIG(cborstreamreader)
Q_TRACE_POINT(qtcore, QFactoryLoader_update, const QString &fileName)
static bool isIidMatch(QByteArrayView raw, QLatin1StringView iid)
static IterationResult iterateInPluginMetaData(QByteArrayView raw, F &&f)
PluginInterface * qLoadPlugin(const QFactoryLoader *loader, const QString &key, Args &&...args)
#define Q_PLUGIN_INSTANCE(IMPLEMENTATION)
Definition qplugin.h:214
#define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
Definition qplugin.h:242
QT_BEGIN_NAMESPACE constexpr unsigned char qPluginArchRequirements()
Definition qplugin.h:21
#define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS)
Definition qplugin.h:261
#define QT_PLUGIN_RESOURCE_INIT
Definition qplugin.h:211
#define QT_PLUGIN_METADATAV2_SECTION
Definition qplugin.h:179
QObject *(* QtPluginInstanceFunction)()
Definition qplugin.h:36
#define QT_PLUGIN_METADATA_SECTION
Definition qplugin.h:139
char name[sizeof(NoteName)]
Definition qplugin.h:92
constexpr ElfNoteHeader(quint32 payloadSize)
Definition qplugin.h:97
static constexpr quint32 NoteType
Definition qplugin.h:85
static constexpr char NoteName[]
Definition qplugin.h:86
quint8 plugin_arch_requirements
Definition qplugin.h:73
char magic[sizeof(QPluginMetaData::MagicString)]
Definition qplugin.h:78
static constexpr void copy(OO(&out)[OSize], II(&in)[ISize])
Definition qplugin.h:45
const void * data
Definition qplugin.h:103
static constexpr quint8 CurrentMetaDataVersion
Definition qplugin.h:39
static constexpr quint8 archRequirements()
Definition qplugin.h:51
static constexpr char MagicString[]
Definition qplugin.h:40
\inmodule QtCore
Definition qplugin.h:110