Browse Source

Migrate to modern cmake targets detection for QtProtobuf dependencies

- Add ProtobufLookup.cmake to detect protobuf installation and generate targets if required
- Add gRPCLookup.cmake to date gRPC installation and generate targets if required
- Update cmake rules for QtProtobuf targets accordingly
- Change gRPC check in QtProtobufCommon.cmake
- Replace variables with libraries with correct
  gRPC and Protobuf targets
- More precise tune of compile features for libraries targets
Alexey Edelev 6 years ago
parent
commit
96afc00165

+ 4 - 19
CMakeLists.txt

@@ -5,16 +5,6 @@ project(QtProtobufProject VERSION ${QTPROTOBUF_PROJECT_VERSION} LANGUAGES CXX)
 
 include(GNUInstallDirs)
 
-find_package(Protobuf CONFIG)
-if(NOT Protobuf_FOUND)
-    find_package(Protobuf MODULE)
-    # still Protobuf hard dependency not found
-    if(NOT Protobuf_FOUND)
-        # TODO: add instructions to cmake/gRPCBuild.cmake
-        message(FATAL_ERROR "Protobuf is a hard dependency of the project. You may install it (with gRPC) by following instructions in cmake/gRPCBuild.cmake script.")
-    endif()
-endif()
-
 find_package(Qt5 COMPONENTS Core Network Qml REQUIRED)
 if (Qt5Core_VERSION VERSION_LESS "5.11.0")
     # grpc target requires QT version not less than 5.11
@@ -22,14 +12,8 @@ if (Qt5Core_VERSION VERSION_LESS "5.11.0")
     message(FATAL_ERROR "Required Qt version is 5.11+")
 endif()
 
-unset(gRPC_CPP_PLUGIN_EXECUTABLE CACHE)
-find_program(gRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
-if (gRPC_CPP_PLUGIN_EXECUTABLE STREQUAL gRPC_CPP_PLUGIN_EXECUTABLE-NOTFOUND)
-    set(gRPC_CPP_PLUGIN_EXECUTABLE_FOUND FALSE)
-    message(WARNING "grpc_cpp_plugin not found: some tests and examples cannot be built.")
-else()
-    set(gRPC_CPP_PLUGIN_EXECUTABLE_FOUND TRUE)
-endif()
+include("cmake/ProtobufLookup.cmake")
+include("cmake/gRPCLookup.cmake")
 
 set(QTPROTOBUF_COMMON_NAMESPACE QtProtobufProject)
 set(GENERATOR_TARGET qtprotobufgen)
@@ -80,7 +64,8 @@ if(MAKE_COVERAGE)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
 endif()
 
-if(NOT gRPC_CPP_PLUGIN_EXECUTABLE_FOUND)
+if(NOT gRPC_FOUND)
+    message(WARNING "gRPC not found: some tests and examples cannot be built.")
     message(STATUS "Force disable test")
     set(MAKE_TESTS OFF)
     message(STATUS "Force disable examples")

+ 45 - 0
cmake/ProtobufLookup.cmake

@@ -0,0 +1,45 @@
+if(NOT Protobuf_FOUND)
+    find_package(Protobuf CONFIG)
+    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 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 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 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(NOT Protobuf_LIBRARY STREQUAL Protobuf_LIBRARY-NOTFOUND
+                AND NOT Protobuf_PROTOC_EXECUTABLE STREQUAL Protobuf_PROTOC_EXECUTABLE-NOTFOUND
+                AND NOT Protobuf_PROTOC_LIBRARY STREQUAL Protobuf_PROTOC_LIBRARY-NOTFOUND)
+            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. You may install it (with gRPC) by following instructions in cmake/gRPCBuild.cmake script.")
+            unset(Protobuf_LIBRARY Protobuf_PROTOC_EXECUTABLE Protobuf_PROTOC_LIBRARY)
+        endif()
+    endif()
+endif()

+ 4 - 4
cmake/QtProtobufCommon.cmake

@@ -22,17 +22,17 @@ function(protobuf_generate_all)
 
     file(MAKE_DIRECTORY ${OUT_DIR})
 
-    if(NOT DEFINED gRPC_CPP_PLUGIN_EXECUTABLE)
-        message(FATAL_ERROR "gRPC plugin is not found set full path to grpc_cpp_plugin using -DgRPC_CPP_PLUGIN_EXECUTABLE=</path/to/grpc_cpp_plugin>")
+    if(NOT TARGET gRPC::grpc_cpp_plugin)
+        message(FATAL_ERROR "gRPC plugin is not found")
     endif()
 
     add_custom_command(
         TARGET ${GEN_TARGET}
-        COMMAND ${Protobuf_PROTOC_EXECUTABLE}
+        COMMAND $<TARGET_FILE:protobuf::protoc>
         ARGS --grpc_out="${OUT_DIR}"
         --cpp_out="${OUT_DIR}"
         ${PROTO_INCLUDES}
-        --plugin=protoc-gen-grpc="${gRPC_CPP_PLUGIN_EXECUTABLE}"
+        --plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
         ${protobuf_generate_all_PROTO_FILES}
         DEPENDS ${protobuf_generate_all_PROTO_FILES})
     add_dependencies(${protobuf_generate_all_TARGET} ${GEN_TARGET})

+ 41 - 0
cmake/gRPCLookup.cmake

@@ -0,0 +1,41 @@
+if(NOT gRPC_FOUND)
+    find_package(gRPC CONFIG)
+    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 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 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 gRPC_CPP_LIBRARY STREQUAL gRPC_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(NOT gRPC_LIBRARY STREQUAL gRPC_LIBRARY-NOTFOUND
+                AND NOT gRPC_CPP_PLUGIN_EXECUTABLE STREQUAL gRPC_CPP_PLUGIN_EXECUTABLE-NOTFOUND
+                AND NOT gRPC_CPP_LIBRARY STREQUAL gRPC_LIBRARY-NOTFOUND)
+            set(gRPC_FOUND TRUE)
+        else()
+            unset(gRPC_LIBRARY gRPC_CPP_PLUGIN_EXECUTABLE gRPC_CPP_LIBRARY)
+        endif()
+    endif()
+endif()

+ 1 - 1
examples/addressbookserver/CMakeLists.txt

@@ -23,5 +23,5 @@ if(WIN32)
     link_directories(${PROTOBUF_LIBRARIES_PATH} ${GRPC_LIBRARIES})
 endif()
 
-target_link_libraries(${TARGET} ${Protobuf_LIBRARIES} grpc++ grpc)
+target_link_libraries(${TARGET} protobuf::libprotobuf gRPC::grpc++ gRPC::grpc)
 file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cert.pem ${CMAKE_CURRENT_SOURCE_DIR}/key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

+ 1 - 1
examples/simplechatserver/CMakeLists.txt

@@ -23,5 +23,5 @@ if(WIN32)
     link_directories(${PROTOBUF_LIBRARIES_PATH} ${GRPC_LIBRARIES})
 endif()
 
-target_link_libraries(${TARGET} ${Protobuf_LIBRARIES} grpc++ grpc)
+target_link_libraries(${TARGET} protobuf::libprotobuf gRPC::grpc++ gRPC::grpc)
 file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cert.pem ${CMAKE_CURRENT_SOURCE_DIR}/key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

+ 1 - 1
src/generator/CMakeLists.txt

@@ -44,7 +44,7 @@ if(DEFINED Protobuf_INCLUDE_DIRS)
     target_include_directories(${TARGET} PUBLIC ${Protobuf_INCLUDE_DIRS})
 endif()
 
-target_link_libraries(${TARGET} ${Protobuf_LIBRARIES} ${Protobuf_PROTOC_LIBRARY})
+target_link_libraries(${TARGET} protobuf::libprotobuf protobuf::libprotoc)
 
 install(TARGETS ${TARGET}
     RUNTIME DESTINATION ${TARGET_BIN_DIR})

+ 8 - 2
src/grpc/CMakeLists.txt

@@ -35,8 +35,14 @@ add_library(${QTPROTOBUF_COMMON_NAMESPACE}::${TARGET} ALIAS ${TARGET})
 set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} PUBLIC_HEADER "${HEADERS}" OUTPUT_NAME ${TARGET})
 target_include_directories(${TARGET} ${INCLUDE_DIRS})
 target_link_libraries(${TARGET} PUBLIC ${QTPROTOBUF_COMMON_NAMESPACE}::QtProtobuf Qt5::Core Qt5::Network)
-target_compile_features(${TARGET} PUBLIC cxx_std_14)
-
+target_compile_features(${TARGET} PUBLIC cxx_std_14
+                                         cxx_auto_type
+                                         cxx_decltype
+                                         cxx_final
+                                         cxx_override
+                                         cxx_nullptr
+                                         cxx_lambdas
+                                         cxx_func_identifier)
 install(TARGETS ${TARGET}
     EXPORT ${TARGET_EXPORT}
     ARCHIVE DESTINATION ${TARGET_LIB_DIR}

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

@@ -1,5 +1,5 @@
 include(CMakeFindDependencyMacro)
-find_dependency(Protobuf REQUIRED CONFIG)
+
 find_dependency(QtProtobuf REQUIRED CONFIG)
 
 include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT@.cmake")

+ 1 - 1
src/grpc/QtGrpcConfigTree.cmake.in

@@ -1,5 +1,5 @@
 include(CMakeFindDependencyMacro)
-find_dependency(Protobuf REQUIRED CONFIG)
+
 find_dependency(QtProtobuf REQUIRED CONFIG)
 
 @PACKAGE_INIT@

+ 12 - 2
src/protobuf/CMakeLists.txt

@@ -34,7 +34,14 @@ add_library(${QTPROTOBUF_COMMON_NAMESPACE}::${TARGET} ALIAS ${TARGET})
 set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} PUBLIC_HEADER "${HEADERS}" OUTPUT_NAME ${TARGET})
 target_include_directories(${TARGET} ${INCLUDE_DIRS})
 target_link_libraries(${TARGET} PUBLIC Qt5::Core Qt5::Qml)
-target_compile_features(${TARGET} PUBLIC cxx_std_14)
+target_compile_features(${TARGET} PUBLIC cxx_std_14
+                                         cxx_auto_type
+                                         cxx_decltype
+                                         cxx_final
+                                         cxx_override
+                                         cxx_nullptr
+                                         cxx_lambdas
+                                         cxx_func_identifier)
 
 install(TARGETS ${TARGET}
     EXPORT ${TARGET_EXPORT}
@@ -58,4 +65,7 @@ export(TARGETS ${TARGET} NAMESPACE ${QTPROTOBUF_COMMON_NAMESPACE}:: FILE ${TARGE
 export(PACKAGE ${TARGET})
 
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/QtProtobufGen.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/QtProtobufGen.cmake" @ONLY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/QtProtobufGen.cmake DESTINATION "${TARGET_CMAKE_DIR}")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/QtProtobufGen.cmake" DESTINATION "${TARGET_CMAKE_DIR}")
+
+configure_file("${CMAKE_SOURCE_DIR}/cmake/ProtobufLookup.cmake" "${CMAKE_CURRENT_BINARY_DIR}/ProtobufLookup.cmake" COPYONLY)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ProtobufLookup.cmake" DESTINATION "${TARGET_CMAKE_DIR}")

+ 1 - 2
src/protobuf/QtProtobufConfig.cmake.in

@@ -1,5 +1,4 @@
-include(CMakeFindDependencyMacro)
-find_dependency(Protobuf REQUIRED CONFIG)
+include("${CMAKE_CURRENT_LIST_DIR}/ProtobufLookup.cmake")
 
 include("${CMAKE_CURRENT_LIST_DIR}/@TARGET_EXPORT@.cmake")
 

+ 1 - 2
src/protobuf/QtProtobufConfigTree.cmake.in

@@ -1,5 +1,4 @@
-include(CMakeFindDependencyMacro)
-find_dependency(Protobuf REQUIRED CONFIG)
+include("${CMAKE_CURRENT_LIST_DIR}/ProtobufLookup.cmake")
 
 @PACKAGE_INIT@
 

+ 1 - 1
src/protobuf/QtProtobufGen.cmake.in

@@ -38,7 +38,7 @@ function(generate_qtprotobuf)
     endforeach()
 
     add_custom_command(TARGET ${GEN_TARGET}
-            COMMAND ${Protobuf_PROTOC_EXECUTABLE}
+            COMMAND $<TARGET_FILE:protobuf::protoc>
                 --@GENERATOR_TARGET@_opt=out=${OUT_DIR}
                 --plugin=protoc-gen-@GENERATOR_TARGET@=${QTPROTOBUF_EXECUTABLE}
                 --@GENERATOR_TARGET@_out=${OUT_DIR}

+ 0 - 1
src/protobuf/qtprotobuftypes.h

@@ -100,4 +100,3 @@ Q_DECLARE_METATYPE(qtprotobuf::sfixed64List)
 
 Q_DECLARE_METATYPE(qtprotobuf::FloatList)
 Q_DECLARE_METATYPE(qtprotobuf::DoubleList)
-

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

@@ -8,7 +8,7 @@ set(GENERATED_SOURCES
 set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
 
 add_executable(${TARGET} main.cpp ${GENERATED_SOURCES})
-target_link_libraries(${TARGET} grpc++ ${Protobuf_LIBRARIES})
+target_link_libraries(${TARGET} gRPC::grpc++ protobuf::libprotobuf)
 target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
 
 file(GLOB PROTO_FILES ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/../proto/*.proto)