Browse Source

Implement optional qml part generation

- Add 'QML' option to protobuf_generate_all cmake routine
- Make qml generation part dependend on 'QML' option
- Update tests, examples and README
Alexey Edelev 5 years ago
parent
commit
03709e3ebe

+ 3 - 1
README.md

@@ -159,10 +159,12 @@ Due to cmake restrictions it's required to specify resulting artifacts manually
 
 *PROTO_FILES* - List of .proto files that will be used in generation procedure
 
-*MULTI* - Enabled/disabled multi-files generation mode. In case if this property is set to TRUE generator will create pair of header/source files for each message
+*MULTI* - Enables/disables multi-files generation mode. In case if this property is set to TRUE generator will create pair of header/source files for each message
 
 **Note:** multi-files generation mode is defined as deprecated by QtProtobuf team, and might have poor support in future
 
+*QML* - Enables/disables QML code generation in protobuf classes. If set to TRUE qml related code for lists and qml registration to be generated.
+
 **Outcome:**
 
 *QtProtobuf_GENERATED* - variable that will contain generated STATIC library target name

+ 8 - 3
cmake/QtProtobufCommon.cmake

@@ -42,7 +42,7 @@ endfunction(protobuf_generate_all)
 
 function(add_test_target)
     set(options)
-    set(oneValueArgs QML_DIR TARGET MULTI)
+    set(oneValueArgs QML_DIR TARGET MULTI QML)
     set(multiValueArgs SOURCES GENERATED_HEADERS EXCLUDE_HEADERS PROTO_FILES)
     cmake_parse_arguments(add_test_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
@@ -67,7 +67,8 @@ function(add_test_target)
         PROTO_FILES ${PROTO_FILES}
         GENERATED_HEADERS ${add_test_target_GENERATED_HEADERS}
         EXCLUDE_HEADERS ${add_test_target_EXCLUDE_HEADERS}
-        MULTI ${add_test_target_MULTI})
+        MULTI ${add_test_target_MULTI}
+        QML ${add_test_target_QML})
 
     add_executable(${add_test_target_TARGET} ${add_test_target_SOURCES})
 
@@ -76,7 +77,11 @@ function(add_test_target)
         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
     endif()
     add_dependencies(${add_test_target_TARGET} ${QtProtobuf_GENERATED})
-    target_link_libraries(${add_test_target_TARGET} gtest_main gtest ${QtProtobuf_GENERATED} ${QTPROTOBUF_COMMON_NAMESPACE}::QtProtobuf ${QTPROTOBUF_COMMON_NAMESPACE}::QtGrpc Qt5::Core Qt5::Test Qt5::Qml Qt5::Network ${CMAKE_THREAD_LIBS_INIT})
+    target_link_libraries(${add_test_target_TARGET} gtest_main gtest ${QtProtobuf_GENERATED} ${QTPROTOBUF_COMMON_NAMESPACE}::QtProtobuf ${QTPROTOBUF_COMMON_NAMESPACE}::QtGrpc Qt5::Core Qt5::Test Qt5::Network ${CMAKE_THREAD_LIBS_INIT})
+    if (${add_test_target_QML})
+        target_link_libraries(${add_test_target_TARGET} Qt5::Qml)
+    endif()
+
 endfunction(add_test_target)
 
 function(add_target_qml)

+ 2 - 1
examples/addressbook/CMakeLists.txt

@@ -11,7 +11,8 @@ file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/proto/addressbook.pro
 
 generate_qtprotobuf(TARGET ${TARGET}
     OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated
-    PROTO_FILES ${PROTO_FILES})
+    PROTO_FILES ${PROTO_FILES}
+    QML TRUE)
 
 file(GLOB SOURCES main.cpp
     addressbookengine.cpp)

+ 2 - 1
examples/simplechat/CMakeLists.txt

@@ -11,7 +11,8 @@ file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/proto/simplechat.prot
 
 generate_qtprotobuf(TARGET ${TARGET}
     OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated
-    PROTO_FILES ${PROTO_FILES})
+    PROTO_FILES ${PROTO_FILES}
+    QML TRUE)
 
 file(GLOB SOURCES main.cpp
     simplechatengine.cpp

+ 4 - 2
src/generator/CMakeLists.txt

@@ -18,7 +18,8 @@ file(GLOB SOURCES main.cpp
     protobufsourcegenerator.cpp
     clientsourcegenerator.cpp
     singlefilegenerator.cpp
-    generatorbase.cpp)
+    generatorbase.cpp
+    generatoroptions.cpp)
 
 file(GLOB HEADERS classgeneratorbase.h
     classsourcegeneratorbase.h
@@ -34,7 +35,8 @@ file(GLOB HEADERS classgeneratorbase.h
     templates.h
     utils.h
     singlefilegenerator.h
-    generatorbase.h)
+    generatorbase.h
+    generatoroptions.h)
 
 add_executable(${TARGET} ${SOURCES})
 

+ 5 - 0
src/generator/classgeneratorbase.cpp

@@ -27,6 +27,7 @@
 
 #include "templates.h"
 #include "utils.h"
+#include "generatoroptions.h"
 
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/io/zero_copy_stream.h>
@@ -120,6 +121,10 @@ void ClassGeneratorBase::printMetaTypeDeclaration()
                    Templates::DeclareMetaTypeTemplate);
     mPrinter->Print({{"classname", mClassName}, {"namespaces", mNamespacesColonDelimited}},
                    Templates::DeclareComplexListTypeTemplate);
+    if (GeneratorOptions::instance().hasQml()) {
+        mPrinter->Print({{"classname", mClassName}, {"namespaces", mNamespacesColonDelimited}},
+                       Templates::DeclareComplexQmlListTypeTemplate);
+    }
 }
 
 bool ClassGeneratorBase::isLocalMessageEnum(const google::protobuf::Descriptor *message,

+ 4 - 1
src/generator/classsourcegeneratorbase.cpp

@@ -29,6 +29,7 @@
 
 #include "templates.h"
 #include "utils.h"
+#include "generatoroptions.h"
 
 using namespace QtProtobuf::generator;
 using namespace ::google::protobuf;
@@ -53,7 +54,9 @@ void ClassSourceGeneratorBase::printClassHeaderInclude()
     std::string includeFileName = mClassName;
     utils::tolower(includeFileName);
     mPrinter->Print({{"include", includeFileName}}, Templates::InternalIncludeTemplate);
-    mPrinter->Print({{"include", "QQmlEngine"}}, Templates::ExternalIncludeTemplate);
+    if (GeneratorOptions::instance().hasQml()) {
+        mPrinter->Print({{"include", "QQmlEngine"}}, Templates::ExternalIncludeTemplate);
+    }
 }
 
 void ClassSourceGeneratorBase::printUsingNamespaces(const std::unordered_set<std::string> &namespaces)

+ 5 - 0
src/generator/generatorbase.cpp

@@ -33,6 +33,7 @@
 
 #include "utils.h"
 #include "templates.h"
+#include "generatoroptions.h"
 
 using namespace ::QtProtobuf::generator;
 using namespace ::google::protobuf;
@@ -79,6 +80,10 @@ bool GeneratorBase::GenerateAll(const std::vector<const FileDescriptor *> &files
     outfHeaderPrinter->Print(Templates::PreambleTemplate);
     outfHeaderPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
 
+    if (GeneratorOptions::instance().hasQml()) {
+        outfHeaderPrinter->Print(Templates::QmlProtobufIncludesTemplate);
+    }
+
     bool addGlobalEnumsHeader = false;
     for (auto file : files) {
         if (m_mode == SingleMode) {

+ 53 - 0
src/generator/generatoroptions.cpp

@@ -0,0 +1,53 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "generatoroptions.h"
+
+#include "utils.h"
+
+#include <iostream>
+
+static const std::string MultifileBuildOption("MULTI");
+static const std::string QmlPluginOption("QML");
+
+using namespace ::QtProtobuf::generator;
+
+GeneratorOptions::GeneratorOptions() : mIsMulti(false)
+  ,mHasQml(false)
+{
+}
+
+void GeneratorOptions::parseFromEnv(const std::string &options)
+{
+    std::vector<std::string> optionsList;
+    utils::split(options, optionsList, ':');
+    for (auto option : optionsList) {
+        if(option == MultifileBuildOption) {
+            mIsMulti = true;
+        } else if (option == QmlPluginOption) {
+            mHasQml = true;
+        }
+    }
+}

+ 51 - 0
src/generator/generatoroptions.h

@@ -0,0 +1,51 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace QtProtobuf {
+namespace generator {
+
+class GeneratorOptions
+{
+    GeneratorOptions();
+public:
+    static GeneratorOptions &instance() {
+        static GeneratorOptions _instance;
+        return _instance;
+    }
+
+    void parseFromEnv(const std::string &options);
+
+    bool isMulti() const { return mIsMulti; }
+    bool hasQml() const { return mHasQml; }
+private:
+    bool mIsMulti;
+    bool mHasQml;
+};
+
+}}

+ 9 - 3
src/generator/globalenumssourcegenerator.cpp

@@ -25,6 +25,8 @@
 
 #include "globalenumssourcegenerator.h"
 
+#include "generatoroptions.h"
+
 #include <google/protobuf/io/zero_copy_stream.h>
 
 using namespace ::QtProtobuf::generator;
@@ -44,8 +46,10 @@ GlobalEnumsSourceGenerator::GlobalEnumsSourceGenerator(const PackagesList &packa
 
 void  GlobalEnumsSourceGenerator::printHeaders() {
     mPrinter->Print("#include \"globalenums.h\"\n\n"
-                    "#include <QProtobufObject>\n\n"
-                    "#include <QQmlEngine>");
+                    "#include <QProtobufObject>\n\n");
+    if (GeneratorOptions::instance().hasQml()) {
+        mPrinter->Print("#include <QQmlEngine>");
+    }
 }
 
 void GlobalEnumsSourceGenerator::run() {
@@ -83,7 +87,9 @@ void GlobalEnumsSourceGenerator::printRegisterBody(const std::list<const FileDes
 
     mPrinter->Print(registrationProperties, Templates::ManualRegistrationGlobalEnumDefinition);
     Indent();
-    mPrinter->Print(registrationProperties, Templates::QmlRegisterTypeUncreatableTemplate);
+    if (GeneratorOptions::instance().hasQml()) {
+        mPrinter->Print(registrationProperties, Templates::QmlRegisterTypeUncreatableTemplate);
+    }
 
     for (auto file : list) {
         for (int i = 0; i < file->enum_type_count(); i++) {

+ 5 - 2
src/generator/main.cpp

@@ -27,11 +27,14 @@
 
 #include "generator.h"
 #include "singlefilegenerator.h"
+#include "generatoroptions.h"
 
+using namespace ::QtProtobuf::generator;
 int main(int argc, char *argv[])
 {
-    std::string generatorType(getenv("QT_PROTOBUF_GENERATOR_TYPE"));
-    if (generatorType == std::string("MULTI")) {
+    GeneratorOptions::instance().parseFromEnv(getenv("QT_PROTOBUF_OPTIONS"));
+    if (GeneratorOptions::instance().isMulti()) {
+        std::cerr << "Run multi generator" << std::endl;
         QtProtobuf::generator::QtGenerator generator;
         return ::google::protobuf::compiler::PluginMain(argc, argv, &generator);
     }

+ 8 - 2
src/generator/protobufclassgenerator.cpp

@@ -25,6 +25,7 @@
 
 #include "protobufclassgenerator.h"
 #include "utils.h"
+#include "generatoroptions.h"
 
 #include <iostream>
 #include <google/protobuf/descriptor.h>
@@ -160,6 +161,9 @@ void ProtobufClassGenerator::printIncludes()
     assert(mMessage != nullptr);
 
     mPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
+    if (GeneratorOptions::instance().hasQml()) {
+        mPrinter->Print(Templates::QmlProtobufIncludesTemplate);
+    }
 
     std::set<std::string> existingIncludes;
     for (int i = 0; i < mMessage->field_count(); i++) {
@@ -397,7 +401,8 @@ void ProtobufClassGenerator::printProperties()
     //Generate extra QmlListProperty that is mapped to list
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);
-        if (field->type() == FieldDescriptor::TYPE_MESSAGE && field->is_repeated() && !field->is_map()) {
+        if (field->type() == FieldDescriptor::TYPE_MESSAGE && field->is_repeated() && !field->is_map()
+                && GeneratorOptions::instance().hasQml()) {
             printField(field, Templates::QmlListPropertyTemplate);
         }
     }
@@ -427,7 +432,8 @@ void ProtobufClassGenerator::printProperties()
         printField(field, Templates::GetterTemplate);
         if (field->is_repeated()) {
             printField(field, Templates::GetterContainerExtraTemplate);
-            if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()) {
+            if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
+                    && GeneratorOptions::instance().hasQml()) {
                 printField(field, Templates::QmlListGetterTemplate);
             }
         }

+ 5 - 2
src/generator/protobufsourcegenerator.cpp

@@ -27,6 +27,7 @@
 
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/io/zero_copy_stream.h>
+#include "generatoroptions.h"
 
 using namespace QtProtobuf::generator;
 using namespace ::google::protobuf;
@@ -55,8 +56,10 @@ void ProtobufSourceGenerator::printRegisterBody()
     mPrinter->Print(registrationProperties,
                    Templates::ManualRegistrationComplexTypeDefinition);
     Indent();
-    mPrinter->Print(registrationProperties, Templates::RegisterQmlListPropertyMetaTypeTemplate);
-    mPrinter->Print(registrationProperties, Templates::QmlRegisterTypeTemplate);
+    if (GeneratorOptions::instance().hasQml()) {
+        mPrinter->Print(registrationProperties, Templates::RegisterQmlListPropertyMetaTypeTemplate);
+        mPrinter->Print(registrationProperties, Templates::QmlRegisterTypeTemplate);
+    }
 
     for (int i = 0; i < mMessage->field_count(); i++) {
         const FieldDescriptor *field = mMessage->field(i);

+ 7 - 0
src/generator/singlefilegenerator.cpp

@@ -34,6 +34,7 @@
 #include "clientgenerator.h"
 #include "clientsourcegenerator.h"
 #include "utils.h"
+#include "generatoroptions.h"
 
 #include <iostream>
 #include <set>
@@ -84,6 +85,9 @@ bool SingleFileGenerator::GenerateMessages(const ::google::protobuf::FileDescrip
     outHeaderPrinter->Print(Templates::DisclaimerTemplate);
     outHeaderPrinter->Print(Templates::PreambleTemplate);
     outHeaderPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
+    if (GeneratorOptions::instance().hasQml()) {
+        outHeaderPrinter->Print(Templates::QmlProtobufIncludesTemplate);
+    }
 
     outSourcePrinter->Print(Templates::DisclaimerTemplate);
     outSourcePrinter->Print({{"include", outFileBasename + Templates::ProtoFileSuffix}}, Templates::InternalIncludeTemplate);
@@ -189,6 +193,9 @@ bool SingleFileGenerator::GenerateServices(const ::google::protobuf::FileDescrip
     outHeaderPrinter->Print(Templates::DisclaimerTemplate);
     outHeaderPrinter->Print(Templates::PreambleTemplate);
     outHeaderPrinter->Print(Templates::DefaultProtobufIncludesTemplate);
+    if (GeneratorOptions::instance().hasQml()) {
+        outHeaderPrinter->Print(Templates::QmlProtobufIncludesTemplate);
+    }
 
     outSourcePrinter->Print(Templates::DisclaimerTemplate);
     outSourcePrinter->Print({{"include", outFileBasename + Templates::GrpcFileSuffix + Templates::ProtoFileSuffix}}, Templates::InternalIncludeTemplate);

+ 7 - 4
src/generator/templates.cpp

@@ -29,15 +29,17 @@ using namespace QtProtobuf::generator;
 
 const char *Templates::DefaultProtobufIncludesTemplate = "#include <QMetaType>\n"
                                                          "#include <QList>\n"
-                                                         "#include <QtQml/QQmlListProperty>\n"
                                                          "#include <QProtobufObject>\n"
-                                                         "#include <QQmlListPropertyConstructor>\n"
                                                          "#include <unordered_map>\n"
                                                          "#include <QSharedPointer>\n\n";
 
+const char *Templates::QmlProtobufIncludesTemplate = "#include <QtQml/QQmlListProperty>\n"
+                                                     "#include <QQmlListPropertyConstructor>\n\n";
+
 const char *Templates::GlobalEnumClassNameTemplate = "GlobalEnums";
 
 const char *Templates::DisclaimerTemplate = "/* This file is autogenerated. DO NOT CHANGE. All changes will be lost */\n\n";
+
 const char *Templates::PreambleTemplate = "#pragma once\n\n"
                                       "#include <QObject>\n";
 
@@ -171,8 +173,9 @@ const char *Templates::DeclareMetaTypeListTemplate = "Q_DECLARE_METATYPE($namesp
 const char *Templates::DeclareMessageMetaTypeTemplate = "Q_DECLARE_METATYPE($namespaces$::$classname$)\n"
                                                         "Q_DECLARE_OPAQUE_POINTER($namespaces$::$classname$)\n";
 
-const char *Templates::DeclareComplexListTypeTemplate = "Q_DECLARE_METATYPE($namespaces$::$classname$Repeated)\n"
-                                                        "Q_DECLARE_METATYPE(QQmlListProperty<$namespaces$::$classname$>)\n";
+const char *Templates::DeclareComplexListTypeTemplate = "Q_DECLARE_METATYPE($namespaces$::$classname$Repeated)\n";
+const char *Templates::DeclareComplexQmlListTypeTemplate = "Q_DECLARE_METATYPE(QQmlListProperty<$namespaces$::$classname$>)\n";
+
 const char *Templates::RegisterMetaTypeDefaultTemplate = "qRegisterMetaType<$namespaces$::$type$>();\n";
 const char *Templates::RegisterMetaTypeTemplateNoNamespace = "qRegisterMetaType<$namespaces$::$type$>(\"$type$\");\n";
 const char *Templates::RegisterMetaTypeTemplate = "qRegisterMetaType<$namespaces$::$type$>(\"$namespaces$::$type$\");\n";

+ 2 - 0
src/generator/templates.h

@@ -35,6 +35,7 @@ namespace generator {
 class Templates {
 public:
     static const char *DefaultProtobufIncludesTemplate;
+    static const char *QmlProtobufIncludesTemplate;
     static const char *GlobalEnumClassNameTemplate;
     static const char *PreambleTemplate;
     static const char *DisclaimerTemplate;
@@ -106,6 +107,7 @@ public:
     static const char *DeclareMetaTypeListTemplate;
     static const char *DeclareMessageMetaTypeTemplate;
     static const char *DeclareComplexListTypeTemplate;
+    static const char *DeclareComplexQmlListTypeTemplate;
     static const char *RegisterMetaTypeDefaultTemplate;
     static const char *RegisterMetaTypeTemplate;
     static const char *RegisterMetaTypeTemplateNoNamespace;

+ 8 - 2
src/protobuf/QtProtobufGen.cmake.in

@@ -1,6 +1,6 @@
 function(generate_qtprotobuf)
     set(options)
-    set(oneValueArgs OUT_DIR TARGET MULTI)
+    set(oneValueArgs OUT_DIR TARGET MULTI QML)
     set(multiValueArgs GENERATED_HEADERS EXCLUDE_HEADERS PROTO_FILES)
     cmake_parse_arguments(generate_qtprotobuf "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
@@ -20,6 +20,12 @@ function(generate_qtprotobuf)
         set(GENERATED_HEADERS ${GENERATED_HEADERS} globalenums.h)
     endif()
 
+    set(GENERATION_OPTIONS ${GENERATION_TYPE})
+    if(${generate_qtprotobuf_QML})
+        message(STATUS "Enabled QML generation for ${generate_qtprotobuf_TARGET}")
+        set(GENERATION_OPTIONS "${GENERATION_OPTIONS}:QML")
+    endif()
+
     find_program(GO_EXECUTABLE "go")
     foreach(PROTO_FILE IN LISTS generate_qtprotobuf_PROTO_FILES)
         get_filename_component(BASE_DIR ${PROTO_FILE} DIRECTORY)
@@ -59,7 +65,7 @@ function(generate_qtprotobuf)
 
     add_custom_command(
             OUTPUT ${QTPROTOBUF_GENERATED_SOURCES} ${QTPROTOBUF_GENERATED_HEADERS}
-            COMMAND "QT_PROTOBUF_GENERATOR_TYPE=${GENERATION_TYPE}" $<TARGET_FILE:protobuf::protoc>
+            COMMAND "QT_PROTOBUF_OPTIONS=${GENERATION_OPTIONS}" $<TARGET_FILE:protobuf::protoc>
                 --plugin=protoc-gen-@GENERATOR_TARGET@=${QTPROTOBUF_EXECUTABLE}
                 --@GENERATOR_TARGET@_out=${OUT_DIR}
                 ${PROTO_INCLUDES}

+ 2 - 1
tests/test_protobuf/CMakeLists.txt

@@ -12,7 +12,8 @@ file(GLOB SOURCES
 
 add_test_target(TARGET ${TARGET}
     EXCLUDE_HEADERS nestedsimpleintmessage.h
-    SOURCES ${SOURCES})
+    SOURCES ${SOURCES}
+    QML TRUE)
 add_target_windeployqt(TARGET ${TARGET}
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})