Create both plugin and backing library in qt_add_protobuf

This approach allows reusing the existing backing target if it's
library and makes step towards plugin-less Qml module.

Pick-to: 6.6
Task-number: QTBUG-115117
Change-Id: I02243d700683ac9e01c1471c3ccccaae71841165
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Alexey Edelev 2023-07-19 19:26:47 +02:00
parent 16713c6e32
commit e9f6546483
8 changed files with 62 additions and 15 deletions

View File

@ -419,6 +419,32 @@ function(qt6_add_protobuf target)
target_sources(${target} PRIVATE ${type_registrations}) target_sources(${target} PRIVATE ${type_registrations})
endif() endif()
if(arg_QML)
string(REPLACE "." "/" qml_module_output_path "${qml_uri}")
set(qml_module_output_full_path "${CMAKE_CURRENT_BINARY_DIR}/${qml_module_output_path}")
qt_policy(SET QTP0001 NEW)
qt6_add_qml_module(${target}
URI ${qml_uri}
NO_GENERATE_PLUGIN_SOURCE
NO_PLUGIN_OPTIONAL
PLUGIN_TARGET "${target}plugin"
VERSION 1.0
OUTPUT_DIRECTORY "${qml_module_output_full_path}"
)
target_sources(${target}plugin PRIVATE
"${output_directory}/${qml_plugin_base_name}plugin.cpp")
set_target_properties(${target}plugin
PROPERTIES
AUTOMOC ON
)
target_link_libraries(${target}plugin PRIVATE
${QT_CMAKE_EXPORT_NAMESPACE}::Protobuf
)
list(APPEND ${arg_OUTPUT_TARGETS} ${target}plugin)
endif()
if(DEFINED arg_OUTPUT_HEADERS) if(DEFINED arg_OUTPUT_HEADERS)
set(${arg_OUTPUT_HEADERS} "${generated_headers}" PARENT_SCOPE) set(${arg_OUTPUT_HEADERS} "${generated_headers}" PARENT_SCOPE)
endif() endif()
@ -426,20 +452,6 @@ function(qt6_add_protobuf target)
if(DEFINED arg_OUTPUT_TARGETS) if(DEFINED arg_OUTPUT_TARGETS)
set(${arg_OUTPUT_TARGETS} "${${arg_OUTPUT_TARGETS}}" PARENT_SCOPE) set(${arg_OUTPUT_TARGETS} "${${arg_OUTPUT_TARGETS}}" PARENT_SCOPE)
endif() endif()
if(arg_QML)
qt_policy(SET QTP0001 NEW)
string(REPLACE "." "/" output_qml_plugin "${qml_uri}")
qt6_add_qml_module(${target}
URI ${qml_uri}
PLUGIN_TARGET ${target}
NO_PLUGIN_OPTIONAL
NO_GENERATE_PLUGIN_SOURCE
VERSION 1.0
OUTPUT_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}/${output_qml_plugin}
)
endif()
endfunction() endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)

View File

@ -207,11 +207,18 @@ void QProtobufGenerator::GenerateQmlPluginIntro(Printer *printer,
} }
printer->Print("\n"); printer->Print("\n");
printer->Print(CommonTemplates::QmlPluginExportMacroTemplate()); printer->Print(CommonTemplates::QmlPluginExportMacroTemplate());
std::string qmlPackageEscaped = utils::escapedQmlUri(qmlPackageUri);
printer->Print({{"qml_package", qmlPackageUri},
{"qml_package_escaped", qmlPackageEscaped}},
CommonTemplates::QmlExtensionPluginPreamble());
printer->Print({{"plugin_name", pluginClassName}}, printer->Print({{"plugin_name", pluginClassName}},
CommonTemplates::QmlExtensionPluginClass()); CommonTemplates::QmlExtensionPluginClass());
printer->Print({{"plugin_name", pluginClassName}, printer->Print({{"plugin_name", pluginClassName},
{"qml_package", qmlPackageUri}}, {"qml_package", qmlPackageUri},
{"qml_package_escaped", qmlPackageEscaped}},
CommonTemplates::QmlExtensionPluginClassBody()); CommonTemplates::QmlExtensionPluginClassBody());
} }

View File

@ -1042,6 +1042,12 @@ const char *CommonTemplates::QmlPluginExportMacroTemplate()
"#endif\n"; "#endif\n";
} }
const char *CommonTemplates::QmlExtensionPluginPreamble()
{
return "\nextern void qml_register_types_$qml_package_escaped$();\n"
"Q_GHS_KEEP_REFERENCE(qml_register_types_$qml_package_escaped$);\n";
}
const char *CommonTemplates::QmlExtensionPluginClass() const char *CommonTemplates::QmlExtensionPluginClass()
{ {
return "\nclass QPB_QML_EXPORT $plugin_name$Plugin : public QQmlExtensionPlugin\n"; return "\nclass QPB_QML_EXPORT $plugin_name$Plugin : public QQmlExtensionPlugin\n";
@ -1057,6 +1063,8 @@ const char *CommonTemplates::QmlExtensionPluginClassBody()
" void registerTypes(const char *uri) override\n" " void registerTypes(const char *uri) override\n"
" {\n" " {\n"
" Q_ASSERT(uri == QLatin1String(\"$qml_package$\"));\n" " Q_ASSERT(uri == QLatin1String(\"$qml_package$\"));\n"
" volatile auto registration = &qml_register_types_$qml_package_escaped$;\n"
" Q_UNUSED(registration);\n"
" qmlRegisterModule(uri, 1, 0);\n"; " qmlRegisterModule(uri, 1, 0);\n";
} }

View File

@ -204,6 +204,7 @@ public:
static const char *ExportMacroTemplate(); static const char *ExportMacroTemplate();
static const char *QmlPluginExportMacroTemplate(); static const char *QmlPluginExportMacroTemplate();
static const char *QmlExtensionPluginPreamble();
static const char *QmlExtensionPluginClass(); static const char *QmlExtensionPluginClass();
static const char *QmlExtensionPluginClassNoExport(); static const char *QmlExtensionPluginClassNoExport();
static const char *QmlExtensionPluginClassBody(); static const char *QmlExtensionPluginClassBody();

View File

@ -9,6 +9,7 @@
#include <ctype.h> #include <ctype.h>
#include <assert.h> #include <assert.h>
#include <regex>
namespace { namespace {
const std::string_view asciiSpacing = " \t\n\r\f\v"; const std::string_view asciiSpacing = " \t\n\r\f\v";
@ -100,6 +101,13 @@ std::string deCapitalizeAsciiName(std::string name)
return name; return name;
} }
std::string escapedQmlUri(const std::string &uri)
{
assert(!uri.empty());
static std::regex uriExceptionsRegex("[^a-zA-Z0-9]");
return std::regex_replace(uri, uriExceptionsRegex, "_");
}
std::string &rtrim(std::string &s) std::string &rtrim(std::string &s)
{ {
const size_t cut = s.find_last_not_of(asciiSpacing); const size_t cut = s.find_last_not_of(asciiSpacing);

View File

@ -29,6 +29,7 @@ std::string removeFileSuffix(std::string fileName);
std::string extractFileBasename(std::string fileName); std::string extractFileBasename(std::string fileName);
std::string capitalizeAsciiName(std::string name); std::string capitalizeAsciiName(std::string name);
std::string deCapitalizeAsciiName(std::string name); std::string deCapitalizeAsciiName(std::string name);
std::string escapedQmlUri(const std::string &uri);
std::string &rtrim(std::string &s); std::string &rtrim(std::string &s);
// trim from beginning of string (left) // trim from beginning of string (left)
std::string &ltrim(std::string &s); std::string &ltrim(std::string &s);

View File

@ -13,6 +13,9 @@
# define QPB_QML_EXPORT # define QPB_QML_EXPORT
#endif #endif
extern void qml_register_types_nopackage_uri_test();
Q_GHS_KEEP_REFERENCE(qml_register_types_nopackage_uri_test);
class QPB_QML_EXPORT NopackageUriTestPlugin : public QQmlExtensionPlugin class QPB_QML_EXPORT NopackageUriTestPlugin : public QQmlExtensionPlugin
{ {
Q_OBJECT Q_OBJECT
@ -24,6 +27,8 @@ public:
void registerTypes(const char *uri) override void registerTypes(const char *uri) override
{ {
Q_ASSERT(uri == QLatin1String("nopackage.uri.test")); Q_ASSERT(uri == QLatin1String("nopackage.uri.test"));
volatile auto registration = &qml_register_types_nopackage_uri_test;
Q_UNUSED(registration);
qmlRegisterModule(uri, 1, 0); qmlRegisterModule(uri, 1, 0);
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(
::TestEnumGadget::staticMetaObject, ::TestEnumGadget::staticMetaObject,

View File

@ -14,6 +14,9 @@
# define QPB_QML_EXPORT # define QPB_QML_EXPORT
#endif #endif
extern void qml_register_types_qtprotobufnamespace_tests();
Q_GHS_KEEP_REFERENCE(qml_register_types_qtprotobufnamespace_tests);
class QPB_QML_EXPORT QtprotobufnamespaceTestsPlugin : public QQmlExtensionPlugin class QPB_QML_EXPORT QtprotobufnamespaceTestsPlugin : public QQmlExtensionPlugin
{ {
Q_OBJECT Q_OBJECT
@ -25,6 +28,8 @@ public:
void registerTypes(const char *uri) override void registerTypes(const char *uri) override
{ {
Q_ASSERT(uri == QLatin1String("qtprotobufnamespace.tests")); Q_ASSERT(uri == QLatin1String("qtprotobufnamespace.tests"));
volatile auto registration = &qml_register_types_qtprotobufnamespace_tests;
Q_UNUSED(registration);
qmlRegisterModule(uri, 1, 0); qmlRegisterModule(uri, 1, 0);
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(
qtprotobufnamespace::tests::SimpleEnumMessage::staticMetaObject, qtprotobufnamespace::tests::SimpleEnumMessage::staticMetaObject,