Selaa lähdekoodia

Update build procedure

- Adjust build procedure to the one implemented in Qt6
- Decided to make QtProtobuf and QtGrpc a single module in the
  end. Root CMakeLists.txt supposed to find all dependencies for
  the module and if optional depenencies are not found, some
  features will be disabled. This is how it's designed in Qt6.
- Add Protobuf, gRPC and GTest wrapper modules. In-source build
  of gRPC is too expensive and looks redundand for me. So it's
  deprecated and will be removed in futher versions.
Alexey Edelev 3 vuotta sitten
vanhempi
commit
3d6b2acaa5
60 muutettua tiedostoa jossa 1123 lisäystä ja 1103 poistoa
  1. 7 4
      .github/workflows/branchpush.yml
  2. 7 4
      .github/workflows/pullrequest.yml
  3. 1 1
      3rdparty/grpc
  4. 86 42
      CMakeLists.txt
  5. 14 4
      ProjectConfig.cmake.in
  6. 2 2
      README.md
  7. 0 37
      cmake/Coverage.cmake
  8. 15 0
      cmake/FindWrapGTest.cmake
  9. 50 0
      cmake/FindWrapProtobuf.cmake
  10. 49 0
      cmake/FindWrapgRPC.cmake
  11. 0 18
      cmake/GenerateQtHeaders.cmake
  12. 0 43
      cmake/ProtobufLookup.cmake
  13. 0 93
      cmake/QtProtobufCommon.cmake
  14. 57 0
      cmake/QtProtobufCoverage.cmake
  15. 30 24
      cmake/QtProtobufGen.cmake
  16. 288 43
      cmake/QtProtobufInternalHelpers.cmake
  17. 104 0
      cmake/QtProtobufTestHelpers.cmake
  18. 0 32
      cmake/dependencies.cmake
  19. 0 40
      cmake/gRPCLookup.cmake
  20. 2 1
      examples/CMakeLists.txt
  21. 1 2
      examples/addressbook/CMakeLists.txt
  22. 1 3
      examples/addressbookserver/CMakeLists.txt
  23. 7 7
      examples/clienttutorial/CMakeLists.txt
  24. 3 3
      examples/clienttutorial/main.cpp
  25. 1 2
      examples/simplechat/CMakeLists.txt
  26. 1 3
      examples/simplechatserver/CMakeLists.txt
  27. 42 73
      src/generator/CMakeLists.txt
  28. 0 11
      src/generator/GeneratorConfig.cmake.in
  29. 13 0
      src/generator/QtqtprotobufgenConfig.cmake.in
  30. 0 2
      src/generator/multifilegenerator.cpp
  31. 1 1
      src/generator/singlefilegenerator.cpp
  32. 52 118
      src/grpc/CMakeLists.txt
  33. 6 6
      src/grpc/QtGrpcConfig.cmake.in
  34. 3 3
      src/grpc/qt_lib_grpc.pri.in
  35. 5 12
      src/grpc/quick/CMakeLists.txt
  36. 65 140
      src/protobuf/CMakeLists.txt
  37. 5 11
      src/protobuf/QtProtobufConfig.cmake.in
  38. 5 4
      src/protobuf/qt_lib_protobuf.pri.in
  39. 6 13
      src/protobuf/quick/CMakeLists.txt
  40. 1 1
      src/protobuf/quick/qtprotobufquickplugin.h
  41. 32 88
      src/qttypes/CMakeLists.txt
  42. 3 4
      src/qttypes/QtProtobufQtTypesConfig.cmake.in
  43. 3 3
      src/qttypes/qtprotobufqttypes.h
  44. 1 1
      src/qttypes/qtprotobufqttypesglobal.h
  45. 21 86
      src/wellknowntypes/CMakeLists.txt
  46. 14 3
      src/wellknowntypes/QtProtobufWellKnownTypesConfig.cmake.in
  47. 2 2
      src/wellknowntypes/dummy.cpp
  48. 24 5
      tests/CMakeLists.txt
  49. 4 11
      tests/test_grpc/CMakeLists.txt
  50. 1 1
      tests/test_grpc/echoserver/CMakeLists.txt
  51. 2 2
      tests/test_grpc/secureechoserver/CMakeLists.txt
  52. 20 58
      tests/test_grpc_qml/CMakeLists.txt
  53. 45 0
      tests/test_grpc_qml/native_grpc_channel_tests.cmake
  54. 2 3
      tests/test_protobuf/CMakeLists.txt
  55. 2 3
      tests/test_protobuf_multifile/CMakeLists.txt
  56. 5 7
      tests/test_qml/CMakeLists.txt
  57. 3 4
      tests/test_qprotobuf_serializer_plugin/CMakeLists.txt
  58. 1 1
      tests/test_qprotobuf_serializer_plugin/serialization/CMakeLists.txt
  59. 4 9
      tests/test_qttypes/CMakeLists.txt
  60. 4 9
      tests/test_wellknowntypes/CMakeLists.txt

+ 7 - 4
.github/workflows/branchpush.yml

@@ -70,7 +70,10 @@ jobs:
       with:
         vs-version: '16.4'
     - name: Install Deps
-      run: choco install wget golang yasm
+      run: |
+        choco install wget golang
+        mkdir C:\yasm
+        wget -q http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe -O C:\yasm\yasm.exe
     - name: Install Qt
       run: |
         wget -q https://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe -O C:/qt-unified-windows-x86-online.exe
@@ -80,10 +83,10 @@ jobs:
         mkdir build-static
         cd build-static
         setx GOROOT "c:\Go"
-        setx path "%path%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools"
+        setx path "%path%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\yasm"
         set GOROOT="c:\Go"
-        set PATH="%PATH%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools"
-        cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.15.2\msvc2019_64;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools" -DBUILD_SHARED_LIBS=OFF ..
+        set PATH="%PATH%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\yasm"
+        cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.15.2\msvc2019_64;C:\Go\bin;C:\yasm" -DBUILD_SHARED_LIBS=OFF ..
         cmake --build . --config Debug
     - name: Run tests
       run: |

+ 7 - 4
.github/workflows/pullrequest.yml

@@ -29,7 +29,10 @@ jobs:
       with:
         vs-version: '16.4'
     - name: Install Deps
-      run: choco install wget golang yasm
+      run: |
+        choco install wget golang
+        mkdir C:\yasm
+        wget -q http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe -O C:\yasm\yasm.exe
     - name: Install Qt
       run: |
         wget -q https://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe -O C:/qt-unified-windows-x86-online.exe
@@ -39,10 +42,10 @@ jobs:
         mkdir build-static
         cd build-static
         setx GOROOT "c:\Go"
-        setx path "%path%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools"
+        setx path "%path%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\yasm"
         set GOROOT="c:\Go"
-        set PATH="%PATH%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools"
-        cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.15.2\msvc2019_64;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools" -DBUILD_SHARED_LIBS=OFF ..
+        set PATH="%PATH%;C:\Qt\5.15.2\msvc2019_64\bin;C:\Go\bin;C:\yasm"
+        cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.15.2\msvc2019_64;C:\Go\bin;C:\yasm" -DBUILD_SHARED_LIBS=OFF ..
         cmake --build . --config Debug
     - name: Run tests
       run: |

+ 1 - 1
3rdparty/grpc

@@ -1 +1 @@
-Subproject commit c1d176528fd8da9dd4066d16554bcd216d29033f
+Subproject commit 257d0045ab958eb767a3591c88e9d0c2bdf4b916

+ 86 - 42
CMakeLists.txt

@@ -1,9 +1,11 @@
-cmake_minimum_required(VERSION 3.6)
+cmake_minimum_required(VERSION 3.14)
 
 set(QT_PROTOBUF_VERSION 0.5.0)
-set(QT_PROTOBUF_PROJECT QtProtobufProject)
+set(QT_PROTOBUF_NAMESPACE QtProtobuf)
+set(QT_PREFIX Qt)
+set(QT_VERSIONED_PREFIX Qt5)
 
-project(${QT_PROTOBUF_PROJECT} VERSION ${QT_PROTOBUF_VERSION} LANGUAGES CXX)
+project(${QT_PROTOBUF_NAMESPACE} VERSION ${QT_PROTOBUF_VERSION} LANGUAGES CXX)
 
 # Conan support, optional
 if(EXISTS "${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
@@ -18,24 +20,17 @@ set(QT_PROTOBUF_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
 set(QT_PROTOBUF_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
 set(QT_PROTOBUF_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
 
-include("${QT_PROTOBUF_CMAKE_DIR}/dependencies.cmake")
-include("${QT_PROTOBUF_CMAKE_DIR}/Coverage.cmake" EXCLUDE_FROM_ALL)
+list(APPEND CMAKE_MODULE_PATH ${QT_PROTOBUF_CMAKE_DIR})
 
-set(GENERATOR_TARGET qtprotobufgen)
-set(PROTOBUF_QUICK_PLUGIN_NAME protobufquickplugin)
-set(GRPC_QUICK_PLUGIN_NAME grpcquickplugin)
-
-set(QT_PROTOBUF_MAKE_TESTS ON CACHE BOOL "Enable QtProtobuf tests build")
-set(QT_PROTOBUF_MAKE_EXAMPLES ON CACHE BOOL "Enable QtProtobuf examples build")
-set(QT_PROTOBUF_MAKE_COVERAGE OFF CACHE BOOL "Enable QtProtobuf build for profiler (gcov)")
-set(QT_PROTOBUF_FIELD_ENUM OFF CACHE BOOL "Enable generation of enumeration with fields numbers for well-known and Qt types libraries")
-set(BUILD_SHARED_LIBS ON CACHE BOOL "Enable QtProtobuf shared library build (disables static library build)")
-
-if(CMAKE_CROSSCOMPILING)
-    set(QT_PROTOBUF_MAKE_TESTS OFF)
-    set(QT_PROTOBUF_MAKE_EXAMPLES OFF)
-endif()
+find_package(WrapProtobuf REQUIRED)
+find_package(WrapgRPC)
+find_package(Threads)
+find_package(${QT_VERSIONED_PREFIX} COMPONENTS Core Qml CONFIG REQUIRED)
+find_package(${QT_VERSIONED_PREFIX} OPTIONAL_COMPONENTS Network Quick Gui CONFIG)
 
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_POSITION_INDEPENDENT_CODE ${${QT_VERSIONED_PREFIX}_POSITION_INDEPENDENT_CODE})
 if(UNIX)
     if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
         # using Clang
@@ -57,35 +52,81 @@ elseif(WIN32)
     endif()
 endif()
 
+include(QtProtobufInternalHelpers)
+include(QtProtobufCoverage)
+include(QtProtobufGen)
+
+qt_protobuf_internal_check_install()
+
+set(PROTOBUF_QUICK_PLUGIN_NAME protobufquickplugin)
+set(GRPC_QUICK_PLUGIN_NAME grpcquickplugin)
+
+set(QT_PROTOBUF_MAKE_TESTS ON CACHE BOOL "Enable QtProtobuf tests build")
+set(QT_PROTOBUF_MAKE_EXAMPLES ON CACHE BOOL "Enable QtProtobuf examples build")
+set(QT_PROTOBUF_MAKE_COVERAGE OFF CACHE BOOL "Enable QtProtobuf build for profiler (gcov)")
+set(QT_PROTOBUF_FIELD_ENUM OFF CACHE BOOL "Enable generation of enumeration with fields numbers for well-known and Qt types libraries")
+set(QT_PROTOBUF_NATIVE_GRPC_CHANNEL OFF CACHE BOOL "Enable native gRPC channel implementation")
+
+if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
+    if(NOT WrapgRPC_FOUND OR NOT Threads_FOUND)
+        message("QT_PROTOBUF_NATIVE_GRPC_CHANNEL is ON, but required dependencies are not found.")
+        set(QT_PROTOBUF_NATIVE_GRPC_CHANNEL OFF)
+    endif()
+endif()
+
+if(CMAKE_CROSSCOMPILING)
+    set(QT_PROTOBUF_MAKE_TESTS OFF)
+    set(QT_PROTOBUF_MAKE_EXAMPLES OFF)
+endif()
+
+set(QT_PROTOBUF_STATIC OFF CACHE INTERNAL "")
+if(NOT BUILD_SHARED_LIBS)
+    set(QT_PROTOBUF_STATIC ON CACHE INTERNAL "" FORCE)
+endif()
+
+set(extra_type_libraries_options "") #Prevent to set from outside
+if(QT_PROTOBUF_FIELD_ENUM)
+    set(extra_type_libraries_options "FIELDENUM ${extra_type_libraries_options}")
+endif()
+
 configure_package_config_file(
     "${CMAKE_CURRENT_SOURCE_DIR}/ProjectConfig.cmake.in" "${QT_PROTOBUF_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
     INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake")
-install(FILES "${QT_PROTOBUF_BINARY_DIR}/${PROJECT_NAME}Config.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
-    COMPONENT dev)
+
+install(FILES "${QT_PROTOBUF_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+    COMPONENT dev
+)
 export(PACKAGE ${PROJECT_NAME})
-add_subdirectory("src/generator")
+install(FILES "${QT_PROTOBUF_CMAKE_DIR}/FindWrapProtobuf.cmake"
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+    COMPONENT dev
+)
 
+add_subdirectory("src/generator")
 add_subdirectory("src/protobuf")
-add_subdirectory("src/grpc")
-
-set(EXTRA_TYPE_LIBRARIES_OPTIONS "") #Prevent to set from outside
-if(QT_PROTOBUF_FIELD_ENUM)
-    set(EXTRA_TYPE_LIBRARIES_OPTIONS "FIELDENUM ${EXTRA_TYPE_LIBRARIES_OPTIONS}")
+if(TARGET ${QT_VERSIONED_PREFIX}::Network)
+    if(${QT_VERSIONED_PREFIX}Core_VERSION VERSION_LESS "5.12.4")
+        # grpc target requires QT version not less than 5.12.4
+        # earlier versions Http2DirectAttribute is broken: https://doc.qt.io/qt-5/whatsnew511.html
+        #                                                  https://bugreports.qt.io/browse/QTBUG-74765
+        message(WARNING "QtGrpc requires the Qt framework version 5.12.4 or higher")
+    else()
+        add_subdirectory("src/grpc")
+    endif()
 endif()
 
-add_subdirectory("src/wellknowntypes")
-add_subdirectory("src/qttypes")
+if(TARGET protobuf::libprotobuf)
+    add_subdirectory("src/wellknowntypes")
+endif()
+if(TARGET ${QT_VERSIONED_PREFIX}::Gui)
+    add_subdirectory("src/qttypes")
+endif()
 
 if(QT_PROTOBUF_MAKE_TESTS)
-    if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/googletest/CMakeLists.txt")
-        set(BUILD_GMOCK OFF CACHE BOOL "" FORCE)
-        set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
-        add_subdirectory("3rdparty/googletest" EXCLUDE_FROM_ALL)
-        set(GTest_FOUND TRUE)
-    else()
-        find_package(GTest)
-    endif()
-    if(GTest_FOUND)
+    find_package(WrapGTest)
+    find_package(${QT_VERSIONED_PREFIX} OPTIONAL_COMPONENTS Test QuickTest CONFIG)
+    if(GTest_FOUND AND TARGET ${QT_VERSIONED_PREFIX}::Test)
         enable_testing()
         add_subdirectory("tests")
     else()
@@ -94,11 +135,14 @@ if(QT_PROTOBUF_MAKE_TESTS)
 endif()
 
 if(QT_PROTOBUF_MAKE_EXAMPLES)
-    add_subdirectory("examples")
+    if(TARGET ${QT_VERSIONED_PREFIX}::Quick)
+        add_subdirectory("examples")
+    else()
+        message(STATUS "${QT_VERSIONED_PREFIX}::Quick is not found. Disable examples")
+    endif()
 endif()
 
 if(QT_PROTOBUF_INSTALL)
-    include("${QT_PROTOBUF_CMAKE_DIR}/packaging.cmake")
+    include(packaging)
 endif()
-
-include("${QT_PROTOBUF_CMAKE_DIR}/doxygen.cmake")
+include(doxygen)

+ 14 - 4
ProjectConfig.cmake.in

@@ -1,6 +1,16 @@
-set(QT_PROTOBUF_PROJECT "@QT_PROTOBUF_PROJECT@")
+set(QT_VERSIONED_PREFIX @QT_VERSIONED_PREFIX@)
+set(QT_PROTOBUF_STATIC @QT_PROTOBUF_STATIC@)
+set(QT_PROTOBUF_NAMESPACE @QT_PROTOBUF_NAMESPACE@)
+list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
 foreach(component ${@PROJECT_NAME@_FIND_COMPONENTS})
-  # For requested component, execute its "config" script
-  #message(STATUS "Including ${CMAKE_CURRENT_LIST_DIR}/${component}Config.cmake...")
-  include(${CMAKE_CURRENT_LIST_DIR}/${component}Config.cmake)
+    # For requested component, execute its "config" script
+    if(component STREQUAL "ProtobufGenerator")
+        include(${CMAKE_CURRENT_LIST_DIR}/@QT_PROTOBUF_NAMESPACE@qtprotobufgenConfig.cmake)
+        continue()
+    endif()
+    set(component_config "${CMAKE_CURRENT_LIST_DIR}/@QT_PROTOBUF_NAMESPACE@${component}Config.cmake")
+    if(NOT EXISTS "${component_config}")
+        message(FATAL_ERROR "Component ${component} not found")
+    endif()
+    include("${component_config}")
 endforeach()

+ 2 - 2
README.md

@@ -335,7 +335,7 @@ You can integrate QtProtobuf as submodule in your project or as installed in sys
 
 ```cmake
 ...
-find_package(QtProtobufProject CONFIG REQUIRED COMPONENTS QtProtobuf QtGrpc)
+find_package(QtProtobuf CONFIG REQUIRED COMPONENTS Protobuf Grpc)
 file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/path/to/protofile1.proto
  ${CMAKE_CURRENT_SOURCE_DIR}/path/to/protofile2.proto
  ...
@@ -369,7 +369,7 @@ GENERATED_HEADERS ${GENERATED_HEADERS})
 In case if you somehow avoided ```qtprotobuf_generate``` usage, you need manualy link QtProtobuf libraries used by project, e.g.:
 ```cmake
 ...
-target_link_libraries(${TARGET} QtProtobuf::QtProtobuf QtProtobuf::QtGrpc QtProtobuf::QtProtobufWellKnownTypes)
+target_link_libraries(${TARGET} QtProtobuf::Protobuf QtProtobuf::Grpc QtProtobuf::ProtobufWellKnownTypes)
 ...
 ```
 

+ 0 - 37
cmake/Coverage.cmake

@@ -1,37 +0,0 @@
-if(QT_PROTOBUF_MAKE_COVERAGE AND UNIX)
-    message(STATUS "Enable gcov")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
-    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
-    add_custom_target(coverage)
-endif()
-
-function(add_coverage_target)
-    set(options)
-    set(oneValueArgs TARGET)
-    set(multiValueArgs)
-    cmake_parse_arguments(add_coverage_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-    set(GCOV_OUTPUT_DIR ${QT_PROTOBUF_BINARY_DIR}/gcov/${add_coverage_target_TARGET})
-    set(OBJECTS_DIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${add_coverage_target_TARGET}.dir)
-    set(COVERAGE_TARGET ${add_coverage_target_TARGET}_coverage)
-    if(QT_PROTOBUF_MAKE_COVERAGE AND UNIX)
-        find_program(GCOV_EXECUTABLE "gcov")
-        if(GCOV_EXECUTABLE STREQUAL GCOV_EXECUTABLE-NOTFOUND)
-            message(FATAL_ERROR "Coverage enabled for target ${add_coverage_target_TARGET}, but gcov is not installed")
-        endif()
-        file(MAKE_DIRECTORY ${GCOV_OUTPUT_DIR})
-        add_custom_target(${COVERAGE_TARGET} DEPENDS ${add_coverage_target_TARGET})
-        add_custom_command(TARGET ${COVERAGE_TARGET} COMMAND ${GCOV_EXECUTABLE} ${OBJECTS_DIR}/*.o -b -c
-            WORKING_DIRECTORY ${GCOV_OUTPUT_DIR})
-
-
-        find_program(GCOVR_EXECUTABLE "gcovr")
-        if(NOT GCOVR_EXECUTABLE STREQUAL GCOVR_EXECUTABLE-NOTFOUND)
-            set(GCOVR_OUTPUT_DIR ${GCOV_OUTPUT_DIR}/html)
-            file(MAKE_DIRECTORY ${GCOVR_OUTPUT_DIR})
-            add_custom_command(TARGET ${COVERAGE_TARGET} COMMAND ${GCOVR_EXECUTABLE} -g -k -r
-                ${CMAKE_SOURCE_DIR} --html --html-details -o ${GCOVR_OUTPUT_DIR}/${add_coverage_target_TARGET}.html ${OBJECTS_DIR} .
-                WORKING_DIRECTORY ${GCOV_OUTPUT_DIR})
-        endif()
-        add_dependencies(coverage ${COVERAGE_TARGET})
-    endif()
-endfunction(add_coverage_target)

+ 15 - 0
cmake/FindWrapGTest.cmake

@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.10)
+
+find_package(GTest QUIET)
+
+unset(WrapGTest_FOUND)
+if(NOT GTest_FOUND)
+    if(EXISTS "${QT_PROTOBUF_SOURCE_DIR}/3rdparty/googletest/CMakeLists.txt")
+        set(BUILD_GMOCK OFF CACHE BOOL "" FORCE)
+        set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+        add_subdirectory("${QT_PROTOBUF_SOURCE_DIR}/3rdparty/googletest" EXCLUDE_FROM_ALL)
+        set(WrapGTest_FOUND TRUE)
+    endif()
+else()
+    set(WrapGTest_FOUND TRUE)
+endif()

+ 50 - 0
cmake/FindWrapProtobuf.cmake

@@ -0,0 +1,50 @@
+cmake_minimum_required(VERSION 3.10)
+
+find_package(Protobuf QUIET)
+
+unset(WrapProtobuf_FOUND)
+if(NOT Protobuf_FOUND OR NOT TARGET protobuf::libprotobuf
+    OR NOT TARGET protobuf::protoc OR NOT TARGET protobuf::libprotoc)
+
+    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+        set(FIND_LIBRARY_USE_LIB64_PATHS TRUE)
+        set(FIND_LIBRARY_USE_LIBX32_PATHS FALSE)
+        set(FIND_LIBRARY_USE_LIB32_PATHS FALSE)
+    else()
+        set(FIND_LIBRARY_USE_LIBX32_PATHS TRUE)
+        set(FIND_LIBRARY_USE_LIB32_PATHS TRUE)
+        set(FIND_LIBRARY_USE_LIB64_PATHS FALSE)
+    endif()
+
+    find_library(Protobuf_LIBRARY protobuf)
+    if(NOT TARGET protobuf::libprotobuf AND Protobuf_LIBRARY)
+        add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
+        set_target_properties(protobuf::libprotobuf PROPERTIES
+            IMPORTED_LOCATION ${Protobuf_LIBRARY}
+        )
+        if(DEFINED Protobuf_INCLUDE_DIRS)
+            set_target_properties(protobuf::libprotobuf PROPERTIES
+                INTERFACE_INCLUDE_DIRECTORIES ${Protobuf_INCLUDE_DIRS})
+        endif()
+    endif()
+
+    find_program(Protobuf_PROTOC_EXECUTABLE protoc)
+    if(NOT TARGET protobuf::protoc AND Protobuf_PROTOC_EXECUTABLE)
+        add_executable(protobuf::protoc IMPORTED)
+        set_target_properties(protobuf::protoc PROPERTIES IMPORTED_LOCATION ${Protobuf_PROTOC_EXECUTABLE})
+    endif()
+
+    find_package(Threads)
+    find_library(Protobuf_PROTOC_LIBRARY protoc)
+    if(NOT TARGET protobuf::libprotoc AND Protobuf_PROTOC_LIBRARY)
+        add_library(protobuf::libprotoc UNKNOWN IMPORTED)
+        set_target_properties(protobuf::libprotoc PROPERTIES IMPORTED_LOCATION ${Protobuf_PROTOC_LIBRARY}
+            INTERFACE_LINK_LIBRARIES Threads::Threads)
+    endif()
+
+    if(TARGET protobuf::libprotoc AND TARGET protobuf::protoc AND TARGET protobuf::libprotobuf)
+        set(WrapProtobuf_FOUND TRUE)
+    endif()
+else()
+    set(WrapProtobuf_FOUND TRUE)
+endif()

+ 49 - 0
cmake/FindWrapgRPC.cmake

@@ -0,0 +1,49 @@
+cmake_minimum_required(VERSION 3.10)
+function(_add_grpc_target_alias target)
+    if(NOT TARGET ${target})
+        message(FATAL_ERROR "${target} is not a target")
+    endif()
+
+    get_target_property(_aliased ${target} ALIASED_TARGET)
+    if(_aliased)
+        message(FATAL_ERROR "_add_grpc_target_alias only could be called with
+the non-aliased target")
+    endif()
+
+    get_target_property(_type ${target} TYPE)
+    if(NOT TARGET gRPC::${target})
+        if(_type STREQUAL "EXECUTABLE")
+            add_executable(gRPC::${target} ALIAS ${target})
+        else()
+            add_library(gRPC::${target} ALIAS ${target})
+        endif()
+    endif()
+endfunction()
+
+find_package(gRPC CONFIG)
+
+if(TARGET grpc)
+    _add_grpc_target_alias(grpc)
+endif()
+if(TARGET grpc++)
+    _add_grpc_target_alias(grpc++)
+endif()
+if(TARGET grpc_cpp_plugin)
+    _add_grpc_target_alias(grpc_cpp_plugin)
+endif()
+
+unset(WrapgRPC_FOUND)
+if(gRPC_FOUND AND TARGET gRPC::grpc AND TARGET gRPC::grpc++ AND TARGET gRPC::grpc_cpp_plugin)
+    set(WrapgRPC_FOUND TRUE)
+elseif(EXISTS "${QT_PROTOBUF_SOURCE_DIR}/3rdparty/grpc/CMakeLists.txt")
+    message(WARNING "Support for built-in gRPC will be discontinued soon. Please make sure that
+you have recent version of gRPC installed in your system.")
+    set(gRPC_BUILD_TESTS FALSE CACHE INTERNAL "" FORCE)
+    set(protobuf_BUILD_TESTS FALSE CACHE INTERNAL "" FORCE)
+    add_subdirectory("${QT_PROTOBUF_SOURCE_DIR}/3rdparty/grpc" EXCLUDE_FROM_ALL)
+
+    _add_grpc_target_alias(grpc)
+    _add_grpc_target_alias(grpc++)
+    _add_grpc_target_alias(grpc_cpp_plugin)
+    set(WrapgRPC_FOUND TRUE)
+endif()

+ 0 - 18
cmake/GenerateQtHeaders.cmake

@@ -1,18 +0,0 @@
-function(protobuf_generate_qt_headers)
-    set(options)
-    set(oneValueArgs COMPONENT)
-    set(multiValueArgs PUBLIC_HEADER)
-    cmake_parse_arguments(protobuf_generate_qt_headers "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
-    foreach(PUBLIC_HEADER IN LISTS protobuf_generate_qt_headers_PUBLIC_HEADER)
-        get_filename_component(PUBLIC_HEADER_BASE_NAME ${PUBLIC_HEADER} NAME FALSE)
-        file(STRINGS ${PUBLIC_HEADER} CLASS_NAME REGEX "#pragma once //[a-zA-Z]+")
-        if (NOT "${CLASS_NAME}" STREQUAL "")
-            string(REPLACE "#pragma once //" "" CLASS_NAME "${CLASS_NAME}")
-            message(STATUS "Generate Qt header for ${CLASS_NAME}")
-            configure_file("${QT_PROTOBUF_CMAKE_DIR}/GeneratedHeaderTemplate" "${QT_PROTOBUF_BINARY_DIR}/include/${protobuf_generate_qt_headers_COMPONENT}/${CLASS_NAME}" @ONLY)
-            set(GENERATED_PUBLIC_HEADER ${GENERATED_PUBLIC_HEADER} ${QT_PROTOBUF_BINARY_DIR}/include/${protobuf_generate_qt_headers_COMPONENT}/${CLASS_NAME})
-        endif()
-    endforeach()
-    set(GENERATED_PUBLIC_HEADER ${GENERATED_PUBLIC_HEADER} PARENT_SCOPE)
-endfunction()

+ 0 - 43
cmake/ProtobufLookup.cmake

@@ -1,43 +0,0 @@
-find_package(Protobuf CONFIG QUIET)
-if(NOT Protobuf_FOUND)
-    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-        set(FIND_LIBRARY_USE_LIB64_PATHS TRUE)
-        set(FIND_LIBRARY_USE_LIBX32_PATHS FALSE)
-        set(FIND_LIBRARY_USE_LIB32_PATHS FALSE)
-    else()
-        set(FIND_LIBRARY_USE_LIBX32_PATHS TRUE)
-        set(FIND_LIBRARY_USE_LIB32_PATHS TRUE)
-        set(FIND_LIBRARY_USE_LIB64_PATHS FALSE)
-    endif()
-
-    find_library(Protobuf_LIBRARY protobuf)
-    if(NOT TARGET protobuf::libprotobuf AND NOT Protobuf_LIBRARY STREQUAL PROTOBUF_LIBRARY-NOTFOUND)
-        add_library(protobuf::libprotobuf SHARED IMPORTED)
-        set_target_properties(protobuf::libprotobuf PROPERTIES IMPORTED_LOCATION ${Protobuf_LIBRARY})
-    endif()
-
-    find_program(Protobuf_PROTOC_EXECUTABLE protoc)
-    if(NOT TARGET protobuf::protoc AND NOT Protobuf_PROTOC_EXECUTABLE STREQUAL Protobuf_PROTOC_EXECUTABLE-NOTFOUND)
-        add_executable(protobuf::protoc IMPORTED)
-        set_target_properties(protobuf::protoc PROPERTIES IMPORTED_LOCATION ${Protobuf_PROTOC_EXECUTABLE})
-    endif()
-
-    find_package(Threads)
-    find_library(Protobuf_PROTOC_LIBRARY protoc)
-    if(NOT TARGET protobuf::libprotoc AND NOT Protobuf_PROTOC_LIBRARY STREQUAL PROTOBUF_PROTOC_LIBRARY-NOTFOUND)
-        add_library(protobuf::libprotoc SHARED IMPORTED)
-        set_target_properties(protobuf::libprotoc PROPERTIES IMPORTED_LOCATION ${Protobuf_PROTOC_LIBRARY}
-            INTERFACE_LINK_LIBRARIES Threads::Threads)
-    endif()
-
-    unset(Protobuf_FOUND)
-    if(TARGET protobuf::libprotoc AND TARGET protobuf::protoc AND TARGET protobuf::libprotobuf)
-        set(Protobuf_FOUND TRUE)
-#        message(STATUS "Found protobuf installation: ${Protobuf_PROTOC_EXECUTABLE} ${Protobuf_PROTOC_LIBRARY} ${Protobuf_LIBRARY}")
-    else()
-        message(FATAL_ERROR "Protobuf is a hard dependency of the project")
-        unset(Protobuf_LIBRARY)
-        unset(Protobuf_PROTOC_EXECUTABLE)
-        unset(Protobuf_PROTOC_LIBRARY)
-    endif()
-endif()

+ 0 - 93
cmake/QtProtobufCommon.cmake

@@ -1,93 +0,0 @@
-function(protobuf_generate_all)
-    set(options)
-    set(oneValueArgs OUT_DIR TARGET)
-    set(multiValueArgs GENERATED_SOURCES PROTO_FILES)
-    cmake_parse_arguments(protobuf_generate_all "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
-    set(GEN_TARGET "${protobuf_generate_all_TARGET}_generate")
-
-    foreach(PROTO_FILE IN LISTS protobuf_generate_all_PROTO_FILES)
-        get_filename_component(BASE_DIR ${PROTO_FILE} DIRECTORY)
-        set(PROTO_INCLUDES -I"${BASE_DIR}" ${PROTO_INCLUDES})
-    endforeach()
-
-    if(NOT DEFINED protobuf_generate_all_OUT_DIR)
-        set(OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
-    else()
-        set(OUT_DIR ${protobuf_generate_all_OUT_DIR})
-    endif()
-
-    file(MAKE_DIRECTORY ${OUT_DIR})
-
-    if(NOT TARGET gRPC::grpc_cpp_plugin)
-        message(FATAL_ERROR "gRPC plugin is not found")
-    endif()
-
-    add_custom_command(
-        OUTPUT ${GENERATED_SOURCES}
-        COMMAND $<TARGET_FILE:protobuf::protoc>
-        ARGS --grpc_out="${OUT_DIR}"
-            --cpp_out="${OUT_DIR}"
-            ${PROTO_INCLUDES}
-            --plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
-            ${protobuf_generate_all_PROTO_FILES}
-        DEPENDS ${protobuf_generate_all_PROTO_FILES}
-    )
-
-    add_custom_target(${GEN_TARGET} DEPENDS ${protobuf_generate_all_PROTO_FILES} ${GENERATED_SOURCES})
-    add_dependencies(${protobuf_generate_all_TARGET} ${GEN_TARGET})
-endfunction(protobuf_generate_all)
-
-function(add_target_qml)
-    set(options)
-    set(oneValueArgs TARGET QMLDIR_FILE)
-    set(multiValueArgs QML_FILES)
-    cmake_parse_arguments(add_target_qml "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
-    add_custom_target(${add_target_qml_TARGET}_qml DEPENDS ${add_qml_QML_FILES} ${add_target_qml_QMLDIR_FILE})
-    foreach(QML_FILE IN LISTS add_target_qml_QML_FILES)
-        add_custom_command(TARGET ${add_target_qml_TARGET}_qml COMMAND ${CMAKE_COMMAND} -E copy ${QML_FILE}
-            ${CMAKE_CURRENT_BINARY_DIR})
-    endforeach()
-    if(DEFINED ${add_target_qml_QMLDIR_FILE})
-        add_custom_command(TARGET ${add_target_qml_TARGET}_qml COMMAND ${CMAKE_COMMAND} -E copy ${add_qml_QMLDIR_FILE}
-            ${CMAKE_CURRENT_BINARY_DIR})
-    endif()
-    add_dependencies(${add_target_qml_TARGET} ${add_target_qml_TARGET}_qml)
-endfunction()
-
-function(add_target_windeployqt)
-if(WIN32)
-    set(options)
-    set(oneValueArgs QML_DIR TARGET)
-    set(multiValueArgs)
-    cmake_parse_arguments(add_target_windeployqt "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-    find_program(WINDEPLOYQT_EXECUTABLE "windeployqt" PATHS ${PATH})
-    if(WINDEPLOYQT_EXECUTABLE STREQUAL WINDEPLOYQT_EXECUTABLE-NOTFOUND)
-        message(WARNING "windeployqt is not found in specified PATH! Please, copy dependencies manually")
-    else()
-        if(DEFINED add_target_windeployqt_QML_DIR)
-            set(QML_DIR --qmldir ${add_target_windeployqt_QML_DIR})
-        endif()
-        add_custom_command(TARGET ${add_target_windeployqt_TARGET} POST_BUILD
-            COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:QtProtobuf> $<TARGET_FILE_DIR:${add_target_windeployqt_TARGET}>
-            COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:QtGrpc> $<TARGET_FILE_DIR:${add_target_windeployqt_TARGET}>
-            COMMAND ${WINDEPLOYQT_EXECUTABLE} ${QML_DIR} $<TARGET_FILE_DIR:${add_target_windeployqt_TARGET}>)
-    endif()
-endif()
-endfunction()
-
-function(extract_qt_variable VARIABLE)
-    if(NOT DEFINED QT_QMAKE_EXECUTABLE)
-        find_program(QT_QMAKE_EXECUTABLE "qmake")
-        if(QT_QMAKE_EXECUTABLE STREQUAL QT_QMAKE_EXECUTABLE-NOTFOUND)
-            message(FATAL_ERROR "Could not find qmake executable")
-        endif()
-    endif()
-    execute_process(
-        COMMAND ${QT_QMAKE_EXECUTABLE} -query ${VARIABLE}
-        OUTPUT_VARIABLE ${VARIABLE}
-        OUTPUT_STRIP_TRAILING_WHITESPACE
-    )
-    set(${VARIABLE} ${${VARIABLE}} PARENT_SCOPE)
-endfunction()

+ 57 - 0
cmake/QtProtobufCoverage.cmake

@@ -0,0 +1,57 @@
+if(QT_PROTOBUF_MAKE_COVERAGE AND UNIX)
+    message(STATUS "Enable gcov")
+    add_custom_target(coverage)
+    add_custom_target(_qt_protobuf_internal_coverage_tests)
+    add_custom_command(TARGET _qt_protobuf_internal_coverage_tests
+        COMMAND ${CMAKE_CTEST_COMMAND}
+        WORKING_DIRECTORY ${QT_PROTOBUF_BINARY_DIR}
+    )
+endif()
+
+function(qt_protobuf_internal_add_coverage_target)
+    if(NOT QT_PROTOBUF_MAKE_COVERAGE OR NOT UNIX)
+        return()
+    endif()
+
+    set(options)
+    set(oneValueArgs "TARGET")
+    set(multiValueArgs)
+    cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    set(GCOV_OUTPUT_DIR ${QT_PROTOBUF_BINARY_DIR}/gcov/${arg_TARGET})
+    set(OBJECTS_DIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${arg_TARGET}.dir)
+    set(COVERAGE_TARGET ${arg_TARGET}_coverage)
+
+    if(NOT TARGET ${arg_TARGET})
+        message(FATAL_ERROR "Unable to add a coverage target, '${arg_TARGET}' is not a traget")
+    endif()
+
+    find_program(GCOV_EXECUTABLE "gcov")
+    if(NOT GCOV_EXECUTABLE)
+        message(FATAL_ERROR "Coverage is enabled for target ${arg_TARGET}, \
+but gcov is not installed")
+    endif()
+
+    target_compile_options(${arg_TARGET} PUBLIC "-fprofile-arcs" "-ftest-coverage")
+    target_link_options(${arg_TARGET} PUBLIC "--coverage")
+
+    add_dependencies(_qt_protobuf_internal_coverage_tests ${arg_TARGET})
+    add_custom_target(${COVERAGE_TARGET} DEPENDS _qt_protobuf_internal_coverage_tests)
+
+    file(MAKE_DIRECTORY "${GCOV_OUTPUT_DIR}")
+    add_custom_command(TARGET ${COVERAGE_TARGET}
+        COMMAND "${GCOV_EXECUTABLE}" "${OBJECTS_DIR}/*.o" -b -c
+        WORKING_DIRECTORY ${GCOV_OUTPUT_DIR}
+    )
+
+    find_program(GCOVR_EXECUTABLE "gcovr")
+    if(GCOVR_EXECUTABLE)
+        set(GCOVR_OUTPUT_DIR "${GCOV_OUTPUT_DIR}/html")
+        file(MAKE_DIRECTORY "${GCOVR_OUTPUT_DIR}")
+        add_custom_command(TARGET ${COVERAGE_TARGET}
+            COMMAND "${GCOVR_EXECUTABLE}" -g -k -r "${CMAKE_SOURCE_DIR}" --html --html-details -o
+                    "${GCOVR_OUTPUT_DIR}/${arg_TARGET}.html" "${OBJECTS_DIR}" .
+            WORKING_DIRECTORY ${GCOV_OUTPUT_DIR}
+        )
+    endif()
+    add_dependencies(coverage ${COVERAGE_TARGET})
+endfunction()

+ 30 - 24
cmake/QtProtobufGen.cmake

@@ -18,9 +18,9 @@ function(qtprotobuf_generate)
         message(FATAL_ERROR "Either TARGET or GENERATED_TARGET must be specified")
     endif()
 
-    set(GEN_TARGET ${GENERATED_TARGET_NAME}_generate)
+    set(deps_target ${GENERATED_TARGET_NAME}_deps)
 
-    set(QT_PROTOBUF_EXECUTABLE $<TARGET_FILE:${QT_PROTOBUF_PROJECT}::${GENERATOR_TARGET}>)
+    set(QT_PROTOBUF_EXECUTABLE $<TARGET_FILE:${QT_PROTOBUF_NAMESPACE}::qtprotobufgen>)
 
     #Options handling
     set(GENERATION_TYPE "SIGNLE")
@@ -68,7 +68,7 @@ function(qtprotobuf_generate)
             message(FATAL_ERROR "Golang is mandatory dependency for QtProtobuf if GENERATED_HEADERS is not specified. Please install it and ensure that it's accessible by PATH environment variable")
         endif()
 
-        get_target_property(PROTO_PARSER ${QT_PROTOBUF_PROJECT}::${GENERATOR_TARGET} PROTO_PARSER)
+        get_target_property(PROTO_PARSER ${QT_PROTOBUF_NAMESPACE}::qtprotobufgen PROTO_PARSER)
         if(NOT PROTO_PARSER)
             message(FATAL_ERROR "Unable to locate parsemessages.go script")
         endif()
@@ -77,7 +77,7 @@ function(qtprotobuf_generate)
             get_filename_component(BASE_DIR ${PROTO_FILE} DIRECTORY)
             set(PROTO_INCLUDES "-I\"${BASE_DIR}\"" ${PROTO_INCLUDES})
             execute_process(COMMAND ${GO_EXECUTABLE} run ${PROTO_PARSER} ${PROTO_FILE} ${GENERATION_TYPE} ${FOLDER_ENABLED} OUTPUT_VARIABLE GENERATED_HEADERS_PART ERROR_VARIABLE PARSER_ERROR)
-            set(GENERATED_HEADERS ${GENERATED_HEADERS} ${GENERATED_HEADERS_PART})
+            list(APPEND GENERATED_HEADERS ${GENERATED_HEADERS_PART})
         endforeach()
     endif()
 
@@ -112,25 +112,28 @@ function(qtprotobuf_generate)
         string(REGEX REPLACE "\\.[^.]*$" "" GENERATED_BASENAME ${GENERATED_BASENAME})
 
         if(qtprotobuf_generate_FOLDER)
-            list(APPEND GENERATED_SOURCES_FULL ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.cpp)
-            list(APPEND GENERATED_HEADERS_FULL ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.h)
+            list(APPEND GENERATED_SOURCES_FULL "${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.cpp")
+            list(APPEND GENERATED_HEADERS_FULL "${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.h")
         else()
-            list(APPEND GENERATED_SOURCES_FULL ${OUT_DIR}/${GENERATED_BASENAME}.cpp)
-            list(APPEND GENERATED_HEADERS_FULL ${OUT_DIR}/${GENERATED_BASENAME}.h)
+            list(APPEND GENERATED_SOURCES_FULL "${OUT_DIR}/${GENERATED_BASENAME}.cpp")
+            list(APPEND GENERATED_HEADERS_FULL "${OUT_DIR}/${GENERATED_BASENAME}.h")
         endif()
-        set_property(SOURCE ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.cpp PROPERTY SKIP_AUTOMOC ON)
-        set_property(SOURCE ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.cpp PROPERTY SKIP_AUTOUIC ON)
-        set_property(SOURCE ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.cpp PROPERTY SKIP_AUTOGEN ON)
     endforeach()
 
-    set_source_files_properties(${GENERATED_SOURCES_FULL} PROPERTIES GENERATED TRUE)
+    set_source_files_properties(${GENERATED_SOURCES_FULL} PROPERTIES
+        GENERATED TRUE
+        SKIP_AUTOMOC ON
+        SKIP_AUTOUIC ON
+        SKIP_AUTOGEN ON
+    )
+
     qt5_wrap_cpp(MOC_SOURCES ${GENERATED_HEADERS_FULL})
 
     add_custom_command(
             OUTPUT ${GENERATED_SOURCES_FULL} ${GENERATED_HEADERS_FULL}
             COMMAND ${PROTOC_COMMAND}
-                --plugin=protoc-gen-${GENERATOR_TARGET}=${QT_PROTOBUF_EXECUTABLE}
-                --${GENERATOR_TARGET}_out=${OUT_DIR}
+                --plugin=protoc-gen-qtprotobufgen=${QT_PROTOBUF_EXECUTABLE}
+                --qtprotobufgen_out=${OUT_DIR}
                 ${PROTO_INCLUDES}
                 ${qtprotobuf_generate_PROTO_FILES}
             WORKING_DIRECTORY ${OUT_DIR}
@@ -139,29 +142,32 @@ function(qtprotobuf_generate)
             COMMAND_EXPAND_LISTS
     )
 
-    add_custom_target(${GEN_TARGET} DEPENDS ${GENERATED_SOURCES_FULL} ${GENERATED_HEADERS_FULL} ${qtprotobuf_generate_PROTO_FILES})
+    add_custom_target(${deps_target} DEPENDS ${GENERATED_SOURCES_FULL} ${GENERATED_HEADERS_FULL}
+        ${qtprotobuf_generate_PROTO_FILES}
+    )
 
     add_library(${GENERATED_TARGET_NAME} OBJECT ${GENERATED_SOURCES_FULL} ${MOC_SOURCES})
-    add_dependencies(${GENERATED_TARGET_NAME} ${GEN_TARGET})
+    add_dependencies(${GENERATED_TARGET_NAME} ${deps_target})
     set_target_properties(${GENERATED_TARGET_NAME} PROPERTIES PUBLIC_HEADER "${GENERATED_HEADERS_FULL}")
 
-    #Add include directories in case if projects are enabled by find_project
+    #Add include directories in case if targets are found by find_project or in source tree
     target_include_directories(${GENERATED_TARGET_NAME} PUBLIC ${OUT_DIR} PRIVATE
-        $<TARGET_PROPERTY:${QT_PROTOBUF_PROJECT}::QtProtobuf,INTERFACE_INCLUDE_DIRECTORIES>)
+        $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::Protobuf,INTERFACE_INCLUDE_DIRECTORIES>)
 
-    if(TARGET ${QT_PROTOBUF_PROJECT}::QtGrpc)
+    #TODO: Do not link targets if they are not used in .proto files.
+    if(TARGET ${QT_PROTOBUF_NAMESPACE}::Grpc)
         target_include_directories(${GENERATED_TARGET_NAME} PRIVATE
-            $<TARGET_PROPERTY:${QT_PROTOBUF_PROJECT}::QtGrpc,INTERFACE_INCLUDE_DIRECTORIES>)
+            $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::Grpc,INTERFACE_INCLUDE_DIRECTORIES>)
     endif()
 
-    if(TARGET ${QT_PROTOBUF_PROJECT}::QtProtobufWellKnownTypes)
+    if(TARGET ${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes)
         target_include_directories(${GENERATED_TARGET_NAME} PRIVATE
-            $<TARGET_PROPERTY:${QT_PROTOBUF_PROJECT}::QtProtobufWellKnownTypes,INTERFACE_INCLUDE_DIRECTORIES>)
+            $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes,INTERFACE_INCLUDE_DIRECTORIES>)
     endif()
 
-    if(TARGET ${QT_PROTOBUF_PROJECT}::QtProtobufQtTypes)
+    if(TARGET ${QT_PROTOBUF_NAMESPACE}::ProtobufQtTypes)
         target_include_directories(${GENERATED_TARGET_NAME} PRIVATE
-            $<TARGET_PROPERTY:${QT_PROTOBUF_PROJECT}::QtProtobufQtTypes,INTERFACE_INCLUDE_DIRECTORIES>)
+            $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::ProtobufQtTypes,INTERFACE_INCLUDE_DIRECTORIES>)
     endif()
 
     #Automatically link whole static library to specified in parameters target

+ 288 - 43
cmake/QtProtobufInternalHelpers.cmake

@@ -1,41 +1,30 @@
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufCommon.cmake)
-
-macro(qt_protobuf_internal_find_dependencies)
-    find_package(Qt5 COMPONENTS Core Qml Network REQUIRED)
-    find_package(Threads REQUIRED)
-    if(NOT TARGET ${QT_PROTOBUF_PROJECT}::QtProtobuf)
-        find_package(${QT_PROTOBUF_PROJECT} COMPONENTS QtProtobuf REQUIRED)
-    endif()
-    if(NOT TARGET ${QT_PROTOBUF_PROJECT}::QtGrpc)
-        find_package(${QT_PROTOBUF_PROJECT} COMPONENTS QtGrpc REQUIRED)
-    endif()
-    if(QT_PROTOBUF_STATIC)
-        add_definitions(-DQT_PROTOBUF_STATIC)# add_definitions is used because old cmake versions
-                                             # compatibility
-    endif()
-
-    set(CMAKE_POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
-    set(CMAKE_AUTOMOC ON)
-    set(CMAKE_AUTORCC ON)
-endmacro()
+set(_qtprotobuf_all_known_multi_args SOURCES PUBLIC_HEADER INCLUDE_DIRECTORIES LIBRARIES
+    PUBLIC_LIBRARIES PUBLIC_INCLUDE_DIRECTORIES DEFINES PUBLIC_DEFINES)
 
+function(qtprotobuf_parse_arguments prefix option single multi)
+    cmake_parse_arguments(arg "" "" "${_qtprotobuf_all_known_multi_args}" ${ARGN})
+    foreach(_arg IN LISTS _qtprotobuf_all_known_multi_args)
+        if(${_arg} IN_LIST multi)
+            set(${prefix}_${_arg} ${arg_${_arg}} PARENT_SCOPE)
+        else()
+            list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${_arg} ${arg_${_arg}})
+        endif()
+    endforeach()
+    set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
+endfunction()
 
-function(qt_protobuf_internal_add_test_target)
+function(qt_protobuf_internal_add_test)
     set(options MULTI QML FIELDENUM)
     set(oneValueArgs QML_DIR TARGET)
     set(multiValueArgs SOURCES GENERATED_HEADERS EXCLUDE_HEADERS PROTO_FILES PROTO_INCLUDES)
     cmake_parse_arguments(add_test_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
-    find_package(Qt5 COMPONENTS Test REQUIRED)
-
     ## test sources build
     # policy enables automoc for generated files
     if(${CMAKE_VERSION} VERSION_GREATER "3.10.0")
         cmake_policy(SET CMP0071 NEW)
     endif()
 
-    set(CMAKE_POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
-
     set(GENERATED_SOURCES_DIR ${CMAKE_CURRENT_BINARY_DIR}/${add_test_target_TARGET}_generated)
 
     if(DEFINED add_test_target_PROTO_FILES)
@@ -67,25 +56,23 @@ function(qt_protobuf_internal_add_test_target)
 
     target_link_libraries(${add_test_target_TARGET} PUBLIC gtest_main
                                                            gtest
-                                                           ${QT_PROTOBUF_PROJECT}::QtProtobuf
-                                                           ${QT_PROTOBUF_PROJECT}::QtGrpc
-                                                           Qt5::Core
-                                                           Qt5::Test
-                                                           Qt5::Network
+                                                           ${QT_PROTOBUF_NAMESPACE}::Protobuf
+                                                           ${QT_PROTOBUF_NAMESPACE}::Grpc
+                                                           ${QT_VERSIONED_PREFIX}::Core
+                                                           ${QT_VERSIONED_PREFIX}::Test
+                                                           ${QT_VERSIONED_PREFIX}::Network
                                                            ${CMAKE_THREAD_LIBS_INIT})
-    if (${add_test_target_QML})
-        target_link_libraries(${add_test_target_TARGET} PUBLIC Qt5::Qml)
+    if(${add_test_target_QML})
+        target_link_libraries(${add_test_target_TARGET} PUBLIC ${QT_VERSIONED_PREFIX}::Qml)
     endif()
 endfunction()
 
-function(qt_protobuf_internal_add_example_target)
+function(qt_protobuf_internal_add_example)
     set(options)
     set(oneValueArgs TARGET QML_DIR)
     set(multiValueArgs SOURCES PROTO_FILES RESOURCES)
     cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
-    find_package(Qt5 COMPONENTS Quick REQUIRED)
-
     set(CMAKE_INCLUDE_CURRENT_DIR ON)
     set(CMAKE_AUTOMOC ON)
     set(CMAKE_AUTORCC ON)
@@ -93,17 +80,275 @@ function(qt_protobuf_internal_add_example_target)
     file(GLOB PROTO_FILES ABSOLUTE ${arg_PROTO_FILES})
     file(GLOB SOURCES ${arg_SOURCES})
 
-    add_executable(${TARGET} ${SOURCES} ${arg_RESOURCES})
-    qtprotobuf_generate(TARGET ${TARGET}
+    add_executable(${arg_TARGET} ${SOURCES} ${arg_RESOURCES})
+    qtprotobuf_generate(TARGET ${arg_TARGET}
         OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated
         PROTO_FILES ${PROTO_FILES}
         QML)
 
-    add_target_windeployqt(TARGET ${TARGET} QML_DIR ${arg_QML_DIR})
+    qt_protobuf_internal_add_target_windeployqt(TARGET ${arg_TARGET} QML_DIR ${arg_QML_DIR})
+
+    target_link_libraries(${arg_TARGET} PRIVATE examples_common
+                                            ${QT_PROTOBUF_NAMESPACE}::Protobuf
+                                            ${QT_PROTOBUF_NAMESPACE}::Grpc
+                                            ${QT_VERSIONED_PREFIX}::Quick
+                                            ${QT_VERSIONED_PREFIX}::Qml)
+endfunction()
+
+function(qt_protobuf_internal_check_install)
+    set(QT_PROTOBUF_INSTALL
+        TRUE CACHE INTERNAL "Indicates wether QT_PROTOBUF_INSTALL might be installed or not" FORCE
+    )
+
+    if(NOT "${QT_PROTOBUF_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
+        message(STATUS "QtProtobuf configured as sub-project.")
+        set(QT_PROTOBUF_INSTALL TRUE CACHE INTERNAL "" FORCE)
+        message(STATUS "All install rules are disabled.")
+    endif()
+endfunction()
+
+function(qt_protobuf_extract_qt_variable variable)
+    if(NOT DEFINED QT_QMAKE_EXECUTABLE)
+        find_program(QT_QMAKE_EXECUTABLE "qmake")
+        if(QT_QMAKE_EXECUTABLE STREQUAL QT_QMAKE_EXECUTABLE-NOTFOUND)
+            message(FATAL_ERROR "Could not find qmake executable")
+        endif()
+    endif()
+    execute_process(
+        COMMAND "${QT_QMAKE_EXECUTABLE}" -query ${variable}
+        OUTPUT_VARIABLE ${variable}
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+    set(${variable} ${${variable}} PARENT_SCOPE)
+endfunction()
+
+function(qt_protobuf_internal_generate_qt_headers out_var)
+    set(options)
+    set(oneValueArgs "TARGET")
+    set(multiValueArgs "PUBLIC_HEADER")
+    cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    foreach(PUBLIC_HEADER IN LISTS arg_PUBLIC_HEADER)
+        get_filename_component(PUBLIC_HEADER_BASE_NAME ${PUBLIC_HEADER} NAME FALSE)
+        file(STRINGS ${PUBLIC_HEADER} CLASS_NAME REGEX "#pragma once //[a-zA-Z]+")
+        if (NOT "${CLASS_NAME}" STREQUAL "")
+            string(REPLACE "#pragma once //" "" CLASS_NAME "${CLASS_NAME}")
+            message(STATUS "Generate Qt header for ${CLASS_NAME}")
+            configure_file("${QT_PROTOBUF_CMAKE_DIR}/GeneratedHeaderTemplate"
+                "${QT_PROTOBUF_BINARY_DIR}/include/${arg_TARGET}/${CLASS_NAME}" @ONLY
+            )
+
+            list(APPEND ${out_var}
+                "${QT_PROTOBUF_BINARY_DIR}/include/${arg_TARGET}/${CLASS_NAME}"
+            )
+        endif()
+    endforeach()
+    set(${out_var} "${${out_var}}" PARENT_SCOPE)
+endfunction()
+
+function(qt_protobuf_internal_add_library target)
+    qtprotobuf_parse_arguments(arg
+        ""
+        ""
+        "SOURCES;PUBLIC_HEADER"
+        ${ARGN}
+    )
+    set(target_export "${QT_PROTOBUF_NAMESPACE}${target}Targets")
+    set(target_config "${QT_PROTOBUF_NAMESPACE}${target}Config")
+
+    set(target_include_dir ${CMAKE_INSTALL_INCLUDEDIR}/${prefixed_target})
+    set(target_lib_dir ${CMAKE_INSTALL_LIBDIR})
+    set(target_cmake_dir ${CMAKE_INSTALL_LIBDIR}/cmake/${QT_PROTOBUF_NAMESPACE})
+
+    set(CMAKE_AUTOMOC ON)
+    set(CMAKE_AUTORCC ON)
+
+    if(NOT arg_SOURCES)
+        message(FATAL_ERROR "SOURCES are not specified for ${target}")
+    endif()
+
+    file(GLOB sources ${arg_SOURCES} ${arg_PUBLIC_HEADER})
+    add_library(${target} ${sources})
+
+    if(NOT BUILD_SHARED_LIBS)
+        target_compile_definitions(${target} PUBLIC QT_PROTOBUF_STATIC)
+    endif()
+
+    string(TOUPPER "${target}" target_upper)
+    target_compile_definitions(${target} PRIVATE QT_BUILD_${target_upper}_LIB)
+
+    set_target_properties(${target}
+        PROPERTIES
+            VERSION ${PROJECT_VERSION}
+            OUTPUT_NAME ${QT_VERSIONED_PREFIX}${target}
+    )
+
+    target_compile_features(${target}
+        PUBLIC cxx_std_14
+            cxx_auto_type
+            cxx_decltype
+            cxx_final
+            cxx_override
+            cxx_nullptr
+            cxx_lambdas
+            cxx_func_identifier
+    )
 
-    target_link_libraries(${TARGET} PRIVATE examples_common
-                                            QtProtobufProject::QtProtobuf
-                                            QtProtobufProject::QtGrpc
-                                            Qt5::Quick
-                                            Qt5::Qml)
+    target_compile_definitions(${target}
+        PUBLIC
+            QT_PROTOBUF_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
+            QT_PROTOBUF_VERSION_MINOR=${PROJECT_VERSION_MINOR}
+    )
+
+    target_include_directories(${target}
+        PUBLIC
+           "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
+           "$<BUILD_INTERFACE:${QT_PROTOBUF_BINARY_DIR}/include/${target}>"
+           "$<INSTALL_INTERFACE:${target_include_dir}>"
+    )
+
+    qt_protobuf_internal_extend_target(${target} ${arg_UNPARSED_ARGUMENTS}
+        PUBLIC_HEADER ${arg_PUBLIC_HEADER})
+
+    add_library(${QT_PROTOBUF_NAMESPACE}::${target} ALIAS ${target})
+
+    set(target_config_bin_dir "${QT_PROTOBUF_BINARY_DIR}/")
+    include(CMakePackageConfigHelpers)
+    configure_package_config_file("Qt${target}Config.cmake.in"
+        "${QT_PROTOBUF_BINARY_DIR}/${target_config}.cmake"
+        INSTALL_DESTINATION "${target_cmake_dir}"
+    )
+
+    if(QT_PROTOBUF_INSTALL)
+        install(TARGETS ${target}
+            EXPORT ${target_export} COMPONENT dev
+            ARCHIVE DESTINATION ${target_lib_dir} COMPONENT lib
+            PUBLIC_HEADER DESTINATION ${target_include_dir} COMPONENT dev
+            LIBRARY DESTINATION ${target_lib_dir} COMPONENT lib
+            RUNTIME DESTINATION ${target_cmake_dir} COMPONENT lib)
+
+        install(EXPORT ${target_export}
+            NAMESPACE ${QT_PROTOBUF_NAMESPACE}::
+            FILE ${target_export}.cmake
+            DESTINATION ${target_cmake_dir}
+            COMPONENT dev)
+
+        install(FILES "${QT_PROTOBUF_BINARY_DIR}/${target_config}.cmake"
+            DESTINATION "${target_cmake_dir}"
+            COMPONENT dev)
+    endif()
+
+    export(TARGETS ${target}
+        NAMESPACE ${QT_PROTOBUF_NAMESPACE}::
+        FILE ${target_export}.cmake)
+
+    qt_protobuf_internal_add_coverage_target(TARGET ${target})
 endfunction()
+
+function(qt_protobuf_internal_extend_target target)
+    set(multi_arg
+        SOURCES
+        PUBLIC_HEADER
+        INCLUDE_DIRECTORIES
+        LIBRARIES
+        PUBLIC_LIBRARIES
+        PUBLIC_INCLUDE_DIRECTORIES
+        DEFINES
+        PUBLIC_DEFINES
+    )
+    qtprotobuf_parse_arguments(arg
+        ""
+        ""
+        "${multi_arg}"
+        ${ARGN}
+    )
+
+    if(NOT TARGET ${target})
+        message(FATAL_ERROR "${target} is not a target")
+    endif()
+
+    if(arg_SOURCES)
+        file(GLOB sources ${arg_SOURCES})
+        target_sources(${target} PRIVATE ${sources})
+    endif()
+
+    if(arg_PUBLIC_HEADER)
+        file(GLOB PUBLIC_HEADER ${arg_PUBLIC_HEADER})
+        qt_protobuf_internal_generate_qt_headers(generated_public_header
+            PUBLIC_HEADER ${PUBLIC_HEADER}
+            TARGET ${target}
+        )
+        set_target_properties(${target} PROPERTIES
+            PUBLIC_HEADER "${PUBLIC_HEADER};${generated_public_header}")
+    endif()
+
+    if(arg_LIBRARIES)
+        target_link_libraries(${target} PRIVATE ${arg_LIBRARIES})
+    endif()
+
+    if(arg_PUBLIC_LIBRARIES)
+        target_link_libraries(${target} PUBLIC ${arg_PUBLIC_LIBRARIES})
+    endif()
+
+    if(arg_INCLUDE_DIRECTORIES)
+        target_include_directories(${target} PRIVATE ${arg_INCLUDE_DIRECTORIES})
+    endif()
+
+    if(arg_PUBLIC_INCLUDE_DIRECTORIES)
+        target_include_directories(${target} PUBLIC ${arg_PUBLIC_INCLUDE_DIRECTORIES})
+    endif()
+
+    if(arg_DEFINES)
+        target_compile_definitions(${target} PRIVATE ${arg_DEFINES})
+    endif()
+
+    if(arg_PUBLIC_DEFINES)
+       target_compile_definitions(${target} PUBLIC ${arg_PUBLIC_DEFINES})
+    endif()
+endfunction()
+
+function(qt_protobuf_internal_add_executable target)
+    qtprotobuf_parse_arguments(arg
+        ""
+        ""
+        "SOURCES"
+        ${ARGN}
+    )
+    set(target_export "${QT_PROTOBUF_NAMESPACE}${target}Targets")
+    set(target_config "${QT_PROTOBUF_NAMESPACE}${target}Config")
+
+    set(target_cmake_dir ${CMAKE_INSTALL_LIBDIR}/cmake/${QT_PROTOBUF_NAMESPACE})
+    set(target_bindir ${CMAKE_INSTALL_BINDIR})
+
+    file(GLOB sources ${arg_SOURCES})
+    add_executable(${target} ${sources})
+
+    qt_protobuf_internal_extend_target(${target} ${arg_UNPARSED_ARGUMENTS})
+
+    add_executable(${QT_PROTOBUF_NAMESPACE}::${target} ALIAS ${target})
+
+    include(CMakePackageConfigHelpers)
+    set(target_config_bin_dir "${QT_PROTOBUF_BINARY_DIR}/")
+    include(CMakePackageConfigHelpers)
+    configure_package_config_file("Qt${target}Config.cmake.in"
+        "${QT_PROTOBUF_BINARY_DIR}/${target_config}.cmake"
+        INSTALL_DESTINATION "${target_cmake_dir}"
+    )
+
+    if(QT_PROTOBUF_INSTALL)
+        install(TARGETS ${target}
+            EXPORT ${target_export} COMPONENT dev
+            RUNTIME DESTINATION ${target_bindir}
+            COMPONENT lib)
+        install(EXPORT ${target_export}
+            NAMESPACE ${QT_PROTOBUF_NAMESPACE}::
+            FILE ${target_export}.cmake
+            DESTINATION ${target_cmake_dir}
+            COMPONENT dev)
+        install(FILES "${QT_PROTOBUF_BINARY_DIR}/${target_config}.cmake"
+            DESTINATION "${target_cmake_dir}"
+            COMPONENT dev)
+    endif()
+
+    export(TARGETS ${target} NAMESPACE ${QT_PROTOBUF_NAMESPACE}:: FILE ${target_export}.cmake)
+endfunction()

+ 104 - 0
cmake/QtProtobufTestHelpers.cmake

@@ -0,0 +1,104 @@
+function(qt_protobuf_internal_protobuf_generate_all)
+    set(options)
+    set(oneValueArgs OUT_DIR TARGET)
+    set(multiValueArgs GENERATED_SOURCES PROTO_FILES)
+    cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    set(GEN_TARGET "${arg_TARGET}_generate")
+
+    foreach(PROTO_FILE IN LISTS arg_PROTO_FILES)
+        get_filename_component(BASE_DIR "${PROTO_FILE}" DIRECTORY)
+        list(APPEND PROTO_INCLUDES "-I${BASE_DIR}")
+    endforeach()
+
+    if(NOT DEFINED arg_OUT_DIR)
+        set(OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+    else()
+        set(OUT_DIR "${arg_OUT_DIR}")
+    endif()
+
+    file(MAKE_DIRECTORY "${OUT_DIR}")
+
+    if(NOT TARGET gRPC::grpc_cpp_plugin)
+        message(FATAL_ERROR "gRPC plugin is not found")
+    endif()
+
+    add_custom_command(
+        OUTPUT ${GENERATED_SOURCES}
+        COMMAND protobuf::protoc
+        ARGS --grpc_out="${OUT_DIR}"
+            --cpp_out="${OUT_DIR}"
+            ${PROTO_INCLUDES}
+            "--plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
+            ${arg_PROTO_FILES}
+        DEPENDS ${arg_PROTO_FILES}
+    )
+
+    add_custom_target(${GEN_TARGET} DEPENDS ${arg_PROTO_FILES} ${GENERATED_SOURCES})
+    add_dependencies(${arg_TARGET} ${GEN_TARGET})
+endfunction()
+
+function(qt_protobuf_internal_add_target_qml)
+    set(options)
+    set(oneValueArgs TARGET QMLDIR_FILE)
+    set(multiValueArgs QML_FILES)
+    cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    add_custom_target(${arg_TARGET}_qml DEPENDS ${arg_QML_FILES} ${arg_QMLDIR_FILE})
+    foreach(QML_FILE IN LISTS arg_QML_FILES)
+        add_custom_command(TARGET ${arg_TARGET}_qml
+            COMMAND ${CMAKE_COMMAND} -E copy "${QML_FILE}" "${CMAKE_CURRENT_BINARY_DIR}"
+        )
+    endforeach()
+    if(DEFINED ${arg_QMLDIR_FILE})
+        add_custom_command(TARGET ${arg_TARGET}_qml
+            COMMAND ${CMAKE_COMMAND} -E copy "${arg_QMLDIR_FILE}" "${CMAKE_CURRENT_BINARY_DIR}"
+        )
+    endif()
+    add_dependencies(${arg_TARGET} ${arg_TARGET}_qml)
+endfunction()
+
+function(qt_protobuf_internal_add_target_windeployqt)
+    if(WIN32)
+        set(options)
+        set(oneValueArgs "QML_DIR" "TARGET")
+        set(multiValueArgs)
+        cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+        find_program(WINDEPLOYQT_EXECUTABLE "windeployqt" PATHS ${PATH})
+        if(WINDEPLOYQT_EXECUTABLE)
+            if(DEFINED arg_QML_DIR)
+                set(QML_DIR --qmldir ${arg_QML_DIR})
+            endif()
+            add_custom_command(TARGET ${arg_TARGET} POST_BUILD
+                COMMAND ${CMAKE_COMMAND}
+                        -E copy $<TARGET_FILE:${QT_PROTOBUF_NAMESPACE}::Protobuf>
+                        $<TARGET_FILE_DIR:${arg_TARGET}>
+                COMMAND ${CMAKE_COMMAND}
+                         -E copy $<TARGET_FILE:${QT_PROTOBUF_NAMESPACE}::Grpc>
+                         $<TARGET_FILE_DIR:${arg_TARGET}>
+                COMMAND ${WINDEPLOYQT_EXECUTABLE}
+                        ${QML_DIR} $<TARGET_FILE_DIR:${arg_TARGET}>)
+        else()
+            message(WARNING "windeployqt is not found in specified PATH! \
+Please, copy dependencies manually")
+        endif()
+    endif()
+endfunction()
+
+macro(qt_protobuf_internal_find_dependencies)
+    find_package(${QT_VERSIONED_PREFIX} COMPONENTS Core Qml Network REQUIRED)
+    find_package(Threads REQUIRED)
+    if(NOT TARGET ${QT_PROTOBUF_NAMESPACE}::Protobuf)
+        find_package(${QT_PROTOBUF_NAMESPACE} COMPONENTS Protobuf REQUIRED)
+    endif()
+    if(NOT TARGET ${QT_PROTOBUF_NAMESPACE}::Grpc)
+        find_package(${QT_PROTOBUF_NAMESPACE} COMPONENTS Grpc REQUIRED)
+    endif()
+    if(QT_PROTOBUF_STATIC)
+        add_definitions(-DQT_PROTOBUF_STATIC)# add_definitions is used because old cmake versions
+                                             # compatibility
+    endif()
+
+    set(CMAKE_AUTOMOC ON)
+    set(CMAKE_AUTORCC ON)
+endmacro()

+ 0 - 32
cmake/dependencies.cmake

@@ -1,32 +0,0 @@
-set(QT_PROTOBUF_INSTALL TRUE)
-
-if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/grpc/CMakeLists.txt")
-    message(STATUS "Found gRPC sub-project. Perform all-in-one build.")
-    set(QT_PROTOBUF_INSTALL FALSE)
-
-    set(gRPC_BUILD_TESTS FALSE)
-    set(protobuf_BUILD_TESTS FALSE)
-    add_subdirectory("3rdparty/grpc" EXCLUDE_FROM_ALL)
-    if(TARGET grpc AND TARGET grpc++ AND TARGET grpc_cpp_plugin)
-        add_library(gRPC::grpc ALIAS grpc)
-        add_library(gRPC::grpc++ ALIAS grpc++)
-        add_executable(gRPC::grpc_cpp_plugin ALIAS grpc_cpp_plugin)
-        if (QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-            export(TARGETS grpc++ grpc gpr NAMESPACE gRPC:: FILE gRPCTargets.cmake)
-            export(TARGETS ssl crypto zlibstatic c-ares address_sorting FILE gRPCDepsTargets.cmake)
-        endif()
-        set(gRPC_FOUND TRUE)
-    endif()
-else()
-    include("${QT_PROTOBUF_CMAKE_DIR}/ProtobufLookup.cmake")
-    include("${QT_PROTOBUF_CMAKE_DIR}/gRPCLookup.cmake")
-endif()
-
-if(NOT "${QT_PROTOBUF_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
-    message(STATUS "QtProtobuf configured as sub-project.")
-    set(QT_PROTOBUF_INSTALL FALSE)
-endif()
-
-if(NOT QT_PROTOBUF_INSTALL)
-    message(STATUS "All install rules are disabled.")
-endif()

+ 0 - 40
cmake/gRPCLookup.cmake

@@ -1,40 +0,0 @@
-find_package(gRPC CONFIG QUIET)
-if(NOT gRPC_FOUND)
-    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-        set(FIND_LIBRARY_USE_LIB64_PATHS TRUE)
-        set(FIND_LIBRARY_USE_LIBX32_PATHS FALSE)
-        set(FIND_LIBRARY_USE_LIB32_PATHS FALSE)
-    else()
-        set(FIND_LIBRARY_USE_LIBX32_PATHS TRUE)
-        set(FIND_LIBRARY_USE_LIB32_PATHS TRUE)
-        set(FIND_LIBRARY_USE_LIB64_PATHS FALSE)
-    endif()
-
-    find_program(gRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
-    if(NOT TARGET gRPC::grpc_cpp_plugin AND NOT gRPC_CPP_PLUGIN_EXECUTABLE STREQUAL gRPC_CPP_PLUGIN_EXECUTABLE-NOTFOUND)
-        add_executable(gRPC::grpc_cpp_plugin IMPORTED)
-        set_target_properties(gRPC::grpc_cpp_plugin PROPERTIES IMPORTED_LOCATION ${gRPC_CPP_PLUGIN_EXECUTABLE})
-    endif()
-
-    find_library(gRPC_LIBRARY grpc)
-    if(NOT TARGET gRPC::grpc AND NOT gRPC_LIBRARY STREQUAL gRPC_LIBRARY-NOTFOUND)
-        add_library(gRPC::grpc SHARED IMPORTED)
-        set_target_properties(gRPC::grpc PROPERTIES IMPORTED_LOCATION ${gRPC_LIBRARY})
-    endif()
-
-    find_library(gRPC_CPP_LIBRARY grpc++)
-    if(NOT TARGET gRPC::grpc++ AND NOT gRPC_CPP_LIBRARY STREQUAL gRPC_CPP_LIBRARY-NOTFOUND)
-        add_library(gRPC::grpc++ SHARED IMPORTED)
-        set_target_properties(gRPC::grpc++ PROPERTIES IMPORTED_LOCATION ${gRPC_CPP_LIBRARY} INTERFACE_LINK_LIBRARIES protobuf::libprotobuf)
-    endif()
-
-    unset(gRPC_FOUND)
-    if(TARGET gRPC::grpc++ AND TARGET gRPC::grpc AND TARGET gRPC::grpc_cpp_plugin)
-#        message(STATUS "Found gRPC")
-        set(gRPC_FOUND TRUE)
-    else()
-        unset(gRPC_LIBRARY)
-        unset(gRPC_CPP_PLUGIN_EXECUTABLE)
-        unset(gRPC_CPP_LIBRARY)
-    endif()
-endif()

+ 2 - 1
examples/CMakeLists.txt

@@ -1,4 +1,5 @@
-if(gRPC_FOUND)
+if(WrapgRPC_FOUND)
+    include(QtProtobufTestHelpers)
     add_subdirectory("examples_common")
 
     add_subdirectory("addressbook")

+ 1 - 2
examples/addressbook/CMakeLists.txt

@@ -1,9 +1,8 @@
 set(TARGET addressbook)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 
-qt_protobuf_internal_add_example_target(TARGET ${TARGET}
+qt_protobuf_internal_add_example(TARGET ${TARGET}
                    PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/proto/addressbook.proto"
                    SOURCES main.cpp
                            addressbookengine.cpp

+ 1 - 3
examples/addressbookserver/CMakeLists.txt

@@ -1,7 +1,5 @@
 set(TARGET addressbookserver)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufCommon.cmake)
-
 set(GENERATED_SOURCES
     ${CMAKE_CURRENT_BINARY_DIR}/addressbook.pb.cc
     ${CMAKE_CURRENT_BINARY_DIR}/addressbook.grpc.pb.cc)
@@ -18,7 +16,7 @@ if(UNIX)
 endif()
 
 file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../addressbook/proto/*.proto)
-protobuf_generate_all(TARGET ${TARGET}
+qt_protobuf_internal_protobuf_generate_all(TARGET ${TARGET}
     GENERATED_SOURCES ${GENERATED_SOURCES}
     PROTO_FILES ${PROTO_FILES})
 

+ 7 - 7
examples/clienttutorial/CMakeLists.txt

@@ -11,11 +11,11 @@ set(CMAKE_AUTORCC ON)
 find_package(Qt5 COMPONENTS Core Quick REQUIRED)
 set(CMAKE_POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
 
-if(NOT TARGET ${QT_PROTOBUF_PROJECT}::QtProtobuf)
-    find_package(${QT_PROTOBUF_PROJECT} COMPONENTS QtProtobuf REQUIRED)
+if(NOT TARGET ${QT_PROTOBUF_NAMESPACE}::Protobuf)
+    find_package(${QT_PROTOBUF_NAMESPACE} COMPONENTS Protobuf REQUIRED)
 endif()
-if(NOT TARGET ${QT_PROTOBUF_PROJECT}::QtGrpc)
-    find_package(${QT_PROTOBUF_PROJECT} COMPONENTS QtGrpc REQUIRED)
+if(NOT TARGET ${QT_PROTOBUF_NAMESPACE}::Grpc)
+    find_package(${QT_PROTOBUF_NAMESPACE} COMPONENTS Grpc REQUIRED)
 endif()
 
 add_executable(clienttutorial main.cpp echoclientengine.cpp qml.qrc)
@@ -25,12 +25,12 @@ qtprotobuf_generate(TARGET clienttutorial
                     QML TRUE)
 
 target_compile_definitions(clienttutorial
-                           PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
+                           PRIVATE "$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>")
 if(QT_PROTOBUF_STATIC)
    add_definitions(-DQT_PROTOBUF_STATIC)# add_definitions is used because old cmake versions
                                         # compatibility
 endif()
 target_link_libraries(clienttutorial PRIVATE Qt5::Core
                                              Qt5::Quick
-                                             QtProtobufProject::QtGrpc
-                                             QtProtobufProject::QtProtobuf)
+                                             ${QT_PROTOBUF_NAMESPACE}::Grpc
+                                             ${QT_PROTOBUF_NAMESPACE}::Protobuf)

+ 3 - 3
examples/clienttutorial/main.cpp

@@ -35,9 +35,9 @@
  * Add following line in your CMakeLists.txt to add QtProtobuf as project dependency:
  *
  * \code
- * find_package(QtProtobufProject COMPONENTS QtProtobuf QtGrpc REQUIRED)
+ * find_package(QtProtobuf COMPONENTS Protobuf Grpc REQUIRED)
  * ...
- * target_link_libraries(clienttutorial PRIVATE QtProtobufProject::QtGrpc QtProtobufProject::QtProtobuf)
+ * target_link_libraries(clienttutorial PRIVATE QtProtobuf::Grpc QtProtobuf::Protobuf)
  * \endcode
  * At this point you will have full access to QtProtobuf libraries and macroses.
  *
@@ -242,7 +242,7 @@
 #include "echoclientengine.h"
 
 int main(int argc, char *argv[])
-{ 
+{
     QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
     QGuiApplication app(argc, argv);
 

+ 1 - 2
examples/simplechat/CMakeLists.txt

@@ -1,9 +1,8 @@
 set(TARGET simplechat)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 
-qt_protobuf_internal_add_example_target(TARGET ${TARGET}
+qt_protobuf_internal_add_example(TARGET ${TARGET}
                    PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/proto/simplechat.proto"
                    SOURCES main.cpp
                            simplechatengine.cpp

+ 1 - 3
examples/simplechatserver/CMakeLists.txt

@@ -1,7 +1,5 @@
 set(TARGET simplechatserver)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufCommon.cmake)
-
 set(GENERATED_SOURCES
     ${CMAKE_CURRENT_BINARY_DIR}/simplechat.pb.cc
     ${CMAKE_CURRENT_BINARY_DIR}/simplechat.grpc.pb.cc)
@@ -18,7 +16,7 @@ if(UNIX)
 endif()
 
 file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../simplechat/proto/*.proto)
-protobuf_generate_all(TARGET ${TARGET}
+qt_protobuf_internal_protobuf_generate_all(TARGET ${TARGET}
     GENERATED_SOURCES ${GENERATED_SOURCES}
     PROTO_FILES ${PROTO_FILES})
 

+ 42 - 73
src/generator/CMakeLists.txt

@@ -1,75 +1,44 @@
-set(TARGET ${GENERATOR_TARGET})
-set(TARGET_EXPORT GeneratorTargets)
-set(TARGET_CONFIG GeneratorConfig)
-
-set(TARGET_BINDIR ${CMAKE_INSTALL_BINDIR})
-set(TARGET_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
-
-file(GLOB SOURCES main.cpp
-    generatorcommon.cpp
-    generatoroptions.cpp
-    templates.cpp
-    generatorbase.cpp
-    singlefilegenerator.cpp
-    multifilegenerator.cpp
-    baseprinter.cpp
-    messagedeclarationprinter.cpp
-    messagedefinitionprinter.cpp
-    enumdeclarationprinter.cpp
-    enumdefinitionprinter.cpp
-    servicedeclarationprinterbase.cpp
-    clientdeclarationprinter.cpp
-    clientdefinitionprinter.cpp
-    serverdeclarationprinter.cpp)
-
-file(GLOB HEADERS utils.h
-    generatorcommon.h
-    generatoroptions.h
-    templates.h
-    generatorbase.h
-    singlefilegenerator.h
-    multifilegenerator.h
-    baseprinter.h
-    descriptorprinterbase.h
-    messagedeclarationprinter.h
-    messagedefinitionprinter.h
-    enumdeclarationprinter.h
-    enumdefinitionprinter.h
-    servicedeclarationprinterbase.h
-    clientdeclarationprinter.h
-    clientdefinitionprinter.h
-    serverdeclarationprinter.h)
-
-add_executable(${TARGET} ${SOURCES})
-
-add_executable(${QT_PROTOBUF_PROJECT}::${TARGET} ALIAS ${TARGET})
-
-if(DEFINED Protobuf_INCLUDE_DIRS)
-    target_include_directories(${TARGET} PUBLIC ${Protobuf_INCLUDE_DIRS})
-endif()
-
-target_link_libraries(${TARGET} protobuf::libprotobuf protobuf::libprotoc)
-
-include(CMakePackageConfigHelpers)
-configure_package_config_file(
-    "${TARGET_CONFIG}.cmake.in" "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake"
-    INSTALL_DESTINATION "${TARGET_CMAKE_DIR}")
-configure_file("${QT_PROTOBUF_CMAKE_DIR}/QtProtobufGen.cmake" "${QT_PROTOBUF_BINARY_DIR}/QtProtobufGen.cmake" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/parsemessages.go" "${QT_PROTOBUF_BINARY_DIR}/parsemessages.go" COPYONLY)
-configure_file("${QT_PROTOBUF_CMAKE_DIR}/ProtobufLookup.cmake" "${QT_PROTOBUF_BINARY_DIR}/ProtobufLookup.cmake" COPYONLY)
-
-set_property(TARGET ${TARGET} PROPERTY PROTO_PARSER "${QT_PROTOBUF_BINARY_DIR}/parsemessages.go")
+qt_protobuf_internal_add_executable(qtprotobufgen
+    SOURCES
+        utils.h
+        descriptorprinterbase.h
+        main.cpp
+        generatorcommon.cpp generatorcommon.h
+        generatoroptions.cpp generatoroptions.h
+        templates.cpp templates.h
+        generatorbase.cpp generatorbase.h
+        singlefilegenerator.cpp singlefilegenerator.h
+        multifilegenerator.cpp multifilegenerator.h
+        baseprinter.cpp baseprinter.h
+        messagedeclarationprinter.cpp messagedeclarationprinter.h
+        messagedefinitionprinter.cpp messagedefinitionprinter.h
+        enumdeclarationprinter.cpp enumdeclarationprinter.h
+        enumdefinitionprinter.cpp enumdefinitionprinter.h
+        servicedeclarationprinterbase.cpp servicedeclarationprinterbase.h
+        clientdeclarationprinter.cpp clientdeclarationprinter.h
+        clientdefinitionprinter.cpp clientdefinitionprinter.h
+        serverdeclarationprinter.cpp serverdeclarationprinter.h
+    LIBRARIES
+        protobuf::libprotobuf
+        protobuf::libprotoc
+)
+
+set_property(TARGET qtprotobufgen
+    PROPERTY PROTO_PARSER "${QT_PROTOBUF_BINARY_DIR}/parsemessages.go"
+)
+
+configure_file("${QT_PROTOBUF_CMAKE_DIR}/QtProtobufGen.cmake"
+    "${QT_PROTOBUF_BINARY_DIR}/QtProtobufGen.cmake" COPYONLY
+)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/parsemessages.go"
+    "${QT_PROTOBUF_BINARY_DIR}/parsemessages.go" COPYONLY
+)
 
 if(QT_PROTOBUF_INSTALL)
-    install(TARGETS ${TARGET}
-        EXPORT ${TARGET_EXPORT} COMPONENT dev
-        RUNTIME DESTINATION ${TARGET_BINDIR} COMPONENT lib)
-    install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
-    install(FILES "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake"
-        "${QT_PROTOBUF_BINARY_DIR}/QtProtobufGen.cmake"
-        "${QT_PROTOBUF_BINARY_DIR}/parsemessages.go"
-        "${QT_PROTOBUF_BINARY_DIR}/ProtobufLookup.cmake"
-        DESTINATION "${TARGET_CMAKE_DIR}" COMPONENT dev)
-endif()
-
-export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake)
+    install(FILES
+           "${QT_PROTOBUF_BINARY_DIR}/QtProtobufGen.cmake"
+           "${QT_PROTOBUF_BINARY_DIR}/parsemessages.go"
+        DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QT_PROTOBUF_NAMESPACE}"
+        COMPONENT dev
+    )
+endif()

+ 0 - 11
src/generator/GeneratorConfig.cmake.in

@@ -1,11 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/ProtobufLookup.cmake")
-
-if(NOT TARGET @TARGET@ AND NOT @TARGET@_BINARY_DIR)
-    include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT@.cmake")
-endif()
-
-set_property(TARGET @QT_PROTOBUF_PROJECT@::@TARGET@ PROPERTY PROTO_PARSER "${CMAKE_CURRENT_LIST_DIR}/parsemessages.go")
-
-@PACKAGE_INIT@
-set(GENERATOR_TARGET "@GENERATOR_TARGET@")
-include("${CMAKE_CURRENT_LIST_DIR}/QtProtobufGen.cmake")

+ 13 - 0
src/generator/QtqtprotobufgenConfig.cmake.in

@@ -0,0 +1,13 @@
+include(CMakeFindDependencyMacro)
+find_dependency(WrapProtobuf REQUIRED)
+
+if(NOT TARGET @QT_PROTOBUF_NAMESPACE@::@target@)
+    include("${CMAKE_CURRENT_LIST_DIR}/@target_export@.cmake")
+endif()
+
+set_property(TARGET @QT_PROTOBUF_NAMESPACE@::@target@
+    PROPERTY PROTO_PARSER "${CMAKE_CURRENT_LIST_DIR}/parsemessages.go"
+)
+
+@PACKAGE_INIT@
+include("${CMAKE_CURRENT_LIST_DIR}/QtProtobufGen.cmake")

+ 0 - 2
src/generator/multifilegenerator.cpp

@@ -94,7 +94,6 @@ bool MultiFileGenerator::Generate(const FileDescriptor *file,
             auto field = message->field(i);
             if (common::isPureMessage(field)) {
                 auto dependency = field->message_type();
-                std::cerr << "Found dependency: " << dependency->name() << std::endl;
                 deps.push_back(dependency);
             }
         }
@@ -192,7 +191,6 @@ std::list<const ::google::protobuf::Descriptor *> MultiFileGenerator::findNested
             auto field = message->field(i);
             if (common::isPureMessage(field)) {
                 auto dependency = field->message_type();
-                std::cerr << "Found dependency: " << dependency->name() << std::endl;
                 dependencies.push_back(dependency);
             }
         }

+ 1 - 1
src/generator/singlefilegenerator.cpp

@@ -103,7 +103,7 @@ bool SingleFileGenerator::GenerateMessages(const ::google::protobuf::FileDescrip
             auto field = message->field(i);
             if (field->type() == ::google::protobuf::FieldDescriptor::TYPE_MESSAGE
                     && !field->is_map() && !field->is_repeated()
-                    && common::isQtType(field)) {                
+                    && common::isQtType(field)) {
                 externalIncludes.insert(field->message_type()->name());
                 hasQtTypes = true;
             }

+ 52 - 118
src/grpc/CMakeLists.txt

@@ -1,132 +1,66 @@
-set(TARGET QtGrpc)
-set(TARGET_EXPORT ${TARGET}Targets)
-set(TARGET_CONFIG ${TARGET}Config)
-
-set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET})
-set(TARGET_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
-set(TARGET_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
-set(TARGET_BINDIR ${CMAKE_INSTALL_BINDIR})
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-
-find_package(Qt5 COMPONENTS Core Network Qml CONFIG REQUIRED)
-if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    find_package(Threads REQUIRED)
-endif()
-
-if(Qt5Core_VERSION VERSION_LESS "5.12.4")
-    # grpc target requires QT version not less than 5.12.4
-    # earlier versions Http2DirectAttribute is broken: https://doc.qt.io/qt-5/whatsnew511.html
-    #                                                  https://bugreports.qt.io/browse/QTBUG-74765
-    message(FATAL_ERROR "Required Qt version is 5.12.4+")
-endif()
-
-set(CMAKE_POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-include(${QT_PROTOBUF_CMAKE_DIR}/GenerateQtHeaders.cmake)
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufCommon.cmake)
-
-set(QT_PROTOBUF_NATIVE_GRPC_CHANNEL OFF CACHE BOOL "Enable native gRPC channel implementation")
-
-file(GLOB SOURCES qgrpcasyncoperationbase.cpp
-    qgrpcasyncreply.cpp
-    qgrpcsubscription.cpp
-    qgrpcstatus.cpp
-    qabstractgrpcchannel.cpp
-    qgrpchttp2channel.cpp
-    qabstractgrpcclient.cpp
-    qgrpccredentials.cpp
-    qgrpcsslcredentials.cpp
-    qgrpcinsecurecredentials.cpp
-    qgrpcuserpasswordcredentials.cpp
+qt_protobuf_internal_add_library(Grpc
+    SOURCES
+        qgrpcasyncoperationbase.cpp
+        qgrpcasyncreply.cpp
+        qgrpcsubscription.cpp
+        qgrpcstatus.cpp
+        qabstractgrpcchannel.cpp
+        qgrpchttp2channel.cpp
+        qabstractgrpcclient.cpp
+        qgrpccredentials.cpp
+        qgrpcsslcredentials.cpp
+        qgrpcinsecurecredentials.cpp
+        qgrpcuserpasswordcredentials.cpp
+    PUBLIC_HEADER
+        qgrpcasyncoperationbase_p.h
+        qgrpcasyncreply.h
+        qgrpcsubscription.h
+        qgrpcstatus.h
+        qabstractgrpcchannel.h
+        qgrpchttp2channel.h
+        qabstractgrpcclient.h
+        qabstractgrpccredentials.h
+        qgrpccredentials.h
+        qgrpcsslcredentials.h
+        qgrpcinsecurecredentials.h
+        qgrpcuserpasswordcredentials.h
+        qtgrpcglobal.h
+    PUBLIC_LIBRARIES
+        ${QT_PROTOBUF_NAMESPACE}::Protobuf
+        Qt5::Core
+        Qt5::Network
 )
 
-file(GLOB HEADERS qgrpcasyncoperationbase_p.h
-    qgrpcasyncreply.h
-    qgrpcsubscription.h
-    qgrpcstatus.h
-    qabstractgrpcchannel.h
-    qgrpchttp2channel.h
-    qabstractgrpcclient.h
-    qabstractgrpccredentials.h
-    qgrpccredentials.h
-    qgrpcsslcredentials.h
-    qgrpcinsecurecredentials.h
-    qgrpcuserpasswordcredentials.h
-    qtgrpcglobal.h)
-
 if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    list(APPEND SOURCES qgrpcchannel.cpp)
-    list(APPEND HEADERS qgrpcchannel.h qgrpcchannel_p.h)
+    qt_protobuf_internal_extend_target(Grpc
+        SOURCES
+            qgrpcchannel.cpp qgrpcchannel_p.h
+        PUBLIC_HEADER
+            qgrpcchannel.h
+        PUBLIC_DEFINES
+            QT_PROTOBUF_NATIVE_GRPC_CHANNEL
+        PUBLIC_LIBRARIES
+            gRPC::grpc++
+            ${CMAKE_THREAD_LIBS_INIT}
+    )
 endif()
 
-protobuf_generate_qt_headers(PUBLIC_HEADER ${HEADERS} COMPONENT ${TARGET})
-
-add_library(${TARGET} ${SOURCES})
-
 if(NOT BUILD_SHARED_LIBS)
-    if(WIN32)
-        message(WARNING "Static version of ${TARGET} is not fully tested on Win32 platforms")
-    endif()
-    target_compile_definitions(${TARGET} PUBLIC QT_PROTOBUF_STATIC)
     set(QT_PROTOBUF_EXTRA_CONFIG "staticlib") #extra config for .pri file in case if static build enabled
 endif()
 
-extract_qt_variable(QT_HOST_DATA)
-
-target_compile_definitions(${TARGET} PRIVATE QT_BUILD_GRPC_LIB)
-
-set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} PUBLIC_HEADER "${HEADERS};${GENERATED_PUBLIC_HEADER}" OUTPUT_NAME ${TARGET})
-target_include_directories(${TARGET} PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-    $<BUILD_INTERFACE:${QT_PROTOBUF_BINARY_DIR}/include/${TARGET}>
-    $<INSTALL_INTERFACE:${TARGET_INCLUDE_DIR}>
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/qt_lib_grpc.pri.in"
+    "${QT_PROTOBUF_BINARY_DIR}/qt_lib_grpc.pri" @ONLY
 )
-target_link_libraries(${TARGET} PUBLIC ${QT_PROTOBUF_PROJECT}::QtProtobuf Qt5::Core Qt5::Network)
-
-if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    target_compile_definitions(${TARGET} PUBLIC QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    target_link_libraries(${TARGET} PUBLIC gRPC::grpc++ ${CMAKE_THREAD_LIBS_INIT})
-endif()
-
-target_compile_features(${TARGET} PUBLIC cxx_std_14
-                                         cxx_auto_type
-                                         cxx_decltype
-                                         cxx_final
-                                         cxx_override
-                                         cxx_nullptr
-                                         cxx_lambdas
-                                         cxx_func_identifier)
-
-add_library(${QT_PROTOBUF_PROJECT}::${TARGET} ALIAS ${TARGET})
-
-include(CMakePackageConfigHelpers)
-configure_package_config_file(
-    "${TARGET_CONFIG}.cmake.in" "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake"
-    INSTALL_DESTINATION "${TARGET_CMAKE_DIR}")
-
-configure_file("${QT_PROTOBUF_CMAKE_DIR}/gRPCLookup.cmake" "${QT_PROTOBUF_BINARY_DIR}/gRPCLookup.cmake" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/qt_lib_grpc.pri.in" "${QT_PROTOBUF_BINARY_DIR}/qt_lib_grpc.pri" @ONLY)
 
 if(QT_PROTOBUF_INSTALL)
-    install(TARGETS ${TARGET}
-        EXPORT ${TARGET_EXPORT} COMPONENT dev
-        ARCHIVE DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        PUBLIC_HEADER DESTINATION ${TARGET_INCLUDE_DIR} COMPONENT dev
-        LIBRARY DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        RUNTIME DESTINATION ${TARGET_BINDIR} COMPONENT lib)
-    install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
-    install(FILES "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake"
-        "${QT_PROTOBUF_BINARY_DIR}/gRPCLookup.cmake"
-        DESTINATION "${TARGET_CMAKE_DIR}" COMPONENT dev)
-    install(FILES "${QT_PROTOBUF_BINARY_DIR}/qt_lib_grpc.pri" DESTINATION "${QT_HOST_DATA}/mkspecs/modules" COMPONENT dev)
+    qt_protobuf_extract_qt_variable(QT_HOST_DATA)
+    install(FILES "${QT_PROTOBUF_BINARY_DIR}/qt_lib_grpc.pri"
+            DESTINATION "${QT_HOST_DATA}/mkspecs/modules"
+            COMPONENT dev
+    )
 endif()
 
-export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake)
-
-add_subdirectory("quick")
-
-add_coverage_target(TARGET ${TARGET})
+if(TARGET Qt5::Quick)
+    add_subdirectory("quick")
+endif()

+ 6 - 6
src/grpc/QtGrpcConfig.cmake.in

@@ -1,19 +1,19 @@
 include(CMakeFindDependencyMacro)
 
-find_dependency(QtProtobufProject COMPONENTS QtProtobuf REQUIRED CONFIG)
+find_dependency(${QT_VERSIONED_PREFIX} COMPONENTS Network REQUIRED CONFIG)
 
 set(QT_PROTOBUF_NATIVE_GRPC_CHANNEL @QT_PROTOBUF_NATIVE_GRPC_CHANNEL@)
 if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    include("${CMAKE_CURRENT_LIST_DIR}/gRPCLookup.cmake")
+    find_dependency(Threads)
+    find_dependency(gRPC)
 endif()
 
-if(NOT TARGET @TARGET@ AND NOT @TARGET@_BINARY_DIR)
-    include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT@.cmake")
+if(NOT TARGET @QT_PROTOBUF_NAMESPACE@::@target@)
+    include("${CMAKE_CURRENT_LIST_DIR}/@target_export@.cmake")
 endif()
 
-if(QT_PROTOBUF_STATIC AND NOT TARGET @GRPC_QUICK_PLUGIN_NAME@ AND NOT @GRPC_QUICK_PLUGIN_NAME@_BINARY_DIR)
+if(QT_PROTOBUF_STATIC AND NOT TARGET @QT_PROTOBUF_NAMESPACE@::@GRPC_QUICK_PLUGIN_NAME@)
     include("${CMAKE_CURRENT_LIST_DIR}/@GRPC_QUICK_PLUGIN_NAME@Targets.cmake")
 endif()
 
 @PACKAGE_INIT@
-

+ 3 - 3
src/grpc/qt_lib_grpc.pri.in

@@ -1,9 +1,9 @@
 QT.grpc.VERSION = @QT_PROTOBUF_VERSION@
 QT.grpc.name = QtGrpc
 QT.grpc.module = QtGrpc
-QT.grpc.includes = @CMAKE_INSTALL_PREFIX@/@TARGET_INCLUDE_DIR@
-QT.grpc.private_includes =
-QT.grpc.libs = @CMAKE_INSTALL_PREFIX@/@TARGET_LIB_DIR@
+QT.protobuf.includes = @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@/QtGrpc
+QT.protobuf.private_includes =
+QT.protobuf.libs = @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
 QT.grpc.depends = core network protobuf
 QT.grpc.module_config = @QT_PROTOBUF_EXTRA_CONFIG@
 

+ 5 - 12
src/grpc/quick/CMakeLists.txt

@@ -4,15 +4,11 @@ set(TARGET_EXPORT ${TARGET}Targets)
 set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET})
 set(TARGET_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
 
-find_package(Qt5 COMPONENTS Core Qml REQUIRED)
-
 set(CMAKE_AUTOMOC ON)
 set(CMAKE_AUTOMOC_MOC_OPTIONS -Muri=QtGrpc)
 set(CMAKE_AUTORCC ON)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufCommon.cmake)
-
-extract_qt_variable(QT_INSTALL_QML)
+qt_protobuf_extract_qt_variable(QT_INSTALL_QML)
 
 set(TARGET_IMPORTS_DIR ${QT_INSTALL_QML}/QtGrpc)
 
@@ -27,13 +23,10 @@ file(GLOB HEADERS
 
 add_library(${TARGET} ${SOURCES})
 if(NOT BUILD_SHARED_LIBS)
-    if(WIN32)
-        message(WARNING "Static version of QtProtobuf is not fully tested on Win32 platforms")
-    endif()
     target_compile_definitions(${TARGET} PRIVATE QT_PROTOBUF_STATIC QT_STATICPLUGIN PUBLIC QT_GRPC_QUICK_PLUGIN_NAME="QtGrpcQuickPlugin")
 endif()
 
-target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QT_PROTOBUF_PROJECT}::QtGrpc)
+target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QT_PROTOBUF_NAMESPACE}::Grpc)
 set_target_properties(${TARGET} PROPERTIES
     LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/QtGrpc"
     RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/QtGrpc"
@@ -42,16 +35,16 @@ set_target_properties(${TARGET} PROPERTIES
 target_compile_definitions(${TARGET} PRIVATE QT_GRPC_QUICK_LIB)
 
 if(NOT BUILD_SHARED_LIBS)
-    add_library(${QT_PROTOBUF_PROJECT}::${TARGET} ALIAS ${TARGET})
+    add_library(${QT_PROTOBUF_NAMESPACE}::${TARGET} ALIAS ${TARGET})
     if(QT_PROTOBUF_INSTALL)
         install(TARGETS ${TARGET} COMPONENT lib
             EXPORT ${TARGET_EXPORT} COMPONENT dev
             ARCHIVE DESTINATION "${TARGET_IMPORTS_DIR}" COMPONENT lib
             RUNTIME DESTINATION "${TARGET_IMPORTS_DIR}" COMPONENT lib
             LIBRARY DESTINATION "${TARGET_IMPORTS_DIR}" COMPONENT lib)
-        install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
+        install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_NAMESPACE}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
     endif()
-    export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake)
+    export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_NAMESPACE}:: FILE ${TARGET_EXPORT}.cmake)
 else()
     if(QT_PROTOBUF_INSTALL)
         install(TARGETS ${TARGET} COMPONENT lib

+ 65 - 140
src/protobuf/CMakeLists.txt

@@ -1,16 +1,4 @@
-set(TARGET QtProtobuf)
-set(TARGET_EXPORT ${TARGET}Targets)
-set(TARGET_CONFIG ${TARGET}Config)
-
-set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET})
-set(TARGET_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
-set(TARGET_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
-set(TARGET_BINDIR ${CMAKE_INSTALL_BINDIR})
-
-find_package(Qt5 COMPONENTS Core Qml REQUIRED)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
+qt_protobuf_extract_qt_variable(QT_INSTALL_PLUGINS)
 
 if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/3rdparty/microjson/CMakeLists.txt")
     set(MICROJSON_MAKE_TESTS OFF)
@@ -21,141 +9,78 @@ else()
     message(FATAL_ERROR "microjson is not found.")
 endif()
 
-set(CMAKE_POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-include(${QT_PROTOBUF_CMAKE_DIR}/GenerateQtHeaders.cmake)
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufCommon.cmake)
-
-file(GLOB SOURCES
-    qtprotobuf.cpp
-    qtprotobuflogging.cpp
-    qprotobufserializerregistry.cpp
-    qabstractprotobufserializer.cpp
-    qprotobufjsonserializer.cpp
-    qprotobufserializer.cpp
-    qprotobufmetaproperty.cpp
-    qprotobufmetaobject.cpp)
-
-file(GLOB HEADERS
-    qtprotobufglobal.h
-    qtprotobuftypes.h
-    qtprotobuflogging.h
-    qprotobufobject.h
-    qprotobufserializerregistry_p.h
-    qqmllistpropertyconstructor.h
-    qabstractprotobufserializer.h
-    qabstractprotobufserializer_p.h
-    qprotobufserializer.h
-    qprotobufserializer_p.h
-    qprotobufjsonserializer.h
-    qprotobufselfcheckiterator.h
-    qprotobufmetaproperty.h
-    qprotobufmetaobject.h
-    qprotobufserializationplugininterface.h
-    qprotobuflazymessagepointer.h)
-
-file(GLOB PUBLIC_HEADER
-    qtprotobufglobal.h
-    qtprotobuftypes.h
-    qtprotobuflogging.h
-    qprotobufobject.h
-    qqmllistpropertyconstructor.h
-    qabstractprotobufserializer.h
-    qabstractprotobufserializer_p.h
-    qprotobufserializer.h
-    qprotobufjsonserializer.h
-    qprotobufselfcheckiterator.h
-    qprotobufmetaproperty.h
-    qprotobufmetaobject.h
-    qprotobufserializationplugininterface.h
-    qprotobuflazymessagepointer.h)
-
-protobuf_generate_qt_headers(PUBLIC_HEADER ${PUBLIC_HEADER} COMPONENT ${TARGET})
+qt_protobuf_internal_add_library(Protobuf
+    SOURCES
+        qtprotobuf.cpp
+        qtprotobuflogging.cpp
+        qprotobufserializerregistry.cpp
+        qabstractprotobufserializer.cpp
+        qprotobufjsonserializer.cpp
+        qprotobufserializer.cpp
+        qprotobufmetaproperty.cpp
+        qprotobufmetaobject.cpp
+        qtprotobufglobal.h
+        qtprotobuftypes.h
+        qtprotobuflogging.h
+        qprotobufobject.h
+        qprotobufserializerregistry_p.h
+        qqmllistpropertyconstructor.h
+        qabstractprotobufserializer.h
+        qabstractprotobufserializer_p.h
+        qprotobufserializer.h
+        qprotobufserializer_p.h
+        qprotobufjsonserializer.h
+        qprotobufselfcheckiterator.h
+        qprotobufmetaproperty.h
+        qprotobufmetaobject.h
+        qprotobufserializationplugininterface.h
+        qprotobuflazymessagepointer.h
+    PUBLIC_HEADER
+        qtprotobufglobal.h
+        qtprotobuftypes.h
+        qtprotobuflogging.h
+        qprotobufobject.h
+        qqmllistpropertyconstructor.h
+        qabstractprotobufserializer.h
+        qabstractprotobufserializer_p.h
+        qprotobufserializer.h
+        qprotobufjsonserializer.h
+        qprotobufselfcheckiterator.h
+        qprotobufmetaproperty.h
+        qprotobufmetaobject.h
+        qprotobufserializationplugininterface.h
+        qprotobuflazymessagepointer.h
+    PUBLIC_LIBRARIES
+        Qt5::Core
+        Qt5::Qml
+    PUBLIC_DEFINES
+        QT_PROTOBUF_PLUGIN_PATH="${QT_INSTALL_PLUGINS}/protobuf"
+)
 
-add_library(${TARGET} ${SOURCES})
+qtprotobuf_link_target(Protobuf microjson)
+set_target_properties(Protobuf PROPERTIES
+    QT_PROTOBUF_PLUGIN_PATH "${QT_INSTALL_PLUGINS}/protobuf"
+)
+set_property(TARGET Protobuf APPEND PROPERTY EXPORT_PROPERTIES QT_PROTOBUF_PLUGIN_PATH)
 
-set(QT_PROTOBUF_STATIC OFF CACHE INTERNAL "")
 if(NOT BUILD_SHARED_LIBS)
-    set(QT_PROTOBUF_STATIC ON CACHE INTERNAL "" FORCE)
-    if(WIN32)
-        message(WARNING "Static version of ${TARGET} is not fully tested on Win32 platforms")
-    endif()
-    target_compile_definitions(${TARGET} PUBLIC QT_PROTOBUF_STATIC)
     set(QT_PROTOBUF_EXTRA_COMPILE_DIFINITIONS QT_PROTOBUF_STATIC)
-    set(QT_PROTOBUF_EXTRA_CONFIG "staticlib") #extra config for .pri file in case if static build enabled
-endif()
-
-if(NOT DEFINED QT_QMAKE_EXECUTABLE)
-    find_program(QT_QMAKE_EXECUTABLE "qmake" NO_DEFAULT_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
-    if(QT_QMAKE_EXECUTABLE STREQUAL QT_QMAKE_EXECUTABLE-NOTFOUND)
-        find_program(QT_QMAKE_EXECUTABLE "qmake")
-        if(QT_QMAKE_EXECUTABLE STREQUAL QT_QMAKE_EXECUTABLE-NOTFOUND)
-            message(FATAL_ERROR "Could not find qmake executable")
-        else()
-            message(STATUS "Use qmake ${QT_QMAKE_EXECUTABLE}")
-        endif()
-    else()
-        message(STATUS "Use qmake ${QT_QMAKE_EXECUTABLE}")
-    endif()
+    set(QT_PROTOBUF_EXTRA_CONFIG "staticlib") # extra config for .pri file in case if static
+                                              # build enabled
 endif()
 
-extract_qt_variable(QT_INSTALL_PLUGINS)
-extract_qt_variable(QT_HOST_DATA)
-
-set_target_properties(${TARGET} PROPERTIES QT_PROTOBUF_PLUGIN_PATH "${QT_INSTALL_PLUGINS}/protobuf")
-target_compile_definitions(${TARGET} PUBLIC QT_PROTOBUF_PLUGIN_PATH="${QT_INSTALL_PLUGINS}/protobuf")
-
-target_compile_definitions(${TARGET} PRIVATE QT_BUILD_PROTOBUF_LIB PUBLIC QT_PROTOBUF_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
-    QT_PROTOBUF_VERSION_MINOR=${PROJECT_VERSION_MINOR})
-
-set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} PUBLIC_HEADER "${PUBLIC_HEADER};${GENERATED_PUBLIC_HEADER}" OUTPUT_NAME ${TARGET})
-target_include_directories(${TARGET} PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-    $<BUILD_INTERFACE:${QT_PROTOBUF_BINARY_DIR}/include/${TARGET}>
-    $<INSTALL_INTERFACE:${TARGET_INCLUDE_DIR}>
-    PRIVATE
-    $<TARGET_PROPERTY:microjson,INCLUDE_DIRECTORIES>
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/qt_lib_protobuf.pri.in"
+    "${QT_PROTOBUF_BINARY_DIR}/qt_lib_protobuf.pri" @ONLY
 )
-add_dependencies(${TARGET} microjson)
-
-target_compile_features(${TARGET} PUBLIC cxx_std_14
-                                         cxx_auto_type
-                                         cxx_decltype
-                                         cxx_final
-                                         cxx_override
-                                         cxx_nullptr
-                                         cxx_lambdas
-                                         cxx_func_identifier)
-
-target_link_libraries(${TARGET} PUBLIC Qt5::Core Qt5::Qml PRIVATE $<TARGET_OBJECTS:microjson>)
-
-add_library(${QT_PROTOBUF_PROJECT}::${TARGET} ALIAS ${TARGET})
-
-include(CMakePackageConfigHelpers)
-configure_package_config_file(
-    "${TARGET_CONFIG}.cmake.in" "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake"
-    INSTALL_DESTINATION "${TARGET_CMAKE_DIR}")
-
-set(QT_PROTOBUF_EXECUTABLE_INSTALL ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/${GENERATOR_TARGET})
-
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/qt_lib_protobuf.pri.in" "${QT_PROTOBUF_BINARY_DIR}/qt_lib_protobuf.pri" @ONLY)
 
 if(QT_PROTOBUF_INSTALL)
-    install(TARGETS ${TARGET}
-        EXPORT ${TARGET_EXPORT} COMPONENT dev
-        ARCHIVE DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        PUBLIC_HEADER DESTINATION ${TARGET_INCLUDE_DIR} COMPONENT dev
-        LIBRARY DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        RUNTIME DESTINATION ${TARGET_BINDIR} COMPONENT lib)
-    install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
-    install(FILES "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake" DESTINATION "${TARGET_CMAKE_DIR}" COMPONENT dev)
-    install(FILES "${QT_PROTOBUF_BINARY_DIR}/qt_lib_protobuf.pri" DESTINATION "${QT_HOST_DATA}/mkspecs/modules" COMPONENT dev)
+    qt_protobuf_extract_qt_variable(QT_HOST_DATA)
+    install(FILES "${QT_PROTOBUF_BINARY_DIR}/qt_lib_protobuf.pri"
+        DESTINATION "${CMAKE_INSTAL_PREFIX}${QT_HOST_DATA}/mkspecs/modules"
+        COMPONENT dev
+    )
 endif()
 
-export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake)
-
-add_subdirectory("quick")
-
-add_coverage_target(TARGET ${TARGET})
+if(TARGET Qt5::Quick)
+    add_subdirectory("quick")
+endif()

+ 5 - 11
src/protobuf/QtProtobufConfig.cmake.in

@@ -1,19 +1,14 @@
 include(CMakeFindDependencyMacro)
 
-set(QT_PROTOBUF_STATIC @QT_PROTOBUF_STATIC@)
+find_package(${QT_VERSIONED_PREFIX} COMPONENTS Core Qml REQUIRED CONFIG)
 
-find_dependency(Qt5 COMPONENTS Core Qml REQUIRED CONFIG)
-find_dependency(QtProtobufProject COMPONENTS Generator CONFIG REQUIRED)
+set(CMAKE_POSITION_INDEPENDENT_CODE ${${QT_VERSIONED_PREFIX}_POSITION_INDEPENDENT_CODE})
 
-set(CMAKE_POSITION_INDEPENDENT_CODE @Qt5_POSITION_INDEPENDENT_CODE@)
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-if(NOT TARGET @TARGET@ AND NOT @TARGET@_BINARY_DIR)
-    include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT@.cmake")
+if(NOT TARGET @QT_PROTOBUF_NAMESPACE@::@target@)
+    include("${CMAKE_CURRENT_LIST_DIR}/@target_export@.cmake")
 endif()
 
-if(QT_PROTOBUF_STATIC AND NOT TARGET @PROTOBUF_QUICK_PLUGIN_NAME@ AND NOT @PROTOBUF_QUICK_PLUGIN_NAME@_BINARY_DIR)
+if(QT_PROTOBUF_STATIC AND NOT TARGET @QT_PROTOBUF_NAMESPACE@::@PROTOBUF_QUICK_PLUGIN_NAME@)
     include("${CMAKE_CURRENT_LIST_DIR}/@PROTOBUF_QUICK_PLUGIN_NAME@Targets.cmake")
 endif()
 
@@ -22,4 +17,3 @@ if(QT_PROTOBUF_STATIC)
     add_definitions(-DQT_PROTOBUF_STATIC)# add_definitions is used because old cmake versions
                                          # compatibility
 endif()
-

+ 5 - 4
src/protobuf/qt_lib_protobuf.pri.in

@@ -1,9 +1,9 @@
 QT.protobuf.VERSION = @QT_PROTOBUF_VERSION@
 QT.protobuf.name = QtProtobuf
 QT.protobuf.module = QtProtobuf
-QT.protobuf.includes = @CMAKE_INSTALL_PREFIX@/@TARGET_INCLUDE_DIR@
+QT.protobuf.includes = @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@/QtProtobuf
 QT.protobuf.private_includes =
-QT.protobuf.libs = @CMAKE_INSTALL_PREFIX@/@TARGET_LIB_DIR@
+QT.protobuf.libs = @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
 QT.protobuf.depends = core qml
 QT.protobuf.module_config = @QT_PROTOBUF_EXTRA_CONFIG@
 
@@ -24,8 +24,9 @@ defineTest(qtprotobuf_generate) {
 
     GENERATED_OUT_DIR = $$OUT_PWD/generated
     system("mkdir $$GENERATED_OUT_DIR")
-    message("QT_PROTOBUF_OPTIONS=$$GENERATOR_OPTIONS protoc --plugin=protoc-gen-@GENERATOR_TARGET@=@QT_PROTOBUF_EXECUTABLE_INSTALL@ --@GENERATOR_TARGET@_out=$$GENERATED_OUT_DIR $$PROTO_INCLUDES_PRIV $$PROTO_FILES_PRIV")
-    system("QT_PROTOBUF_OPTIONS=$$GENERATOR_OPTIONS protoc --plugin=protoc-gen-@GENERATOR_TARGET@=@QT_PROTOBUF_EXECUTABLE_INSTALL@ --@GENERATOR_TARGET@_out=$$GENERATED_OUT_DIR $$PROTO_INCLUDES_PRIV $$PROTO_FILES_PRIV"):OK=true
+    protoc_command_line = "QT_PROTOBUF_OPTIONS=$$GENERATOR_OPTIONS protoc --plugin=protoc-gen-qtprotobufgen=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/qtprotobufgen --qtprotobufgen_out=$$GENERATED_OUT_DIR $$PROTO_INCLUDES_PRIV $$PROTO_FILES_PRIV"
+    message("$$protoc_command_line")
+    system("$$protoc_command_line"):OK=true
     SOURCES += $$files($$GENERATED_OUT_DIR/*.cpp)
     HEADERS += $$files($$GENERATED_OUT_DIR/*.h)
     INCLUDEPATH += $$GENERATED_OUT_DIR

+ 6 - 13
src/protobuf/quick/CMakeLists.txt

@@ -4,15 +4,11 @@ set(TARGET_EXPORT ${TARGET}Targets)
 set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET})
 set(TARGET_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
 
-find_package(Qt5 COMPONENTS Core Qml REQUIRED)
-
 set(CMAKE_AUTOMOC ON)
 set(CMAKE_AUTOMOC_MOC_OPTIONS -Muri=QtProtobuf)
 set(CMAKE_AUTORCC ON)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufCommon.cmake)
-
-extract_qt_variable(QT_INSTALL_QML)
+qt_protobuf_extract_qt_variable(QT_INSTALL_QML)
 
 set(TARGET_IMPORTS_DIR ${QT_INSTALL_QML}/QtProtobuf)
 
@@ -26,13 +22,10 @@ file(GLOB HEADERS
 add_library(${TARGET} ${SOURCES})
 
 if(NOT BUILD_SHARED_LIBS)
-    if(WIN32)
-        message(WARNING "Static version of QtProtobuf is not fully tested on Win32 platforms")
-    endif()
-    target_compile_definitions(${TARGET} PUBLIC QT_STATICPLUGIN QT_PROTOBUF_QUICK_PLUGIN_NAME="QtProtobufQuickPlugin")
+    target_compile_definitions(${TARGET} PUBLIC QT_PROTOBUF_STATIC QT_STATICPLUGIN QT_PROTOBUF_QUICK_PLUGIN_NAME="QtProtobufQuickPlugin")
 endif()
 
-target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QT_PROTOBUF_PROJECT}::QtProtobuf)
+target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QT_PROTOBUF_NAMESPACE}::Protobuf)
 set_target_properties(${TARGET} PROPERTIES
     LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/QtProtobuf"
     RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/QtProtobuf"
@@ -55,16 +48,16 @@ endforeach()
 target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ ${Qt5Qml_PRIVATE_INCLUDE_DIRS})
 
 if(NOT BUILD_SHARED_LIBS)
-    add_library(${QT_PROTOBUF_PROJECT}::${TARGET} ALIAS ${TARGET})
+    add_library(${QT_PROTOBUF_NAMESPACE}::${TARGET} ALIAS ${TARGET})
     if(QT_PROTOBUF_INSTALL)
         install(TARGETS ${TARGET} COMPONENT lib
             EXPORT ${TARGET_EXPORT} COMPONENT dev
             ARCHIVE DESTINATION "${TARGET_IMPORTS_DIR}" COMPONENT lib
             RUNTIME DESTINATION "${TARGET_IMPORTS_DIR}" COMPONENT lib
             LIBRARY DESTINATION "${TARGET_IMPORTS_DIR}" COMPONENT lib)
-        install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
+        install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_NAMESPACE}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
     endif()
-    export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake)
+    export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_NAMESPACE}:: FILE ${TARGET_EXPORT}.cmake)
 else()
     if(QT_PROTOBUF_INSTALL)
         install(TARGETS ${TARGET} COMPONENT lib

+ 1 - 1
src/protobuf/quick/qtprotobufquickplugin.h

@@ -66,7 +66,7 @@
  * \code
  * ...
  * if(QT_PROTOBUF_STATIC)
- *     target_link_libraries(${TARGET} PRIVATE QtProtobufProject::protobufquickplugin)
+ *     target_link_libraries(${TARGET} PRIVATE QtProtobuf::protobufquickplugin)
  * endif()
  * ...
  * \endcode

+ 32 - 88
src/qttypes/CMakeLists.txt

@@ -1,97 +1,41 @@
-set(TARGET QtProtobufQtTypes)
-set(TARGET_EXPORT ${TARGET}Targets)
-set(TARGET_CONFIG ${TARGET}Config)
-
-set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/QtProtobuf)
-set(TARGET_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
-set(TARGET_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
-set(TARGET_BINDIR ${CMAKE_INSTALL_BINDIR})
-
-find_package(Qt5 COMPONENTS Core Gui Qml REQUIRED)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-
-if(NOT TARGET ${GENERATOR_TARGET})
-    find_package(QtProtobufProject COMPONENTS Generator CONFIG REQUIRED)
-else()
-    include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufGen.cmake)
-endif()
-
-set(CMAKE_POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-include(${QT_PROTOBUF_CMAKE_DIR}/GenerateQtHeaders.cmake)
-
-file(GLOB SOURCES
-    qtprotobufqttypes.cpp)
-
-file(GLOB HEADERS
-    qtprotobufqttypes.h
-    qtprotobufqttypesglobal.h)
-
-
-protobuf_generate_qt_headers(PUBLIC_HEADER ${HEADERS} COMPONENT QtProtobuf)
-
-add_library(${TARGET} ${SOURCES})
-
-if(NOT BUILD_SHARED_LIBS)
-    if(WIN32)
-        message(WARNING "Static version of ${TARGET} is not fully tested on Win32 platforms")
-    endif()
-    target_compile_definitions(${TARGET} PUBLIC QT_PROTOBUF_STATIC)
-endif()
+qt_protobuf_internal_add_library(ProtobufQtTypes
+    SOURCES
+        qtprotobufqttypes.cpp
+    PUBLIC_HEADER
+        qtprotobufqttypes.h
+        qtprotobufqttypesglobal.h
+    PUBLIC_INCLUDE_DIRECTORIES
+        "$<BUILD_INTERFACE:${QT_PROTOBUF_BINARY_DIR}/include/QtProtobuf>"
+        "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/generated>"
+    PUBLIC_LIBRARIES
+        Qt5::Core
+        Qt5::Gui
+        Qt5::Qml
+        ${QT_PROTOBUF_NAMESPACE}::Protobuf
+)
+
+set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}/QtProtobuf)
 
 file(GLOB PROTO_FILE ${CMAKE_CURRENT_SOURCE_DIR}/QtProtobuf/Qt*.proto)
-qtprotobuf_generate(TARGET ${TARGET}
+qtprotobuf_generate(TARGET ProtobufQtTypes
     OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated
     PROTO_FILES ${PROTO_FILE}
-    QML FOLDER ${EXTRA_TYPE_LIBRARIES_OPTIONS})
-
-target_compile_definitions(${TARGET} PRIVATE QT_BUILD_PROTOBUF_QT_TYPES_LIB PUBLIC QT_PROTOBUF_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
-    QT_PROTOBUF_VERSION_MINOR=${PROJECT_VERSION_MINOR})
-
-set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} OUTPUT_NAME ${TARGET}
-    PROTO_INCLUDES "-I\"${CMAKE_CURRENT_SOURCE_DIR}\"" PUBLIC_HEADER "${HEADERS};${GENERATED_PUBLIC_HEADER}")
-
-target_compile_features(${TARGET} PUBLIC cxx_std_14
-    cxx_auto_type
-    cxx_decltype
-    cxx_final
-    cxx_override
-    cxx_nullptr
-    cxx_lambdas
-    cxx_func_identifier)
+    QML FOLDER ${extra_type_libraries_options})
 
-target_include_directories(${TARGET} PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/generated>
-    $<BUILD_INTERFACE:${QT_PROTOBUF_BINARY_DIR}/include/QtProtobuf>
-    $<INSTALL_INTERFACE:${TARGET_INCLUDE_DIR}>
-    )
-
-add_library(${QT_PROTOBUF_PROJECT}::${TARGET} ALIAS ${TARGET})
+target_compile_definitions(ProtobufQtTypes PRIVATE QT_BUILD_PROTOBUF_QT_TYPES_LIB)
 
-target_link_libraries(${TARGET} PUBLIC Qt5::Core Qt5::Gui Qt5::Qml ${QT_PROTOBUF_PROJECT}::QtProtobuf)
+set_target_properties(ProtobufQtTypes PROPERTIES
+    PROTO_INCLUDES
+        "-I\"${CMAKE_CURRENT_SOURCE_DIR}\";-I\"${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDEDIR}\""
+)
 
-include(CMakePackageConfigHelpers)
-configure_package_config_file(
-    "${TARGET_CONFIG}.cmake.in" "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake"
-    INSTALL_DESTINATION "${TARGET_CMAKE_DIR}")
+set_property(TARGET ProtobufQtTypes APPEND PROPERTY EXPORT_PROPERTIES PROTO_INCLUDES)
 
 if(QT_PROTOBUF_INSTALL)
-    install(TARGETS ${TARGET}
-        EXPORT ${TARGET_EXPORT} COMPONENT dev
-        ARCHIVE DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        PUBLIC_HEADER DESTINATION ${TARGET_INCLUDE_DIR} COMPONENT dev
-        LIBRARY DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        RUNTIME DESTINATION ${TARGET_BINDIR} COMPONENT lib)
-    install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
-    install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/QtProtobuf/QtCore.proto ${CMAKE_CURRENT_SOURCE_DIR}/QtProtobuf/QtGui.proto DESTINATION "${TARGET_INCLUDE_DIR}" COMPONENT dev)
-    install(FILES "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake" DESTINATION "${TARGET_CMAKE_DIR}" COMPONENT dev)
-endif()
-
-export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake)
-
-add_coverage_target(TARGET ${TARGET})
+    install(FILES
+                "${CMAKE_CURRENT_SOURCE_DIR}/QtProtobuf/QtCore.proto"
+                "${CMAKE_CURRENT_SOURCE_DIR}/QtProtobuf/QtGui.proto"
+            DESTINATION "${INSTALL_INCLUDEDIR}"
+            COMPONENT dev
+    )
+endif()

+ 3 - 4
src/qttypes/QtProtobufQtTypesConfig.cmake.in

@@ -1,10 +1,9 @@
 include(CMakeFindDependencyMacro)
 
-find_dependency(Qt5 COMPONENTS Network REQUIRED CONFIG)
-find_dependency(QtProtobufProject COMPONENTS QtProtobuf REQUIRED CONFIG)
+find_dependency(${QT_VERSIONED_PREFIX} COMPONENTS Gui REQUIRED CONFIG)
 
-if(NOT TARGET @TARGET@ AND NOT @TARGET@_BINARY_DIR)
-    include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT@.cmake")
+if(NOT TARGET @QT_PROTOBUF_NAMESPACE@::@target@)
+    include("${CMAKE_CURRENT_LIST_DIR}/@target_export@.cmake")
 endif()
 
 @PACKAGE_INIT@

+ 3 - 3
src/qttypes/qtprotobufqttypes.h

@@ -66,12 +66,12 @@
  *
  * \subsubsection Usage
  *
- * To enable Qt types support add QtProtobufQtTypes as dependency to CMake project:
+ * To enable Qt types support add ProtobufQtTypes as dependency to CMake project:
  * \code
  * ...
- * find_package(QtProtobufProject CONFIG COMPONENTS QtProtobuf QtProtobufQtTypes REQUIRED)
+ * find_package(QtProtobuf CONFIG COMPONENTS Protobuf ProtobufQtTypes REQUIRED)
  * ... #After target creation
- * target_link_libraries(${TARGET} PRIVATE ${QT_PROTOBUF_PROJECT}::QtProtobufQtTypes)
+ * target_link_libraries(${TARGET} PRIVATE ${QT_PROTOBUF_NAMESPACE}::ProtobufQtTypes)
  * \endcode
  *
  * Starting from this point you are almost complete preparation. Unlike automatical registration of generated code, QtProtobufQtTypes requires additional intialization step.

+ 1 - 1
src/qttypes/qtprotobufqttypesglobal.h

@@ -28,7 +28,7 @@
 #include <QtCore/QtGlobal>
 
 #ifndef QT_PROTOBUF_STATIC
-    #if defined(QT_BUILD_PROTOBUF_QT_TYPES_LIB)
+    #if defined(QT_BUILD_PROTOBUFQTTYPES_LIB)
         #define Q_PROTOBUF_QT_TYPES_EXPORT Q_DECL_EXPORT
     #else
         #define Q_PROTOBUF_QT_TYPES_EXPORT Q_DECL_IMPORT

+ 21 - 86
src/wellknowntypes/CMakeLists.txt

@@ -1,31 +1,14 @@
-set(TARGET QtProtobufWellKnownTypes)
-set(TARGET_EXPORT ${TARGET}Targets)
-set(TARGET_CONFIG ${TARGET}Config)
-
-set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/QtProtobuf/google/protobuf)
-set(TARGET_LIB_DIR ${CMAKE_INSTALL_LIBDIR})
-set(TARGET_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
-set(TARGET_BINDIR ${CMAKE_INSTALL_BINDIR})
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-
-find_package(Qt5 COMPONENTS Core Qml REQUIRED)
-find_package(Protobuf QUIET)
-if(NOT TARGET ${GENERATOR_TARGET})
-    find_package(QtProtobufProject COMPONENTS Generator CONFIG REQUIRED)
-else()
-    include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufGen.cmake)
-endif()
-
-set(CMAKE_POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE})
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-include(${QT_PROTOBUF_CMAKE_DIR}/GenerateQtHeaders.cmake)
-
-file(GLOB SOURCES
-    dummy.cpp)
+qt_protobuf_internal_add_library(ProtobufWellKnownTypes
+    SOURCES
+        dummy.cpp
+    PUBLIC_INCLUDE_DIRECTORIES
+        "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/generated>"
+        "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/QtProtobuf/google/protobuf>"
+    PUBLIC_LIBRARIES
+        Qt5::Core
+        Qt5::Qml
+        ${QT_PROTOBUF_NAMESPACE}::Protobuf
+)
 
 function(add_wellknowntype TYPENAME)
     list(APPEND LOOKUP_DIRS ${QT_PROTOBUF_SOURCE_DIR}/3rdparty/grpc/third_party/protobuf/src)
@@ -34,13 +17,13 @@ function(add_wellknowntype TYPENAME)
         file(GLOB PROTO_FILE ${INCLUDE_DIR}/google/protobuf/${TYPENAME}.proto)
         if(NOT "${PROTO_FILE}" STREQUAL "")
             message(STATUS "Add well-known type ${PROTO_FILE}")
-            qtprotobuf_generate(TARGET ${TARGET} GENERATED_TARGET ${TYPENAME}
+            qtprotobuf_generate(TARGET ProtobufWellKnownTypes GENERATED_TARGET ${TYPENAME}
                 OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated
                 PROTO_FILES ${PROTO_FILE}
                 PROTO_INCLUDES "-I\"${INCLUDE_DIR}\""
-                QML FOLDER ${EXTRA_TYPE_LIBRARIES_OPTIONS})
+                QML FOLDER ${extra_type_libraries_options})
             target_include_directories(${TYPENAME} PRIVATE
-                $<TARGET_PROPERTY:${QT_PROTOBUF_PROJECT}::QtProtobufWellKnownTypes,INTERFACE_INCLUDE_DIRECTORIES>)
+                $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes,INTERFACE_INCLUDE_DIRECTORIES>)
             get_target_property(GENERATED_PUBLIC_HEADER_PRIVATE ${TYPENAME} PUBLIC_HEADER)
             set(GENERATED_PUBLIC_HEADER "${GENERATED_PUBLIC_HEADER};${GENERATED_PUBLIC_HEADER_PRIVATE}" PARENT_SCOPE)
             break()
@@ -51,8 +34,6 @@ function(add_wellknowntype TYPENAME)
     endif()
 endfunction()
 
-add_library(${TARGET} ${SOURCES})
-
 add_wellknowntype(any)
 add_wellknowntype(duration)
 add_wellknowntype(empty)
@@ -61,62 +42,16 @@ add_wellknowntype(source_context)
 add_wellknowntype(struct)
 add_wellknowntype(timestamp)
 add_wellknowntype(wrappers)
-
 add_wellknowntype(type)
 add_dependencies(type any source_context)
 add_wellknowntype(api)
 add_dependencies(api type source_context)
 
-
-target_compile_definitions(${TARGET} PRIVATE QT_BUILD_PROTOBUF_WELLKNOWNTYPES_LIB PUBLIC QT_PROTOBUF_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
-    QT_PROTOBUF_VERSION_MINOR=${PROJECT_VERSION_MINOR})
-
-set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} PUBLIC_HEADER "${GENERATED_PUBLIC_HEADER}" OUTPUT_NAME ${TARGET}
-    PROTO_INCLUDES "-I\"${QT_PROTOBUF_SOURCE_DIR}/3rdparty/grpc/third_party/protobuf/src\"")
-
-target_compile_features(${TARGET} PUBLIC cxx_std_14
-    cxx_auto_type
-    cxx_decltype
-    cxx_final
-    cxx_override
-    cxx_nullptr
-    cxx_lambdas
-    cxx_func_identifier)
-
-target_include_directories(${TARGET} PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/generated>
-    $<BUILD_INTERFACE:${QT_PROTOBUF_BINARY_DIR}/include/${TARGET}>
-    $<INSTALL_INTERFACE:${TARGET_INCLUDE_DIR}>
-    )
-
-add_library(${QT_PROTOBUF_PROJECT}::${TARGET} ALIAS ${TARGET})
-
-if(NOT BUILD_SHARED_LIBS)
-    if(WIN32)
-        message(WARNING "Static version of ${TARGET} is not fully tested on Win32 platforms")
-    endif()
-    target_compile_definitions(${TARGET} PUBLIC QT_PROTOBUF_STATIC)
+# TODO: Check if 3rdparty protobuf module is initialized
+if(EXISTS "${QT_PROTOBUF_SOURCE_DIR}/3rdparty/grpc/third_party/protobuf/src")
+    set_target_properties(ProtobufWellKnownTypes PROPERTIES
+        PROTO_INCLUDES "-I\"${QT_PROTOBUF_SOURCE_DIR}/3rdparty/grpc/third_party/protobuf/src\"")
+elseif(Protobuf_INCLUDE_DIRS)
+    set_target_properties(ProtobufWellKnownTypes PROPERTIES
+        PROTO_INCLUDES "-I\"${Protobuf_INCLUDE_DIRS}\"")
 endif()
-
-target_link_libraries(${TARGET} PUBLIC Qt5::Core Qt5::Qml ${QT_PROTOBUF_PROJECT}::QtProtobuf)
-
-include(CMakePackageConfigHelpers)
-configure_package_config_file(
-    "${TARGET_CONFIG}.cmake.in" "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake"
-    INSTALL_DESTINATION "${TARGET_CMAKE_DIR}")
-
-if(QT_PROTOBUF_INSTALL)
-    install(TARGETS ${TARGET}
-        EXPORT ${TARGET_EXPORT} COMPONENT dev
-        ARCHIVE DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        PUBLIC_HEADER DESTINATION ${TARGET_INCLUDE_DIR} COMPONENT dev
-        LIBRARY DESTINATION ${TARGET_LIB_DIR} COMPONENT lib
-        RUNTIME DESTINATION ${TARGET_BINDIR} COMPONENT lib)
-    install(EXPORT ${TARGET_EXPORT} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake DESTINATION ${TARGET_CMAKE_DIR} COMPONENT dev)
-    install(FILES "${QT_PROTOBUF_BINARY_DIR}/${TARGET_CONFIG}.cmake" DESTINATION "${TARGET_CMAKE_DIR}" COMPONENT dev)
-endif()
-
-export(TARGETS ${TARGET} NAMESPACE ${QT_PROTOBUF_PROJECT}:: FILE ${TARGET_EXPORT}.cmake)
-
-add_coverage_target(TARGET ${TARGET})

+ 14 - 3
src/wellknowntypes/QtProtobufWellKnownTypesConfig.cmake.in

@@ -1,9 +1,20 @@
 include(CMakeFindDependencyMacro)
+find_dependency(WrapProtobuf REQUIRED)
 
-find_dependency(QtProtobufProject COMPONENTS QtProtobuf REQUIRED CONFIG)
+if(NOT TARGET @QT_PROTOBUF_NAMESPACE@::@target@)
+    include("${CMAKE_CURRENT_LIST_DIR}/@target_export@.cmake")
+endif()
+
+# Make possible usage of
+# $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes,PROTO_INCLUDES>
+# outside the build tree. Expecting that WrapProtobuf sets Protobuf_INCLUDE_DIRS.
 
-if(NOT TARGET @TARGET@ AND NOT @TARGET@_BINARY_DIR)
-    include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT@.cmake")
+if(DEFINED Protobuf_INCLUDE_DIRS)
+    string(JOIN " -I" proto_includes ${Protobuf_INCLUDE_DIRS})
 endif()
 
+set_target_properties(@QT_PROTOBUF_NAMESPACE@::@target@ PROPERTIES
+    PROTO_INCLUDES "-I${proto_includes}"
+)
+
 @PACKAGE_INIT@

+ 2 - 2
src/wellknowntypes/dummy.cpp

@@ -92,9 +92,9 @@
  * ...
  * \endcode
  *
- * In both scenarious you also need to link QtProtobufWellKnownTypes library by adding following lines to
+ * In both scenarious you also need to link QtProtobuf WellKnownTypes library by adding following lines to
  * **CMakeLists.txt** for your target.
  * \code
- *     target_link_libraries(YourTargetName PRIVATE QtProtobufProject::QtProtobufWellKnownTypes)
+ *     target_link_libraries(YourTargetName PRIVATE QtProtobuf::ProtobufWellKnownTypes)
  * \endcode
  */

+ 24 - 5
tests/CMakeLists.txt

@@ -1,12 +1,31 @@
+include(QtProtobufTestHelpers)
+
 add_subdirectory("test_protobuf")
-add_subdirectory("test_qml")
+if(TARGET ${QT_VERSIONED_PREFIX}::QuickTest)
+    add_subdirectory("test_qml")
+endif()
 add_subdirectory("test_protobuf_multifile")
 add_subdirectory("test_qprotobuf_serializer_plugin")
-add_subdirectory("test_wellknowntypes")
-add_subdirectory("test_qttypes")
-if(gRPC_FOUND)
+
+if(TARGET ${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes)
+    add_subdirectory("test_wellknowntypes")
+endif()
+
+if(TARGET ${QT_PROTOBUF_NAMESPACE}::ProtobufQtTypes)
+    add_subdirectory("test_qttypes")
+endif()
+
+if(WrapgRPC_FOUND AND TARGET ${QT_PROTOBUF_NAMESPACE}::Grpc)
+    if(UNIX)
+        set(TEST_DRIVER_NAME "test_driver.sh")
+    elseif(WIN32)
+        set(TEST_DRIVER_NAME "test_driver.bat")
+    endif()
+
     add_subdirectory("test_grpc")
-    add_subdirectory("test_grpc_qml")
+    if(TARGET ${QT_VERSIONED_PREFIX}::QuickTest)
+        add_subdirectory("test_grpc_qml")
+    endif()
 else()
     message(WARNING "gRPC not found: some tests cannot be built.")
 endif()

+ 4 - 11
tests/test_grpc/CMakeLists.txt

@@ -1,15 +1,14 @@
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 
 # clients
-qt_protobuf_internal_add_test_target(TARGET qtgrpc_test
+qt_protobuf_internal_add_test(TARGET qtgrpc_test
     SOURCES clienttest.cpp QML)
-add_target_windeployqt(TARGET qtgrpc_test
+qt_protobuf_internal_add_target_windeployqt(TARGET qtgrpc_test
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
-qt_protobuf_internal_add_test_target(TARGET qtgrpc_secure_test
+qt_protobuf_internal_add_test(TARGET qtgrpc_secure_test
     SOURCES sslclienttest.cpp)
-add_target_windeployqt(TARGET qtgrpc_secure_test
+qt_protobuf_internal_add_target_windeployqt(TARGET qtgrpc_secure_test
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
 # servers
@@ -18,12 +17,6 @@ add_subdirectory(secureechoserver)
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testfile ${CMAKE_CURRENT_BINARY_DIR}/testfile COPYONLY)
 
-if(UNIX)
-    set(TEST_DRIVER_NAME "test_driver.sh")
-elseif(WIN32)
-    set(TEST_DRIVER_NAME "test_driver.bat")
-endif()
-
 configure_file(${TEST_DRIVER_NAME}.in ${TEST_DRIVER_NAME} @ONLY)
 add_test(NAME qtgrpc_echo_test
          COMMAND ${TEST_DRIVER_NAME} $<TARGET_FILE:qtgrpc_test> $<TARGET_FILE:echoserver> $<TARGET_FILE_NAME:qtgrpc_test> $<TARGET_FILE_NAME:echoserver>

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

@@ -14,6 +14,6 @@ if(MSVC)
    target_compile_definitions(${TARGET} PRIVATE _WIN32_WINNT=0x600 _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS)
 endif()
 file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../proto/*.proto)
-protobuf_generate_all(TARGET ${TARGET}
+qt_protobuf_internal_protobuf_generate_all(TARGET ${TARGET}
     GENERATED_SOURCES ${GENERATED_SOURCES}
     PROTO_FILES ${PROTO_FILES})

+ 2 - 2
tests/test_grpc/secureechoserver/CMakeLists.txt

@@ -14,8 +14,8 @@ if(MSVC)
    target_compile_definitions(${TARGET} PRIVATE _WIN32_WINNT=0x600 _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS)
 endif()
 file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../proto/*.proto)
-protobuf_generate_all(TARGET ${TARGET}
+qt_protobuf_internal_protobuf_generate_all(TARGET ${TARGET}
     GENERATED_SOURCES ${GENERATED_SOURCES}
     PROTO_FILES ${PROTO_FILES})
-    
+
 file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cert.pem ${CMAKE_CURRENT_SOURCE_DIR}/key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

+ 20 - 58
tests/test_grpc_qml/CMakeLists.txt

@@ -1,6 +1,4 @@
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
-find_package(Qt5 COMPONENTS Quick QuickTest REQUIRED)
 
 set(CMAKE_AUTOMOC OFF)
 
@@ -9,76 +7,40 @@ file(GLOB QML_FILES qml/tst_grpc.qml)
 qt5_wrap_cpp(MOC_SOURCES test.h)
 
 add_executable(qtgrpc_qml_test_http2 ${MOC_SOURCES} http2.cpp ${QML_FILES})
-if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    add_executable(qtgrpc_qml_test_grpc_http ${MOC_SOURCES} grpc_http.cpp ${QML_FILES})
-    add_executable(qtgrpc_qml_test_grpc_socket ${MOC_SOURCES} grpc_socket.cpp ${QML_FILES})
-endif()
-
-target_link_libraries(qtgrpc_qml_test_http2 PRIVATE Qt5::Qml Qt5::Quick Qt5::Test Qt5::QuickTest QtProtobufProject::QtGrpc)
-if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    target_link_libraries(qtgrpc_qml_test_grpc_http PRIVATE Qt5::Qml Qt5::Quick Qt5::Test Qt5::QuickTest QtProtobufProject::QtGrpc)
-    target_link_libraries(qtgrpc_qml_test_grpc_socket PRIVATE Qt5::Qml Qt5::Quick Qt5::Test Qt5::QuickTest QtProtobufProject::QtGrpc)
-endif()
+target_link_libraries(qtgrpc_qml_test_http2
+    PRIVATE
+        ${QT_VERSIONED_PREFIX}::Qml
+        ${QT_VERSIONED_PREFIX}::Quick
+        ${QT_VERSIONED_PREFIX}::Test
+        ${QT_VERSIONED_PREFIX}::QuickTest
+        ${QT_PROTOBUF_NAMESPACE}::Grpc
+)
+qtprotobuf_link_target(qtgrpc_qml_test_http2 qtgrpc_test_qtprotobuf_gen)
 
 if(QT_PROTOBUF_STATIC)
     target_link_libraries(qtgrpc_qml_test_http2 PRIVATE ${PROTOBUF_QUICK_PLUGIN_NAME} ${GRPC_QUICK_PLUGIN_NAME})
-    if (QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-        target_link_libraries(qtgrpc_qml_test_grpc_http PRIVATE ${PROTOBUF_QUICK_PLUGIN_NAME} ${GRPC_QUICK_PLUGIN_NAME})
-        target_link_libraries(qtgrpc_qml_test_grpc_socket PRIVATE ${PROTOBUF_QUICK_PLUGIN_NAME} ${GRPC_QUICK_PLUGIN_NAME})
-    endif()
-endif()
-
-qtprotobuf_link_target(qtgrpc_qml_test_http2 qtgrpc_test_qtprotobuf_gen)
-if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    qtprotobuf_link_target(qtgrpc_qml_test_grpc_http qtgrpc_test_qtprotobuf_gen)
-    qtprotobuf_link_target(qtgrpc_qml_test_grpc_socket qtgrpc_test_qtprotobuf_gen)
-endif()
-
-if(UNIX)
-    set(TEST_DRIVER_NAME "test_driver.sh")
-elseif(WIN32)
-    set(TEST_DRIVER_NAME "test_driver.bat")
 endif()
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../test_grpc/${TEST_DRIVER_NAME}.in ${TEST_DRIVER_NAME} @ONLY)
 add_test(NAME qtgrpc_qml_test_http2
-         COMMAND ${TEST_DRIVER_NAME} $<TARGET_FILE:qtgrpc_qml_test_http2> $<TARGET_FILE:echoserver> $<TARGET_FILE_NAME:qtgrpc_qml_test_http2> $<TARGET_FILE_NAME:echoserver>
+    COMMAND ${TEST_DRIVER_NAME}
+        $<TARGET_FILE:qtgrpc_qml_test_http2>
+        $<TARGET_FILE:echoserver>
+        $<TARGET_FILE_NAME:qtgrpc_qml_test_http2>
+        $<TARGET_FILE_NAME:echoserver>
 )
-if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    add_test(NAME qtgrpc_qml_test_grpc_http
-            COMMAND ${TEST_DRIVER_NAME} $<TARGET_FILE:qtgrpc_qml_test_grpc_http> $<TARGET_FILE:echoserver> $<TARGET_FILE_NAME:qtgrpc_qml_test_grpc_http> $<TARGET_FILE_NAME:echoserver>
-    )
-    add_test(NAME qtgrpc_qml_test_grpc_socket
-            COMMAND ${TEST_DRIVER_NAME} $<TARGET_FILE:qtgrpc_qml_test_grpc_socket> $<TARGET_FILE:echoserver> $<TARGET_FILE_NAME:qtgrpc_qml_test_grpc_socket> $<TARGET_FILE_NAME:echoserver>
-    )
-endif()
-
-add_target_qml(TARGET qtgrpc_qml_test_http2 QML_FILES ${QML_FILES})
-add_target_windeployqt(TARGET qtgrpc_qml_test_http2 QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
-if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-    add_target_qml(TARGET qtgrpc_qml_test_grpc_http QML_FILES ${QML_FILES})
-    add_target_windeployqt(TARGET qtgrpc_qml_test_grpc_http QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
-    add_target_qml(TARGET qtgrpc_qml_test_grpc_socket QML_FILES ${QML_FILES})
-    add_target_windeployqt(TARGET qtgrpc_qml_test_grpc_socket QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
-endif()
 
+qt_protobuf_internal_add_target_qml(TARGET qtgrpc_qml_test_http2 QML_FILES ${QML_FILES})
+qt_protobuf_internal_add_target_windeployqt(TARGET qtgrpc_qml_test_http2 QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
 
 if(WIN32)
     set_tests_properties(qtgrpc_qml_test_http2 PROPERTIES
         ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..\;$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
-    if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-        set_tests_properties(qtgrpc_qml_test_grpc_http PROPERTIES
-            ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..\;$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
-        set_tests_properties(qtgrpc_qml_test_grpc_socket PROPERTIES
-            ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..\;$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
-    endif()
 else()
     set_tests_properties(qtgrpc_qml_test_http2 PROPERTIES
         ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..:$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
-    if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
-        set_tests_properties(qtgrpc_qml_test_grpc_http PROPERTIES
-            ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..:$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
-        set_tests_properties(qtgrpc_qml_test_grpc_socket PROPERTIES
-            ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..:$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
-    endif()
+endif()
+
+if(QT_PROTOBUF_NATIVE_GRPC_CHANNEL)
+    include("${CMAKE_CURRENT_LIST_DIR}/native_grpc_channel_tests.cmake")
 endif()

+ 45 - 0
tests/test_grpc_qml/native_grpc_channel_tests.cmake

@@ -0,0 +1,45 @@
+add_executable(qtgrpc_qml_test_grpc_http ${MOC_SOURCES} grpc_http.cpp ${QML_FILES})
+add_executable(qtgrpc_qml_test_grpc_socket ${MOC_SOURCES} grpc_socket.cpp ${QML_FILES})
+target_link_libraries(qtgrpc_qml_test_grpc_http
+    PRIVATE
+        ${QT_VERSIONED_PREFIX}::Qml
+        ${QT_VERSIONED_PREFIX}::Quick
+        ${QT_VERSIONED_PREFIX}::Test
+        ${QT_VERSIONED_PREFIX}::QuickTest
+        ${QT_PROTOBUF_NAMESPACE}::Grpc
+)
+target_link_libraries(qtgrpc_qml_test_grpc_socket
+    PRIVATE
+        ${QT_VERSIONED_PREFIX}::Qml
+        ${QT_VERSIONED_PREFIX}::Quick
+        ${QT_VERSIONED_PREFIX}::Test
+        ${QT_VERSIONED_PREFIX}::QuickTest
+        ${QT_PROTOBUF_NAMESPACE}::Grpc
+)
+qtprotobuf_link_target(qtgrpc_qml_test_grpc_http qtgrpc_test_qtprotobuf_gen)
+qtprotobuf_link_target(qtgrpc_qml_test_grpc_socket qtgrpc_test_qtprotobuf_gen)
+if(QT_PROTOBUF_STATIC)
+    target_link_libraries(qtgrpc_qml_test_grpc_http PRIVATE ${PROTOBUF_QUICK_PLUGIN_NAME} ${GRPC_QUICK_PLUGIN_NAME})
+    target_link_libraries(qtgrpc_qml_test_grpc_socket PRIVATE ${PROTOBUF_QUICK_PLUGIN_NAME} ${GRPC_QUICK_PLUGIN_NAME})
+endif()
+add_test(NAME qtgrpc_qml_test_grpc_http
+    COMMAND ${TEST_DRIVER_NAME} $<TARGET_FILE:qtgrpc_qml_test_grpc_http> $<TARGET_FILE:echoserver> $<TARGET_FILE_NAME:qtgrpc_qml_test_grpc_http> $<TARGET_FILE_NAME:echoserver>
+)
+add_test(NAME qtgrpc_qml_test_grpc_socket
+        COMMAND ${TEST_DRIVER_NAME} $<TARGET_FILE:qtgrpc_qml_test_grpc_socket> $<TARGET_FILE:echoserver> $<TARGET_FILE_NAME:qtgrpc_qml_test_grpc_socket> $<TARGET_FILE_NAME:echoserver>
+)
+qt_protobuf_internal_add_target_qml(TARGET qtgrpc_qml_test_grpc_http QML_FILES ${QML_FILES})
+qt_protobuf_internal_add_target_windeployqt(TARGET qtgrpc_qml_test_grpc_http QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
+qt_protobuf_internal_add_target_qml(TARGET qtgrpc_qml_test_grpc_socket QML_FILES ${QML_FILES})
+qt_protobuf_internal_add_target_windeployqt(TARGET qtgrpc_qml_test_grpc_socket QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
+if(WIN32)
+    set_tests_properties(qtgrpc_qml_test_grpc_http PROPERTIES
+        ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..\;$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
+    set_tests_properties(qtgrpc_qml_test_grpc_socket PROPERTIES
+        ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..\;$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
+else()
+    set_tests_properties(qtgrpc_qml_test_grpc_http PROPERTIES
+        ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..:$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
+    set_tests_properties(qtgrpc_qml_test_grpc_socket PROPERTIES
+        ENVIRONMENT QML2_IMPORT_PATH=$<TARGET_FILE_DIR:${PROTOBUF_QUICK_PLUGIN_NAME}>/..:$<TARGET_FILE_DIR:${GRPC_QUICK_PLUGIN_NAME}>/..)
+endif()

+ 2 - 3
tests/test_protobuf/CMakeLists.txt

@@ -1,6 +1,5 @@
 set(TARGET qtprotobuf_test)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 
 file(GLOB SOURCES
@@ -17,10 +16,10 @@ if(NOT WIN32)
     list(APPEND SOURCES internalstest.cpp)
 endif()
 
-qt_protobuf_internal_add_test_target(TARGET ${TARGET}
+qt_protobuf_internal_add_test(TARGET ${TARGET}
     SOURCES ${SOURCES}
     QML FIELDENUM)
-add_target_windeployqt(TARGET ${TARGET}
+qt_protobuf_internal_add_target_windeployqt(TARGET ${TARGET}
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
 add_test(NAME ${TARGET} COMMAND ${TARGET})

+ 2 - 3
tests/test_protobuf_multifile/CMakeLists.txt

@@ -1,6 +1,5 @@
 set(TARGET qtprotobuf_test_multifile)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 
 file(GLOB SOURCES
@@ -9,13 +8,13 @@ file(GLOB SOURCES
 
 file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../test_protobuf/proto/*.proto)
 
-qt_protobuf_internal_add_test_target(TARGET ${TARGET}
+qt_protobuf_internal_add_test(TARGET ${TARGET}
     PROTO_FILES ${PROTO_FILES}
     SOURCES ${SOURCES}
     QML
     MULTI
     FIELDENUM)
-add_target_windeployqt(TARGET ${TARGET}
+qt_protobuf_internal_add_target_windeployqt(TARGET ${TARGET}
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
 add_test(NAME ${TARGET} COMMAND ${TARGET})

+ 5 - 7
tests/test_qml/CMakeLists.txt

@@ -1,8 +1,6 @@
 set(TARGET qtprotobuf_qml_test)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
-find_package(Qt5 COMPONENTS Quick QuickTest REQUIRED)
 
 set(CMAKE_AUTOMOC OFF)
 
@@ -12,10 +10,10 @@ file(GLOB QML_FILES qml/tst_simple.qml)
 qt5_wrap_cpp(MOC_SOURCES test.h)
 
 add_executable(${TARGET} ${MOC_SOURCES} ${SOURCES} ${QML_FILES})
-target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml Qt5::Network Qt5::Quick Qt5::Test Qt5::QuickTest QtProtobufProject::QtProtobuf)
+target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml Qt5::Network Qt5::Quick Qt5::Test Qt5::QuickTest ${QT_PROTOBUF_NAMESPACE}::Protobuf)
 
-if(TARGET QtProtobufProject::QtProtobufWellKnownTypes)
-    target_link_libraries(${TARGET} PRIVATE QtProtobufProject::QtProtobufWellKnownTypes)
+if(TARGET ${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes)
+    target_link_libraries(${TARGET} PRIVATE ${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes)
 endif()
 
 if(QT_PROTOBUF_STATIC)
@@ -24,8 +22,8 @@ endif()
 
 qtprotobuf_link_target(${TARGET} qtprotobuf_test_qtprotobuf_gen)
 
-add_target_qml(TARGET ${TARGET} QML_FILES ${QML_FILES})
-add_target_windeployqt(TARGET ${TARGET} QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
+qt_protobuf_internal_add_target_qml(TARGET ${TARGET} QML_FILES ${QML_FILES})
+qt_protobuf_internal_add_target_windeployqt(TARGET ${TARGET} QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/qml)
 
 add_test(NAME ${TARGET} COMMAND ${TARGET})
 

+ 3 - 4
tests/test_qprotobuf_serializer_plugin/CMakeLists.txt

@@ -1,6 +1,5 @@
 set(TARGET qtprotobuf_plugin_test)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 find_package(Qt5 CONFIG COMPONENTS Test REQUIRED)
 
@@ -12,13 +11,13 @@ file(GLOB SOURCES
 add_executable(${TARGET} ${SOURCES})
 target_link_libraries(${TARGET} PRIVATE gtest_main
                                         gtest
-                                        ${QT_PROTOBUF_PROJECT}::QtProtobuf
-                                        ${QT_PROTOBUF_PROJECT}::QtGrpc
+                                        ${QT_PROTOBUF_NAMESPACE}::Protobuf
+                                        ${QT_PROTOBUF_NAMESPACE}::Grpc
                                         Qt5::Core
                                         Qt5::Test
                                         Qt5::Network
                                         ${CMAKE_THREAD_LIBS_INIT})
-add_target_windeployqt(TARGET ${TARGET}
+qt_protobuf_internal_add_target_windeployqt(TARGET ${TARGET}
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
 add_subdirectory("serialization")

+ 1 - 1
tests/test_qprotobuf_serializer_plugin/serialization/CMakeLists.txt

@@ -20,7 +20,7 @@ file(GLOB HEADERS
     qtserialization_global.h)
 
 add_library(${TARGET} SHARED ${SOURCES})
-target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QT_PROTOBUF_PROJECT}::QtProtobuf)
+target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QT_PROTOBUF_NAMESPACE}::Protobuf)
 target_compile_definitions(${TARGET} PRIVATE SERIALIZATION_LIB)
 
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/serializeinfo.json" "${CMAKE_CURRENT_BINARY_DIR}/serializeinfo.json" COPYONLY)

+ 4 - 9
tests/test_qttypes/CMakeLists.txt

@@ -1,24 +1,19 @@
 set(TARGET qttypes_test)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 
-if(NOT TARGET QtProtobufProject::QtProtobufQtTypes)
-    find_package(QtProtobufProject CONFIG COMPONENTS QtProtobufQtTypes REQUIRED)
-endif()
-
 file(GLOB SOURCES
     qtcoretest.cpp
     qtguitest.cpp)
 
-qt_protobuf_internal_add_test_target(TARGET ${TARGET}
+qt_protobuf_internal_add_test(TARGET ${TARGET}
     SOURCES ${SOURCES}
-    PROTO_INCLUDES $<TARGET_PROPERTY:${QT_PROTOBUF_PROJECT}::QtProtobufQtTypes,PROTO_INCLUDES>
+    PROTO_INCLUDES $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::ProtobufQtTypes,PROTO_INCLUDES>
     QML)
-add_target_windeployqt(TARGET ${TARGET}
+qt_protobuf_internal_add_target_windeployqt(TARGET ${TARGET}
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testimage.png ${CMAKE_CURRENT_BINARY_DIR}/testimage.png COPYONLY)
 
-target_link_libraries(${TARGET} PRIVATE ${QT_PROTOBUF_PROJECT}::QtProtobufQtTypes)
+target_link_libraries(${TARGET} PRIVATE ${QT_PROTOBUF_NAMESPACE}::ProtobufQtTypes)
 add_test(NAME ${TARGET} COMMAND ${TARGET})

+ 4 - 9
tests/test_wellknowntypes/CMakeLists.txt

@@ -1,21 +1,16 @@
 set(TARGET wellknowntypes_test)
 
-include(${QT_PROTOBUF_CMAKE_DIR}/QtProtobufInternalHelpers.cmake)
 qt_protobuf_internal_find_dependencies()
 
-if(NOT TARGET QtProtobufProject::QtProtobufQtTypes)
-    find_package(QtProtobufProject CONFIG COMPONENTS QtProtobufWellKnownTypes REQUIRED)
-endif()
-
 file(GLOB SOURCES
     simpletest.cpp)
 
-qt_protobuf_internal_add_test_target(TARGET ${TARGET}
+qt_protobuf_internal_add_test(TARGET ${TARGET}
     SOURCES ${SOURCES}
-    PROTO_INCLUDES $<TARGET_PROPERTY:${QT_PROTOBUF_PROJECT}::QtProtobufWellKnownTypes,PROTO_INCLUDES>
+    PROTO_INCLUDES $<TARGET_PROPERTY:${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes,PROTO_INCLUDES>
     QML)
-add_target_windeployqt(TARGET ${TARGET}
+qt_protobuf_internal_add_target_windeployqt(TARGET ${TARGET}
     QML_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
-target_link_libraries(${TARGET} PRIVATE ${QT_PROTOBUF_PROJECT}::QtProtobufWellKnownTypes)
+target_link_libraries(${TARGET} PRIVATE ${QT_PROTOBUF_NAMESPACE}::ProtobufWellKnownTypes)
 add_test(NAME ${TARGET} COMMAND ${TARGET})