Browse Source

Port gRPC examples to Qt6

Alexey Edelev 3 years ago
parent
commit
cf8f65f9e3
62 changed files with 356 additions and 319 deletions
  1. 5 13
      examples/CMakeLists.txt
  2. 0 17
      examples/addressbook/CMakeLists.txt
  3. 0 26
      examples/addressbook/resources.qrc
  4. 0 33
      examples/addressbookserver/CMakeLists.txt
  5. 0 11
      examples/example_crosscompiling_toolchain.cmake
  6. 0 24
      examples/examples_common/CMakeLists.txt
  7. 0 13
      examples/examples_common/exmaples_common_global.h
  8. 8 0
      examples/grpc/CMakeLists.txt
  9. 81 0
      examples/grpc/addressbook/CMakeLists.txt
  10. 3 3
      examples/grpc/addressbook/addressbookengine.cpp
  11. 1 1
      examples/grpc/addressbook/addressbookengine.h
  12. 0 0
      examples/grpc/addressbook/images/arrow.png
  13. 0 0
      examples/grpc/addressbook/images/back.png
  14. 0 0
      examples/grpc/addressbook/images/call.png
  15. 0 0
      examples/grpc/addressbook/images/check.png
  16. 0 0
      examples/grpc/addressbook/images/drop.png
  17. 0 0
      examples/grpc/addressbook/images/minus.png
  18. 0 0
      examples/grpc/addressbook/images/plus.png
  19. 5 6
      examples/grpc/addressbook/main.cpp
  20. 0 0
      examples/grpc/addressbook/proto/addressbook.proto
  21. 1 1
      examples/grpc/addressbook/qml/AddContactView.qml
  22. 1 1
      examples/grpc/addressbook/qml/CallPopup.qml
  23. 1 1
      examples/grpc/addressbook/qml/ContactDetails.qml
  24. 0 0
      examples/grpc/addressbook/qml/ContactList.qml
  25. 0 0
      examples/grpc/addressbook/qml/CountryCodesModel.qml
  26. 0 0
      examples/grpc/addressbook/qml/DropDownColumn.qml
  27. 0 0
      examples/grpc/addressbook/qml/FloatingRoundButton.qml
  28. 0 0
      examples/grpc/addressbook/qml/InputRow.qml
  29. 3 3
      examples/grpc/addressbook/qml/PhoneInput.qml
  30. 0 0
      examples/grpc/addressbook/qml/PrimaryText.qml
  31. 0 0
      examples/grpc/addressbook/qml/SecondaryText.qml
  32. 0 0
      examples/grpc/addressbook/qml/StackItem.qml
  33. 0 0
      examples/grpc/addressbook/qml/TextInputRow.qml
  34. 0 0
      examples/grpc/addressbook/qml/TextRow.qml
  35. 1 1
      examples/grpc/addressbook/qml/main.qml
  36. 62 0
      examples/grpc/addressbookserver/CMakeLists.txt
  37. 0 3
      examples/grpc/addressbookserver/main.cpp
  38. 0 0
      examples/grpc/examples_common/universallistmodel.cpp
  39. 1 1
      examples/grpc/examples_common/universallistmodel.h
  40. 0 0
      examples/grpc/examples_common/universallistmodelbase.cpp
  41. 1 3
      examples/grpc/examples_common/universallistmodelbase.h
  42. 63 0
      examples/grpc/simplechat/CMakeLists.txt
  43. 1 0
      examples/grpc/simplechat/ChatInputField.qml
  44. 1 1
      examples/grpc/simplechat/ChatView.qml
  45. 0 0
      examples/grpc/simplechat/img/arrow.png
  46. 2 4
      examples/grpc/simplechat/main.cpp
  47. 1 1
      examples/grpc/simplechat/main.qml
  48. 0 0
      examples/grpc/simplechat/proto/simplechat.proto
  49. 5 5
      examples/grpc/simplechat/simplechatengine.cpp
  50. 0 0
      examples/grpc/simplechat/simplechatengine.h
  51. 63 0
      examples/grpc/simplechatserver/CMakeLists.txt
  52. 0 0
      examples/grpc/simplechatserver/main.cpp
  53. 0 0
      examples/grpc/ssl/cert.pem
  54. 0 0
      examples/grpc/ssl/key.pem
  55. 0 17
      examples/simplechat/CMakeLists.txt
  56. 0 8
      examples/simplechat/resources.qrc
  57. 0 28
      examples/simplechatserver/CMakeLists.txt
  58. 0 23
      examples/simplechatserver/cert.pem
  59. 0 28
      examples/simplechatserver/key.pem
  60. 42 0
      src/protobuf/cmake/Qt6ProtobufMacro.cmake
  61. 3 42
      tests/auto/test_grpc/CMakeLists.txt
  62. 1 1
      tests/auto/test_grpc/echoserver/CMakeLists.txt

+ 5 - 13
examples/CMakeLists.txt

@@ -1,16 +1,8 @@
-if(WrapgRPC_FOUND)
-    include(QtProtobufTestHelpers)
-    add_subdirectory("examples_common")
+qt_examples_build_begin(EXTERNAL_BUILD)
 
-    add_subdirectory("addressbook")
-    add_subdirectory("addressbookserver")
-    configure_file(client_server_driver.sh.in addressbook_driver.sh @ONLY)
+# gRPC tests require reference gRPC and protobuf implementation
+add_subdirectory(grpc)
 
-    add_subdirectory("simplechat")
-    add_subdirectory("simplechatserver")
-    configure_file(client_server_driver.sh.in simplechat_driver.sh @ONLY)
+# add_subdirectory("clienttutorial")
 
-    add_subdirectory("clienttutorial")
-else()
-    message(WARNING "gRPC not found: disable examples")
-endif()
+qt_examples_build_end()

+ 0 - 17
examples/addressbook/CMakeLists.txt

@@ -1,17 +0,0 @@
-set(TARGET addressbook)
-
-qt_protobuf_internal_find_dependencies()
-
-qt_protobuf_internal_add_example(TARGET ${TARGET}
-                   PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/proto/addressbook.proto"
-                   SOURCES main.cpp
-                           addressbookengine.cpp
-                   RESOURCES resources.qrc
-                   QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
-
-add_custom_command(TARGET ${TARGET}
-    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/../addressbookserver/cert.pem"
-            "$<TARGET_FILE_DIR:${TARGET}>"
-)
-
-set(CLIENT_EXEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} PARENT_SCOPE)

+ 0 - 26
examples/addressbook/resources.qrc

@@ -1,26 +0,0 @@
-<RCC>
-    <qresource prefix="/">
-        <file>qml/main.qml</file>
-        <file>qml/ContactList.qml</file>
-        <file>qml/AddContactView.qml</file>
-        <file>qml/FloatingRoundButton.qml</file>
-        <file>images/plus.png</file>
-        <file>qml/StackItem.qml</file>
-        <file>images/back.png</file>
-        <file>qml/PrimaryText.qml</file>
-        <file>qml/SecondaryText.qml</file>
-        <file>qml/TextInputRow.qml</file>
-        <file>images/check.png</file>
-        <file>images/minus.png</file>
-        <file>qml/DropDownColumn.qml</file>
-        <file>images/arrow.png</file>
-        <file>qml/CountryCodesModel.qml</file>
-        <file>qml/InputRow.qml</file>
-        <file>qml/PhoneInput.qml</file>
-        <file>qml/ContactDetails.qml</file>
-        <file>qml/TextRow.qml</file>
-        <file>images/call.png</file>
-        <file>images/drop.png</file>
-        <file>qml/CallPopup.qml</file>
-    </qresource>
-</RCC>

+ 0 - 33
examples/addressbookserver/CMakeLists.txt

@@ -1,33 +0,0 @@
-set(TARGET addressbookserver)
-
-set(GENERATED_SOURCES
-    ${CMAKE_CURRENT_BINARY_DIR}/addressbook.pb.cc
-    ${CMAKE_CURRENT_BINARY_DIR}/addressbook.grpc.pb.cc)
-set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
-
-add_executable(${TARGET} main.cpp ${GENERATED_SOURCES})
-target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-
-if(UNIX)
-    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
-        # using GCC
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=array-bounds")
-    endif()
-endif()
-
-file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../addressbook/proto/*.proto)
-qt_protobuf_internal_protobuf_generate_all(TARGET ${TARGET}
-    GENERATED_SOURCES ${GENERATED_SOURCES}
-    PROTO_FILES ${PROTO_FILES})
-
-target_link_libraries(${TARGET} PRIVATE protobuf::libprotobuf gRPC::grpc++ gRPC::grpc)
-if(MSVC)
-   target_compile_definitions(${TARGET} PRIVATE _WIN32_WINNT=0x600 _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS)
-endif()
-add_custom_command(TARGET ${TARGET}
-    COMMAND ${CMAKE_COMMAND} -E copy
-            "${CMAKE_CURRENT_SOURCE_DIR}/cert.pem"
-            "${CMAKE_CURRENT_SOURCE_DIR}/key.pem"
-            "$<TARGET_FILE_DIR:${TARGET}>"
-)
-set(SERVER_EXEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} PARENT_SCOPE)

+ 0 - 11
examples/example_crosscompiling_toolchain.cmake

@@ -1,11 +0,0 @@
-set(CMAKE_SYSTEM_NAME Linux)
-
-set(CMAKE_SYSROOT /usr/armv7a-hardfloat-linux-gnueabi/)
-
-set(CMAKE_C_COMPILER /usr/bin/armv7a-hardfloat-linux-gnueabi-gcc)
-set(CMAKE_CXX_COMPILER /usr/bin/armv7a-hardfloat-linux-gnueabi-g++)
-
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) 

+ 0 - 24
examples/examples_common/CMakeLists.txt

@@ -1,24 +0,0 @@
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-
-find_package(Qt6 COMPONENTS Core CONFIG REQUIRED)
-
-file(GLOB HEADERS
-    universallistmodelbase.h
-    universallistmodel.h
-    exmaples_common_global.h
-)
-
-file(GLOB SOURCES
-    universallistmodelbase.cpp
-    universallistmodel.cpp
-)
-
-# headers added to make them visible in IDE
-add_library(examples_common ${SOURCES} ${HEADERS})
-
-target_compile_definitions(examples_common PRIVATE EXAMPLES_COMMON_LIB)
-
-target_include_directories(examples_common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(examples_common Qt6::Core)

+ 0 - 13
examples/examples_common/exmaples_common_global.h

@@ -1,13 +0,0 @@
-#pragma once
-
-#include <QtCore/QtGlobal>
-
-#ifndef QT_PROTOBUF_STATIC
-    #ifdef EXAMPLES_COMMON_LIB
-        #define UNVERSALLISTMODEL_EXPORT Q_DECL_EXPORT
-    #else
-        #define UNVERSALLISTMODEL_EXPORT Q_DECL_IMPORT
-    #endif
-#else
-    #define UNVERSALLISTMODEL_EXPORT
-#endif

+ 8 - 0
examples/grpc/CMakeLists.txt

@@ -0,0 +1,8 @@
+# TODO Qt6: Not tested on embedded platforms. Perhaps servers need to be build for the host only and
+# run on host. Clients need to use a host-based IP address provided by the emulator.
+qt_internal_add_example(addressbook)
+qt_internal_add_example(simplechat)
+if(NOT CMAKE_CROSSCOMPILING)
+    qt_internal_add_example(addressbookserver)
+    qt_internal_add_example(simplechatserver)
+endif()

+ 81 - 0
examples/grpc/addressbook/CMakeLists.txt

@@ -0,0 +1,81 @@
+cmake_minimum_required(VERSION 3.16)
+project(grpcaddressbook LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+    set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/grpc/addressbook")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Quick Protobuf Grpc)
+
+qt_add_executable(grpcaddressbook
+    main.cpp
+    addressbookengine.cpp addressbookengine.h
+    ../examples_common/universallistmodel.cpp ../examples_common/universallistmodel.h
+    ../examples_common/universallistmodelbase.cpp ../examples_common/universallistmodel.h
+)
+
+target_include_directories(grpcaddressbook PRIVATE ../examples_common)
+
+target_link_libraries(grpcaddressbook PRIVATE
+    Qt::Core
+    Qt::Quick
+    Qt::Protobuf
+    Qt::Grpc
+    Qt::Quick
+)
+
+qt_add_qml_module(grpcaddressbook
+    URI examples.grpc.addressbook
+    VERSION 1.0
+    QML_FILES
+        qml/AddContactView.qml
+        qml/CallPopup.qml
+        qml/ContactDetails.qml
+        qml/ContactList.qml
+        qml/CountryCodesModel.qml
+        qml/DropDownColumn.qml
+        qml/FloatingRoundButton.qml
+        qml/InputRow.qml
+        qml/main.qml
+        qml/PhoneInput.qml
+        qml/PrimaryText.qml
+        qml/SecondaryText.qml
+        qml/StackItem.qml
+        qml/TextInputRow.qml
+        qml/TextRow.qml
+    RESOURCES
+        images/arrow.png
+        images/back.png
+        images/call.png
+        images/check.png
+        images/drop.png
+        images/minus.png
+        images/plus.png
+    NO_RESOURCE_TARGET_PATH
+)
+
+qt_protobuf_generate(TARGET grpcaddressbook
+    PROTO_FILES
+        proto/addressbook.proto
+    QML
+)
+
+install(TARGETS grpcaddressbook
+    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
+
+add_custom_command(TARGET grpcaddressbook
+    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+         "$<TARGET_FILE_DIR:grpcaddressbook>"
+)
+
+install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+        DESTINATION "${INSTALL_EXAMPLEDIR}"
+)

+ 3 - 3
examples/addressbook/addressbookengine.cpp → examples/grpc/addressbook/addressbookengine.cpp

@@ -53,11 +53,11 @@ AddressBookEngine::AddressBookEngine() : QObject()
     conf.setProtocol(QSsl::TlsV1_2);
     conf.setAllowedNextProtocols({QSslConfiguration::ALPNProtocolHTTP2});
 
-    std::shared_ptr<QtProtobuf::QAbstractGrpcChannel> channel(new QtProtobuf::QGrpcHttp2Channel(QUrl("https://localhost:65001"), QtProtobuf::QGrpcSslCredentials(conf) |
-                                                                                      QtProtobuf::QGrpcUserPasswordCredentials<>("authorizedUser", QCryptographicHash::hash("test", QCryptographicHash::Md5).toHex())));
+    std::shared_ptr<QAbstractGrpcChannel> channel(new QGrpcHttp2Channel(QUrl("https://localhost:65001"), QGrpcSslCredentials(conf) |
+                                                                                      QGrpcUserPasswordCredentials<>("authorizedUser", QCryptographicHash::hash("test", QCryptographicHash::Md5).toHex())));
     m_client->attachChannel(channel);
     auto stream = m_client->streamContacts(ListFrame());
-    connect(stream.get(), &QtProtobuf::QGrpcStream::messageReceived, this, [this, stream]() {
+    connect(stream.get(), &QGrpcStream::messageReceived, this, [this, stream]() {
         m_contacts->reset(stream->read<Contacts>().list());
     });
     m_client->streamCallStatus(qtprotobuf::examples::None(), QPointer<CallStatus>(&m_callStatus));

+ 1 - 1
examples/addressbook/addressbookengine.h → examples/grpc/addressbook/addressbookengine.h

@@ -28,7 +28,7 @@
 #include <QObject>
 #include "addressbook.qpb.h"
 
-#include "universallistmodel.h"
+#include <universallistmodel.h>
 
 namespace qtprotobuf { namespace examples {
 class AddressBookClient;

+ 0 - 0
examples/addressbook/images/arrow.png → examples/grpc/addressbook/images/arrow.png


+ 0 - 0
examples/addressbook/images/back.png → examples/grpc/addressbook/images/back.png


+ 0 - 0
examples/addressbook/images/call.png → examples/grpc/addressbook/images/call.png


+ 0 - 0
examples/addressbook/images/check.png → examples/grpc/addressbook/images/check.png


+ 0 - 0
examples/addressbook/images/drop.png → examples/grpc/addressbook/images/drop.png


+ 0 - 0
examples/addressbook/images/minus.png → examples/grpc/addressbook/images/minus.png


+ 0 - 0
examples/addressbook/images/plus.png → examples/grpc/addressbook/images/plus.png


+ 5 - 6
examples/addressbook/main.cpp → examples/grpc/addressbook/main.cpp

@@ -34,6 +34,8 @@
 
 #include <QMetaProperty>
 #include <QQmlPropertyMap>
+#include <QDir>
+#include <QDebug>
 
 using namespace qtprotobuf::examples;
 
@@ -41,17 +43,14 @@ int main(int argc, char *argv[])
 {
     qRegisterProtobufTypes();
 
-    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
-
-    qmlRegisterType<ContactsListModel>("examples.addressbook", 1, 0, "ContactsListModel");
-    QGuiApplication app(argc, argv);
-
-    qmlRegisterSingletonType<AddressBookEngine>("examples.addressbook", 1, 0, "AddressBookEngine", [](QQmlEngine *engine, QJSEngine *) -> QObject *{
+    qmlRegisterType<ContactsListModel>("examples.grpc.addressbook", 1, 0, "ContactsListModel");
+    qmlRegisterSingletonType<AddressBookEngine>("examples.grpc.addressbook", 1, 0, "AddressBookEngine", [](QQmlEngine *engine, QJSEngine *) -> QObject *{
         static AddressBookEngine abEngine;
         engine->setObjectOwnership(&abEngine, QQmlEngine::CppOwnership);
         return &abEngine;
     });
 
+    QGuiApplication app(argc, argv);
     QQmlApplicationEngine engine;
 
     engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));

+ 0 - 0
examples/addressbook/proto/addressbook.proto → examples/grpc/addressbook/proto/addressbook.proto


+ 1 - 1
examples/addressbook/qml/AddContactView.qml → examples/grpc/addressbook/qml/AddContactView.qml

@@ -27,7 +27,7 @@ import QtQuick 2.9
 import QtQuick.Controls 2.4
 
 import qtprotobuf.examples 1.0
-import examples.addressbook 1.0
+import examples.grpc.addressbook 1.0
 
 StackItem {
     id: root

+ 1 - 1
examples/addressbook/qml/CallPopup.qml → examples/grpc/addressbook/qml/CallPopup.qml

@@ -27,7 +27,7 @@ import QtQuick 2.9
 import QtQuick.Controls 2.4
 
 import qtprotobuf.examples 1.0
-import examples.addressbook 1.0
+import examples.grpc.addressbook 1.0
 
 Rectangle {
     id: root

+ 1 - 1
examples/addressbook/qml/ContactDetails.qml → examples/grpc/addressbook/qml/ContactDetails.qml

@@ -27,7 +27,7 @@ import QtQuick 2.9
 import QtQuick.Controls 2.4
 
 import qtprotobuf.examples 1.0
-import examples.addressbook 1.0
+import examples.grpc.addressbook 1.0
 
 StackItem {
     id: root

+ 0 - 0
examples/addressbook/qml/ContactList.qml → examples/grpc/addressbook/qml/ContactList.qml


+ 0 - 0
examples/addressbook/qml/CountryCodesModel.qml → examples/grpc/addressbook/qml/CountryCodesModel.qml


+ 0 - 0
examples/addressbook/qml/DropDownColumn.qml → examples/grpc/addressbook/qml/DropDownColumn.qml


+ 0 - 0
examples/addressbook/qml/FloatingRoundButton.qml → examples/grpc/addressbook/qml/FloatingRoundButton.qml


+ 0 - 0
examples/addressbook/qml/InputRow.qml → examples/grpc/addressbook/qml/InputRow.qml


+ 3 - 3
examples/addressbook/qml/PhoneInput.qml → examples/grpc/addressbook/qml/PhoneInput.qml

@@ -73,9 +73,9 @@ InputRow {
             Layout.alignment: Qt.AlignBottom
             font.pointSize: 12
             color: "#ffffff"
-            validator: RegExpValidator {
-                regExp:/\d*/
-            }
+//            validator: RegularExpressionValidator {
+//                regExp:/\d*/
+//            }
             Rectangle {
                 anchors.top: _inputItem.bottom
                 width: _inputItem.width

+ 0 - 0
examples/addressbook/qml/PrimaryText.qml → examples/grpc/addressbook/qml/PrimaryText.qml


+ 0 - 0
examples/addressbook/qml/SecondaryText.qml → examples/grpc/addressbook/qml/SecondaryText.qml


+ 0 - 0
examples/addressbook/qml/StackItem.qml → examples/grpc/addressbook/qml/StackItem.qml


+ 0 - 0
examples/addressbook/qml/TextInputRow.qml → examples/grpc/addressbook/qml/TextInputRow.qml


+ 0 - 0
examples/addressbook/qml/TextRow.qml → examples/grpc/addressbook/qml/TextRow.qml


+ 1 - 1
examples/addressbook/qml/main.qml → examples/grpc/addressbook/qml/main.qml

@@ -27,7 +27,7 @@ import QtQuick 2.9
 import QtQuick.Controls 2.4
 
 import qtprotobuf.examples 1.0
-import examples.addressbook 1.0
+import examples.grpc.addressbook 1.0
 
 ApplicationWindow {
     id: mainWindow

+ 62 - 0
examples/grpc/addressbookserver/CMakeLists.txt

@@ -0,0 +1,62 @@
+cmake_minimum_required(VERSION 3.16)
+project(grpcaddressbookserver LANGUAGES CXX)
+
+find_package(gRPC CONFIG QUIET)
+find_package(Protobuf CONFIG QUIET)
+
+# gRPC servers require reference gRPC and protobuf implementation
+if(NOT TARGET gRPC::grpc_cpp_plugin
+    OR NOT TARGET gRPC::grpc++
+    OR NOT TARGET protobuf::libprotobuf
+    OR NOT TARGET protobuf::protoc)
+    message(AUTOR_WARNING "gRPC is not found. The ${PROJECT_NAME} example won't be built.")
+    return ()
+endif()
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+    set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/grpc/addressbookserver")
+
+set(generated_sources
+    ${CMAKE_CURRENT_BINARY_DIR}/addressbook.pb.cc
+    ${CMAKE_CURRENT_BINARY_DIR}/addressbook.grpc.pb.cc)
+set_source_files_properties(${generated_sources} PROPERTIES GENERATED TRUE)
+
+qt_add_executable(grpcaddressbookserver main.cpp ${generated_sources})
+target_include_directories(grpcaddressbookserver PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+
+_qt_internal_protobuf_reference_generate(TARGET grpcaddressbookserver
+    GENERATED_SOURCES ${generated_sources}
+    PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../addressbook/proto/addressbook.proto")
+
+target_link_libraries(grpcaddressbookserver PRIVATE protobuf::libprotobuf gRPC::grpc++ gRPC::grpc)
+if(MSVC)
+    target_compile_definitions(grpcaddressbookserver PRIVATE _WIN32_WINNT=0x600 _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS)
+endif()
+if(UNIX AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    target_compile_options(grpcaddressbookserver PRIVATE -Wno-error=array-bounds)
+endif()
+
+install(TARGETS grpcaddressbookserver
+    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
+
+add_custom_command(TARGET grpcaddressbookserver
+    COMMAND ${CMAKE_COMMAND} -E copy
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/key.pem"
+            "$<TARGET_FILE_DIR:grpcaddressbookserver>"
+)
+
+install(FILES
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/key.pem"
+        DESTINATION "${INSTALL_EXAMPLEDIR}"
+)

+ 0 - 3
examples/addressbookserver/main.cpp → examples/grpc/addressbookserver/main.cpp

@@ -30,9 +30,6 @@ public:
         contact->set_firstname("John");
         contact->set_lastname("McClane");
         contact = m_contacts.add_list();
-        contact->set_firstname("Alexey");
-        contact->set_lastname("Edelev");
-        contact = m_contacts.add_list();
         contact->set_firstname("Ebenezer");
         contact->set_lastname("Scrooge");
         Job *job = new Job;

+ 0 - 0
examples/examples_common/universallistmodel.cpp → examples/grpc/examples_common/universallistmodel.cpp


+ 1 - 1
examples/examples_common/universallistmodel.h → examples/grpc/examples_common/universallistmodel.h

@@ -1,6 +1,6 @@
 #pragma once
 
-#include <universallistmodelbase.h>
+#include "universallistmodelbase.h"
 
 #include <QObject>
 #include <QList>

+ 0 - 0
examples/examples_common/universallistmodelbase.cpp → examples/grpc/examples_common/universallistmodelbase.cpp


+ 1 - 3
examples/examples_common/universallistmodelbase.h → examples/grpc/examples_common/universallistmodelbase.h

@@ -1,13 +1,11 @@
 #pragma once
 
-#include <exmaples_common_global.h>
-
 #include <QAbstractListModel>
 /*!
  * \brief The UniversalListModelBase class to make possible properties definition for UniversalListModel
  * This class should not be used as is, but leaves this possibility.
  */
-class UNVERSALLISTMODEL_EXPORT UniversalListModelBase : public QAbstractListModel
+class  UniversalListModelBase : public QAbstractListModel
 {
     Q_OBJECT
     Q_PROPERTY(int count READ count NOTIFY countChanged)

+ 63 - 0
examples/grpc/simplechat/CMakeLists.txt

@@ -0,0 +1,63 @@
+cmake_minimum_required(VERSION 3.16)
+project(grpcsimplechat LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+    set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/grpc/grpcsimplechat")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Quick Protobuf Grpc)
+
+qt_add_executable(grpcsimplechat
+    main.cpp
+    simplechatengine.cpp simplechatengine.h
+    ../examples_common/universallistmodel.cpp ../examples_common/universallistmodel.h
+    ../examples_common/universallistmodelbase.cpp ../examples_common/universallistmodel.h
+)
+
+target_include_directories(grpcsimplechat PRIVATE ../examples_common)
+
+target_link_libraries(grpcsimplechat PRIVATE
+    Qt::Core
+    Qt::Quick
+    Qt::Protobuf
+    Qt::Grpc
+    Qt::Quick
+)
+
+qt_add_qml_module(grpcsimplechat
+    URI examples.grpc.simplechat
+    VERSION 1.0
+    QML_FILES
+        ChatInputField.qml
+        ChatView.qml
+        main.qml
+    RESOURCES
+        img/arrow.png
+    NO_RESOURCE_TARGET_PATH
+)
+
+qt_protobuf_generate(TARGET grpcsimplechat
+    PROTO_FILES
+        proto/simplechat.proto
+    QML
+)
+
+install(TARGETS grpcsimplechat
+    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
+
+add_custom_command(TARGET grpcsimplechat
+    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+         "$<TARGET_FILE_DIR:grpcsimplechat>"
+)
+
+install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+        DESTINATION "${INSTALL_EXAMPLEDIR}"
+)

+ 1 - 0
examples/simplechat/ChatInputField.qml → examples/grpc/simplechat/ChatInputField.qml

@@ -1,5 +1,6 @@
 import QtQuick 2.9
 import QtQuick.Controls 2.4
+
 TextField {
     id: _inputField
     width: 200

+ 1 - 1
examples/simplechat/ChatView.qml → examples/grpc/simplechat/ChatView.qml

@@ -1,5 +1,5 @@
 import QtQuick 2.4
-import examples.simplechat 1.0
+import examples.grpc.simplechat 1.0
 import qtprotobuf.examples 1.0
 
 Rectangle {

+ 0 - 0
examples/simplechat/img/arrow.png → examples/grpc/simplechat/img/arrow.png


+ 2 - 4
examples/simplechat/main.cpp → examples/grpc/simplechat/main.cpp

@@ -45,10 +45,8 @@ int main(int argc, char *argv[])
 
     QGuiApplication app(argc, argv);
 
-    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
-
-    qmlRegisterUncreatableType<ChatMessageModel>("examples.simplechat",  1, 0, "ChatMessageModel", "");
-    qmlRegisterSingletonType<SimpleChatEngine>("examples.simplechat", 1, 0, "SimpleChatEngine", [](QQmlEngine *engine, QJSEngine *) -> QObject *{
+    qmlRegisterUncreatableType<ChatMessageModel>("examples.grpc.simplechat",  1, 0, "ChatMessageModel", "");
+    qmlRegisterSingletonType<SimpleChatEngine>("examples.grpc.simplechat", 1, 0, "SimpleChatEngine", [](QQmlEngine *engine, QJSEngine *) -> QObject *{
         static SimpleChatEngine scEngine;
         engine->setObjectOwnership(&scEngine, QQmlEngine::CppOwnership);
         return &scEngine;

+ 1 - 1
examples/simplechat/main.qml → examples/grpc/simplechat/main.qml

@@ -27,7 +27,7 @@ import QtQuick 2.9
 import QtQuick.Controls 2.4
 import QtGraphicalEffects 1.0
 
-import examples.simplechat 1.0
+import examples.grpc.simplechat 1.0
 
 ApplicationWindow {
     id: mainWindow

+ 0 - 0
examples/simplechat/proto/simplechat.proto → examples/grpc/simplechat/proto/simplechat.proto


+ 5 - 5
examples/simplechat/simplechatengine.cpp → examples/grpc/simplechat/simplechatengine.cpp

@@ -69,16 +69,16 @@ void SimpleChatEngine::login(const QString &name, const QString &password)
     conf.setAllowedNextProtocols({QSslConfiguration::ALPNProtocolHTTP2});
 
     QUrl url("https://localhost:65002");
-    std::shared_ptr<QtProtobuf::QAbstractGrpcChannel> channel(new QtProtobuf::QGrpcHttp2Channel(url, QtProtobuf::QGrpcSslCredentials(conf) |
-                                                                                      QtProtobuf::QGrpcUserPasswordCredentials<>(name, QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex())));
+    std::shared_ptr<QAbstractGrpcChannel> channel(new QGrpcHttp2Channel(url, QGrpcSslCredentials(conf) |
+                                                                                      QGrpcUserPasswordCredentials<>(name, QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex())));
 
     m_client->attachChannel(channel);
-    QtProtobuf::QGrpcStreamShared stream = m_client->streamMessageList(None());
-    QObject::connect(stream.get(), &QtProtobuf::QGrpcStream::error, this, [stream] {
+    QGrpcStreamShared stream = m_client->streamMessageList(None());
+    QObject::connect(stream.get(), &QGrpcStream::error, this, [stream] {
         qCritical() << "Stream error, cancel";
         stream->abort();
     });
-    QObject::connect(stream.get(), &QtProtobuf::QGrpcStream::messageReceived, this, [this, name, stream]() {
+    QObject::connect(stream.get(), &QGrpcStream::messageReceived, this, [this, name, stream]() {
         if (m_userName != name) {
             m_userName = name;
             userNameChanged();

+ 0 - 0
examples/simplechat/simplechatengine.h → examples/grpc/simplechat/simplechatengine.h


+ 63 - 0
examples/grpc/simplechatserver/CMakeLists.txt

@@ -0,0 +1,63 @@
+cmake_minimum_required(VERSION 3.16)
+project(grpcsimplechatserver LANGUAGES CXX)
+
+find_package(gRPC CONFIG QUIET)
+find_package(Protobuf CONFIG QUIET)
+
+# gRPC servers require reference gRPC and protobuf implementation
+if(NOT TARGET gRPC::grpc_cpp_plugin
+    OR NOT TARGET gRPC::grpc++
+    OR NOT TARGET protobuf::libprotobuf
+    OR NOT TARGET protobuf::protoc)
+    message(AUTOR_WARNING "gRPC is not found. The ${PROJECT_NAME} example won't be built.")
+    return ()
+endif()
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+    set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/grpc/simplechatserver")
+
+set(generated_sources
+    "${CMAKE_CURRENT_BINARY_DIR}/simplechat.pb.cc"
+    "${CMAKE_CURRENT_BINARY_DIR}/simplechat.grpc.pb.cc"
+)
+set_source_files_properties(${generated_sources} PROPERTIES GENERATED TRUE)
+
+qt_add_executable(grpcsimplechatserver main.cpp ${generated_sources})
+target_include_directories(grpcsimplechatserver PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+
+_qt_internal_protobuf_reference_generate(TARGET grpcsimplechatserver
+    GENERATED_SOURCES ${generated_sources}
+    PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../simplechat/proto/simplechat.proto")
+
+target_link_libraries(grpcsimplechatserver PRIVATE protobuf::libprotobuf gRPC::grpc++ gRPC::grpc)
+if(MSVC)
+    target_compile_definitions(grpcsimplechatserver PRIVATE _WIN32_WINNT=0x600 _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS)
+endif()
+if(UNIX AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    target_compile_options(grpcsimplechatserver PRIVATE -Wno-error=array-bounds)
+endif()
+
+install(TARGETS grpcsimplechatserver
+    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
+
+add_custom_command(TARGET grpcsimplechatserver
+    COMMAND ${CMAKE_COMMAND} -E copy
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/key.pem"
+            "$<TARGET_FILE_DIR:grpcsimplechatserver>"
+)
+
+install(FILES
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/cert.pem"
+            "${CMAKE_CURRENT_SOURCE_DIR}/../ssl/key.pem"
+        DESTINATION "${INSTALL_EXAMPLEDIR}"
+)

+ 0 - 0
examples/simplechatserver/main.cpp → examples/grpc/simplechatserver/main.cpp


+ 0 - 0
examples/addressbookserver/cert.pem → examples/grpc/ssl/cert.pem


+ 0 - 0
examples/addressbookserver/key.pem → examples/grpc/ssl/key.pem


+ 0 - 17
examples/simplechat/CMakeLists.txt

@@ -1,17 +0,0 @@
-set(TARGET simplechat)
-
-qt_protobuf_internal_find_dependencies()
-
-qt_protobuf_internal_add_example(TARGET ${TARGET}
-                   PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/proto/simplechat.proto"
-                   SOURCES main.cpp
-                           simplechatengine.cpp
-                   RESOURCES resources.qrc
-                   QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-
-add_custom_command(TARGET ${TARGET}
-    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/../addressbookserver/cert.pem"
-            "$<TARGET_FILE_DIR:${TARGET}>"
-)
-
-set(CLIENT_EXEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} PARENT_SCOPE)

+ 0 - 8
examples/simplechat/resources.qrc

@@ -1,8 +0,0 @@
-<RCC>
-    <qresource prefix="/">
-        <file>main.qml</file>
-        <file>img/arrow.png</file>
-        <file>ChatInputField.qml</file>
-        <file>ChatView.qml</file>
-    </qresource>
-</RCC>

+ 0 - 28
examples/simplechatserver/CMakeLists.txt

@@ -1,28 +0,0 @@
-set(TARGET simplechatserver)
-
-set(GENERATED_SOURCES
-    ${CMAKE_CURRENT_BINARY_DIR}/simplechat.pb.cc
-    ${CMAKE_CURRENT_BINARY_DIR}/simplechat.grpc.pb.cc)
-set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
-
-add_executable(${TARGET} main.cpp ${GENERATED_SOURCES})
-target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-
-if(UNIX)
-    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
-        # using GCC
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=array-bounds")
-    endif()
-endif()
-
-file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../simplechat/proto/*.proto)
-qt_protobuf_internal_protobuf_generate_all(TARGET ${TARGET}
-    GENERATED_SOURCES ${GENERATED_SOURCES}
-    PROTO_FILES ${PROTO_FILES})
-
-target_link_libraries(${TARGET} PRIVATE protobuf::libprotobuf gRPC::grpc++ gRPC::grpc)
-if(MSVC)
-   target_compile_definitions(${TARGET} PRIVATE _WIN32_WINNT=0x600 _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS)
-endif()
-file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cert.pem ${CMAKE_CURRENT_SOURCE_DIR}/key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-set(SERVER_EXEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} PARENT_SCOPE)

+ 0 - 23
examples/simplechatserver/cert.pem

@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID1zCCAr+gAwIBAgIUW685KAdBXhPGRm3tHMoGgnRHxTMwDQYJKoZIhvcNAQEL
-BQAwezELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVy
-bGluMRMwEQYDVQQKDApRdFByb3RvYnVmMRIwEAYDVQQDDAlsb2NhbGhvc3QxITAf
-BgkqhkiG9w0BCQEWEnNlbWxhbmlrQGdtYWlsLmNvbTAeFw0yMDA2MjgxNzUxNDha
-Fw0zMDA2MjYxNzUxNDhaMHsxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4x
-DzANBgNVBAcMBkJlcmxpbjETMBEGA1UECgwKUXRQcm90b2J1ZjESMBAGA1UEAwwJ
-bG9jYWxob3N0MSEwHwYJKoZIhvcNAQkBFhJzZW1sYW5pa0BnbWFpbC5jb20wggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqBiZjOX/AhOvQzc0pK+jvgOnZ
-GdhrdS7/FaSUizF9JmwrixyOQqUaRb/uhbPvZ9SYHUsbm6yQ343kWB+ID+FUwZyj
-JneAaz+gfColC9hligEyTRMGBnEVI0d2vfJGFJJ8ewW4L4CJPN33icYn32YB6tij
-T5cesOrghlJjzgZcFj/eHdbuGHnjDegtYcjuooomahBfPVj5XhxykeAsyETpN9QC
-RkfqQ1cW8EUxcP697eELoFVi4VmAOTOS4rtk9IbgaOQ31Tp2jdvJkvrbp3elpmhG
-obpgkjtWpXWJj+CT2vLEoyXr/56CfLxnJZX2geeG538TWck72OoehzllmP11AgMB
-AAGjUzBRMB0GA1UdDgQWBBTzodlJrNWT66criqfGb9YV5l0YNDAfBgNVHSMEGDAW
-gBTzodlJrNWT66criqfGb9YV5l0YNDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
-DQEBCwUAA4IBAQBdOlaWDmJsQX22ZYI5LbkyRtDNBLI28i6jPODfB0aZW8E0MlYs
-7AiGIOKCCe8wV/OsE822DwECSAdPUzuXjkDgxTegZ5JsJq2RpYn+BnkEV01GYcrA
-2funOMTtf1jFrKbWq9ERhBjtqPBaovG9FpPYxD40Zq4PmAraA+fMNUnd2/C1lAPB
-Nnb5160p69YtihseVEDUPaHlmnmImO4n9UBrhzuupMglJZZctask+8Zgwt8LbFWd
-2uJdn6uK0JgS2N4ndAvIxnYuieV9V/jcUsYY+MABBvIbT7Etl+h8XVLru1IluXHf
-qAfO52sje4L8lYruakWTCx9AoqN6s+dHv621
------END CERTIFICATE-----

+ 0 - 28
examples/simplechatserver/key.pem

@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqBiZjOX/AhOvQ
-zc0pK+jvgOnZGdhrdS7/FaSUizF9JmwrixyOQqUaRb/uhbPvZ9SYHUsbm6yQ343k
-WB+ID+FUwZyjJneAaz+gfColC9hligEyTRMGBnEVI0d2vfJGFJJ8ewW4L4CJPN33
-icYn32YB6tijT5cesOrghlJjzgZcFj/eHdbuGHnjDegtYcjuooomahBfPVj5Xhxy
-keAsyETpN9QCRkfqQ1cW8EUxcP697eELoFVi4VmAOTOS4rtk9IbgaOQ31Tp2jdvJ
-kvrbp3elpmhGobpgkjtWpXWJj+CT2vLEoyXr/56CfLxnJZX2geeG538TWck72Ooe
-hzllmP11AgMBAAECggEAQkrtksirkBQDokFsGf5970xzYWvbX2KsdVcp+aUgIazm
-hj/SXYGMwGarxEOredAhK0JYs6YKLd6Mg5j8il+uuw5WlaJ8+7xVbayb/h/VOxoJ
-B2TX4wSF+Pjtd1Xubfa9ev24qC0VT+1EmqzEb22CZ4L6/wocYSIYIn0dCL8e6a48
-etN5MYlt5RNISeNYNn4Xjz4eZXdcKHlP+25F94AgJyZAbDLd10krT/kY4+ybzGVD
-F4Gysfk+OYuE/Bd3vugxaxQF+IN/VIyIP4NaX3aHe2LsLZp8Xvdd8wi12pUoPHEb
-c4FAPjfgFZlwScPmjX7pkV1Ta0dBg6iTXkf8CGuhYQKBgQDTCSCFiQMb+wF5Argg
-ta5sUkWJOnA83KADhOXULQZkw/NVkxZ0qdSPRS7EPWYQ7/XyCVtG2kayOdiwAu5H
-SvQ8A+XZMXmYa00Awc7cVVKQ+wuTdnwoQax2nPuuPBxUM+I1TvtV9+afQgZsR9zM
-i0MvxYwsMjr1n1L79FDAxjbAyQKBgQDOQA56sMlF1lMCmwrvSNmG9VY7ltU/nn7/
-OUnQAtyywm6bAJSzM4n5eBZPj/lW4y/U1Ud9PXoPxNTsHkBqI7g3g10iCq5i8Ajl
-Fp4KXAuEUROOq0W9dzt6BirENsUFDOpsw+wUhlMuTa5jFcFDyiUCjMLgQ03OD+Ti
-Z5yqaPJ5TQKBgG3A/Wz1iOxwap+ozmIUmxYy438vKVg91ep+n5jtobmeP1tuF+us
-t6Obc2sUE5UTd3Hdc98xfjsK4qsHmyzwyny7+jovBPJEO9P897yXk01bgvW6VXAK
-V8uIcUx4brNMGIVpAkX/m62QBQ8jgK3Qb6zUrMX/ibJcnifzNFxNugQhAoGAGm97
-a55dLeZanWrh6+maeAHaG6kpjA30mSHupAq53u+s3ZElfhKNDLynn2sEum5EIzNz
-Bkpq6rp/0APQncoWQodD2Kkl0OiTO0m61/kUQNFjgFXTioVNykYgFSYv+oW9RlOW
-XssYvkaWo3yWWOn/9GO2VqhJwK+o1pwRKIZrDcECgYEAhC2zYomTV7CLtTc3d7BY
-tjoZSL0dnENDi3Q60/T9D8MRBGcPfQLtHxwyPSHos/lwFsX1gX9Pdz/AhM4MPP6O
-AGG2E2PGS4/8jy2fB2f30bAMM8etFRD2e4fvMlR2SwpsbqYimpm56bh5EBS4zHGI
-WtC+GbqJf43y3ozmNggxddE=
------END PRIVATE KEY-----

+ 42 - 0
src/protobuf/cmake/Qt6ProtobufMacro.cmake

@@ -9,6 +9,48 @@ function(_qt_internal_link_protobuf_objects target)
     endforeach()
 endfunction()
 
+function(_qt_internal_protobuf_reference_generate)
+    set(options)
+    set(oneValueArgs OUTPUT_DIRECTORY TARGET)
+    set(multiValueArgs GENERATED_SOURCES PROTO_FILES)
+    cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    set(generated_target "${arg_TARGET}_generate")
+
+    foreach(proto_file IN LISTS arg_PROTO_FILES)
+        get_filename_component(dir "${proto_file}" DIRECTORY)
+        list(APPEND proto_includes "-I${dir}")
+    endforeach()
+
+    if(NOT DEFINED arg_OUTPUT_DIRECTORY)
+        set(output_directory "${CMAKE_CURRENT_BINARY_DIR}")
+    else()
+        set(output_directory "${arg_OUTPUT_DIRECTORY}")
+    endif()
+
+    file(MAKE_DIRECTORY "${OUTPUT_DIRECTORY}")
+
+    if(NOT TARGET gRPC::grpc_cpp_plugin)
+        message(FATAL_ERROR "gRPC plugin is not found")
+    endif()
+
+    add_custom_command(
+        OUTPUT ${arg_GENERATED_SOURCES}
+        COMMAND protobuf::protoc
+        ARGS --grpc_out="${output_directory}"
+            --cpp_out="${output_directory}"
+            ${proto_includes}
+            "--plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
+            ${arg_PROTO_FILES}
+        DEPENDS
+            ${arg_PROTO_FILES}
+            gRPC::grpc_cpp_plugin
+    )
+
+    add_custom_target(${generated_target} DEPENDS ${arg_PROTO_FILES} ${arg_GENERATED_SOURCES})
+    add_dependencies(${arg_TARGET} ${generated_target})
+endfunction()
+
 # TODO Qt6: Use WrapProtobuf instead
 find_package(Protobuf)
 

+ 3 - 42
tests/auto/test_grpc/CMakeLists.txt

@@ -1,54 +1,15 @@
 qt_find_package(gRPC CONFIG)
+qt_find_package(Protobuf CONFIG)
 
 # gRPC tests require reference gRPC and protobuf implementation
 if(NOT TARGET gRPC::grpc_cpp_plugin
     OR NOT TARGET gRPC::grpc++
     OR NOT TARGET protobuf::libprotobuf
     OR NOT TARGET protobuf::protoc)
+    message(AUTHOR_WARNING "QtGrpc tests require the reference gRPC C++ libraries.")
+    return ()
 endif()
 
-function(qt_internal_protobuf_reference_generate)
-    set(options)
-    set(oneValueArgs OUTPUT_DIRECTORY TARGET)
-    set(multiValueArgs GENERATED_SOURCES PROTO_FILES)
-    cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
-    set(generated_target "${arg_TARGET}_generate")
-
-    foreach(proto_file IN LISTS arg_PROTO_FILES)
-        get_filename_component(dir "${proto_file}" DIRECTORY)
-        list(APPEND proto_includes "-I${dir}")
-    endforeach()
-
-    if(NOT DEFINED arg_OUTPUT_DIRECTORY)
-        set(output_directory "${CMAKE_CURRENT_BINARY_DIR}")
-    else()
-        set(output_directory "${arg_OUTPUT_DIRECTORY}")
-    endif()
-
-    file(MAKE_DIRECTORY "${OUTPUT_DIRECTORY}")
-
-    if(NOT TARGET gRPC::grpc_cpp_plugin)
-        message(FATAL_ERROR "gRPC plugin is not found")
-    endif()
-
-    add_custom_command(
-        OUTPUT ${arg_GENERATED_SOURCES}
-        COMMAND protobuf::protoc
-        ARGS --grpc_out="${output_directory}"
-            --cpp_out="${output_directory}"
-            ${proto_includes}
-            "--plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
-            ${arg_PROTO_FILES}
-        DEPENDS
-            ${arg_PROTO_FILES}
-            gRPC::grpc_cpp_plugin
-    )
-
-    add_custom_target(${generated_target} DEPENDS ${arg_PROTO_FILES} ${arg_GENERATED_SOURCES})
-    add_dependencies(${arg_TARGET} ${generated_target})
-endfunction()
-
 qt_protobuf_generate(GENERATED_TARGET grpc_tests_common_gen
     PROTO_FILES
         proto/simpletest.proto

+ 1 - 1
tests/auto/test_grpc/echoserver/CMakeLists.txt

@@ -25,7 +25,7 @@ if(MSVC)
 endif()
 
 file(GLOB proto_files ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../proto/*.proto)
-qt_internal_protobuf_reference_generate(TARGET echoserver
+_qt_internal_protobuf_reference_generate(TARGET echoserver
     GENERATED_SOURCES ${generated_sources}
     PROTO_FILES ${proto_files}
 )