| # ~~~ |
| # Copyright 2019 Google LLC |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # ~~~ |
| |
| #[=======================================================================[.rst: |
| FindgRPC |
| -------- |
| |
| Locate and configure the ``gRPC`` library. |
| |
| The following variables can be set and are optional: |
| |
| ``gRPC_DEBUG`` |
| Show debug messages. |
| ``gRPC_USE_STATIC_LIBS`` |
| Set to ON to force the use of the static libraries. |
| Default is OFF. |
| |
| Defines the following variables: |
| |
| ``gRPC_FOUND`` |
| Found the gRPC library |
| ``gRPC_VERSION`` |
| Version of package found. |
| |
| The following ``IMPORTED`` targets are also defined: |
| |
| ``gRPC::grpc++`` |
| The gRPC C++ library. |
| ``gRPC::grpc`` |
| The gRPC C core library. |
| ``gRPC::cpp_plugin`` |
| The C++ plugin for the Protobuf protoc compiler. |
| |
| The following cache variables are also available to set or use: |
| |
| Example: |
| |
| .. code-block:: cmake |
| |
| find_package(gRPC REQUIRED) |
| add_executable(bar bar.cc) |
| target_link_libraries(bar PRIVATE gRPC::grpc++) |
| |
| #]=======================================================================] |
| |
| if (gRPC_DEBUG) |
| message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| "gRPC_USE_STATIC_LIBS = ${gRPC_USE_STATIC_LIBS}" |
| " gRPC_FOUND = ${gRPC_FOUND}") |
| endif () |
| |
| # gRPC always requires Thread support. |
| find_package(Threads REQUIRED) |
| |
| # Load the module to find protobuf with proper targets. Do not use |
| # `find_package()` because we (have to) install this module in non-standard |
| # locations. |
| list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") |
| find_package(ProtobufWithTargets) |
| |
| # The gRPC::grpc_cpp_plugin target is sometimes defined, but without a |
| # IMPORTED_LOCATION |
| function (_grpc_fix_grpc_cpp_plugin_target) |
| # The target may already exist, do not create it again if it does. |
| if (NOT TARGET gRPC::grpc_cpp_plugin) |
| add_executable(gRPC::grpc_cpp_plugin IMPORTED) |
| endif () |
| get_target_property(_gRPC_CPP_PLUGIN_EXECUTABLE gRPC::grpc_cpp_plugin |
| IMPORTED_LOCATION) |
| if (gRPC_DEBUG) |
| message( |
| STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| "LOCATION=${_gRPC_CPP_PLUGIN_EXECUTABLE}") |
| endif () |
| # Even if the target exists, gRPC CMake support files do not define the |
| # executable for the imported target (at least they do not in v1.19.1), so |
| # we need to define it ourselves. |
| if (NOT _gRPC_CPP_PLUGIN_EXECUTABLE) |
| find_program(_gRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin |
| DOC "The gRPC C++ plugin for protoc") |
| mark_as_advanced(_gRPC_CPP_PLUGIN_EXECUTABLE) |
| if (_gRPC_CPP_PLUGIN_EXECUTABLE) |
| set_property( |
| TARGET gRPC::grpc_cpp_plugin |
| PROPERTY IMPORTED_LOCATION ${_gRPC_CPP_PLUGIN_EXECUTABLE}) |
| else () |
| set(gRPC_FOUND "grpc_cpp_plugin-NOTFOUND") |
| endif () |
| endif () |
| endfunction () |
| |
| # The gRPC::* targets sometimes lack the right definitions to compile cleanly on |
| # WIN32 |
| function (_grpc_fix_grpc_target_definitions) |
| # Including gRPC headers without this definition results in a build error. |
| if (WIN32) |
| set_property( |
| TARGET gRPC::grpc |
| APPEND |
| PROPERTY INTERFACE_COMPILE_DEFINITIONS _WIN32_WINNT=0x600) |
| set_property( |
| TARGET gRPC::grpc++ |
| APPEND |
| PROPERTY INTERFACE_COMPILE_DEFINITIONS _WIN32_WINNT=0x600) |
| endif () |
| endfunction () |
| |
| # First try to use the `gRPCConfig.cmake` or `grpc-config.cmake` file if it was |
| # installed. This is common on systems (or package managers) where gRPC was |
| # compiled and installed with `CMake`. |
| |
| find_package(gRPC NO_MODULE QUIET) |
| |
| if (gRPC_DEBUG) |
| message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| "NO_MODULE result gRPC_FOUND = ${gRPC_FOUND}") |
| endif () |
| |
| if (gRPC_FOUND) |
| _grpc_fix_grpc_cpp_plugin_target() |
| _grpc_fix_grpc_target_definitions() |
| return() |
| endif () |
| |
| include(SelectLibraryConfigurations) |
| |
| # Internal function: search for normal library as well as a debug one if the |
| # debug one is specified also include debug/optimized keywords in *_LIBRARIES |
| # variable |
| function (_gRPC_find_library name filename) |
| if (${name}_LIBRARY) |
| # Use result recorded by a previous call. |
| return() |
| else () |
| find_library(${name}_LIBRARY_RELEASE NAMES ${filename}) |
| mark_as_advanced(${name}_LIBRARY_RELEASE) |
| |
| find_library(${name}_LIBRARY_DEBUG NAMES ${filename}d ${filename}) |
| mark_as_advanced(${name}_LIBRARY_DEBUG) |
| |
| select_library_configurations(${name}) |
| |
| if (gRPC_DEBUG) |
| message( |
| STATUS |
| "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| "${name} ${filename} RELEASE=${${name}_LIBRARY}" |
| " DEBUG=${${name}_LIBRARY_DEBUG} DEFAULT=${${name}_LIBRARY}" |
| ) |
| endif () |
| |
| set(${name}_LIBRARY |
| "${${name}_LIBRARY}" |
| PARENT_SCOPE) |
| endif () |
| endfunction () |
| |
| # |
| # Main |
| # |
| |
| # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES |
| if (_gRPC_USE_STATIC_LIBS) |
| set(_gRPC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) |
| if (WIN32) |
| set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) |
| else () |
| set(CMAKE_FIND_LIBRARY_SUFFIXES .a) |
| endif () |
| endif () |
| |
| _grpc_find_library(_gRPC_grpc grpc) |
| _grpc_find_library(_gRPC_grpc++ grpc++) |
| |
| if (NOT _gRPC_INCLUDE_DIR) |
| find_path(_gRPC_INCLUDE_DIR grpcpp/grpcpp.h) |
| mark_as_advanced(_gRPC_INCLUDE_DIR) |
| endif () |
| |
| if (gRPC_DEBUG) |
| message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| " _gRPC_grpc_LIBRARY = ${_gRPC_grpc_LIBRARY}") |
| message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| " _gRPC_grpc++_LIBRARY = ${_gRPC_grpc++_LIBRARY}") |
| message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| " _gRPC_INCLUDE_DIR = ${_gRPC_INCLUDE_DIR}") |
| endif () |
| |
| if (_gRPC_grpc_LIBRARY) |
| if (NOT TARGET gRPC::grpc) |
| add_library(gRPC::grpc UNKNOWN IMPORTED) |
| set_target_properties( |
| gRPC::grpc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES |
| "${_gRPC_INCLUDE_DIR}") |
| if (EXISTS "${_gRPC_grpc_LIBRARY}") |
| set_target_properties(gRPC::grpc PROPERTIES IMPORTED_LOCATION |
| "${_gRPC_grpc_LIBRARY}") |
| endif () |
| if (EXISTS "${_gRPC_grpc_LIBRARY_RELEASE}") |
| set_property( |
| TARGET gRPC::grpc |
| APPEND |
| PROPERTY IMPORTED_CONFIGURATIONS RELEASE) |
| set_target_properties( |
| gRPC::grpc PROPERTIES IMPORTED_LOCATION_RELEASE |
| "${_gRPC_grpc_LIBRARY_RELEASE}") |
| endif () |
| if (EXISTS "${_gRPC_grpc_LIBRARY_DEBUG}") |
| set_property( |
| TARGET gRPC::grpc |
| APPEND |
| PROPERTY IMPORTED_CONFIGURATIONS DEBUG) |
| set_target_properties( |
| gRPC::grpc PROPERTIES IMPORTED_LOCATION_DEBUG |
| "${_gRPC_grpc_LIBRARY_DEBUG}") |
| endif () |
| set_property( |
| TARGET gRPC::grpc |
| APPEND |
| PROPERTY INTERFACE_LINK_LIBRARIES protobuf::libprotobuf |
| Threads::Threads) |
| endif () |
| endif () |
| |
| if (_gRPC_grpc++_LIBRARY) |
| if (NOT TARGET gRPC::grpc++) |
| add_library(gRPC::grpc++ UNKNOWN IMPORTED) |
| set_target_properties( |
| gRPC::grpc++ PROPERTIES INTERFACE_INCLUDE_DIRECTORIES |
| "${_gRPC++_INCLUDE_DIR}") |
| if (EXISTS "${_gRPC_grpc++_LIBRARY}") |
| set_target_properties( |
| gRPC::grpc++ PROPERTIES IMPORTED_LOCATION |
| "${_gRPC_grpc++_LIBRARY}") |
| endif () |
| if (EXISTS "${_gRPC_grpc++_LIBRARY_RELEASE}") |
| set_property( |
| TARGET gRPC::grpc++ |
| APPEND |
| PROPERTY IMPORTED_CONFIGURATIONS RELEASE) |
| set_target_properties( |
| gRPC::grpc++ PROPERTIES IMPORTED_LOCATION_RELEASE |
| "${_gRPC_grpc++_LIBRARY_RELEASE}") |
| endif () |
| if (EXISTS "${_gRPC_grpc++_LIBRARY_DEBUG}") |
| set_property( |
| TARGET gRPC::grpc++ |
| APPEND |
| PROPERTY IMPORTED_CONFIGURATIONS DEBUG) |
| set_target_properties( |
| gRPC::grpc++ PROPERTIES IMPORTED_LOCATION_DEBUG |
| "${_gRPC_grpc++_LIBRARY_DEBUG}") |
| endif () |
| set_property( |
| TARGET gRPC::grpc++ |
| APPEND |
| PROPERTY INTERFACE_LINK_LIBRARIES gRPC::grpc protobuf::libprotobuf |
| Threads::Threads) |
| if (CMAKE_VERSION VERSION_GREATER 3.8) |
| # gRPC++ requires C++14 (soon), but only CMake-3.8 introduced a |
| # compiler feature to meet that requirement. |
| set_property( |
| TARGET gRPC::grpc++ |
| APPEND |
| PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_14) |
| elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") |
| # CMake 3.5 is still alive and kicking in some older distros, use |
| # the compiler-specific versions in these cases. |
| set_property( |
| TARGET gRPC::grpc++ |
| APPEND |
| PROPERTY INTERFACE_COMPILE_OPTIONS "-std=c++14") |
| elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") |
| set_property( |
| TARGET gRPC::grpc++ |
| APPEND |
| PROPERTY INTERFACE_COMPILE_OPTIONS "-std=c++14") |
| else () |
| message( |
| WARNING |
| "gRPC::grpc++ requires C++14, but this module" |
| " (${CMAKE_CURRENT_LIST_FILE})" |
| " cannot enable it for the library target in your CMake and" |
| " compiler versions. You need to enable C++14 in the" |
| " CMakeLists.txt for your project. Consider filing a bug" |
| " so we can fix this problem.") |
| endif () |
| endif () |
| endif () |
| |
| # Restore original find library prefixes |
| if (_gRPC_USE_STATIC_LIBS) |
| set(CMAKE_FIND_LIBRARY_PREFIXES "${_gRPC_ORIG_FIND_LIBRARY_PREFIXES}") |
| endif () |
| |
| file( |
| WRITE "${CMAKE_BINARY_DIR}/get_gRPC_version.cc" |
| [====[ |
| #include <grpcpp/grpcpp.h> |
| #include <iostream> |
| int main() { |
| std::cout << grpc::Version(); // no newline to simplify CMake module |
| return 0; |
| } |
| ]====]) |
| |
| try_run( |
| _gRPC_GET_VERSION_STATUS |
| _gRPC_GET_VERSION_COMPILE_STATUS |
| "${CMAKE_BINARY_DIR}" |
| "${CMAKE_BINARY_DIR}/get_gRPC_version.cc" |
| LINK_LIBRARIES |
| gRPC::grpc++ |
| gRPC::grpc |
| COMPILE_OUTPUT_VARIABLE _gRPC_GET_VERSION_COMPILE_OUTPUT |
| RUN_OUTPUT_VARIABLE gRPC_VERSION) |
| |
| file(REMOVE "${CMAKE_BINARY_DIR}/get_gRPC_version.cc") |
| |
| _grpc_fix_grpc_cpp_plugin_target() |
| |
| if (gRPC_DEBUG) |
| foreach ( |
| _var |
| _gRPC_CPP_PLUGIN_EXECUTABLE |
| _gRPC_VERSION_RAW |
| _gRPC_GET_VERSION_STATUS |
| _gRPC_GET_VERSION_COMPILE_STATUS |
| _gRPC_GET_VERSION_COMPILE_OUTPUT |
| _gRPC_grpc_LIBRARY |
| _gRPC_grpc++_LIBRARY |
| _gRPC_INCLUDE_DIR) |
| message( |
| STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " |
| "${_var} = ${${_var}}") |
| endforeach () |
| unset(_var) |
| endif () |
| |
| include(FindPackageHandleStandardArgs) |
| find_package_handle_standard_args( |
| gRPC |
| REQUIRED_VARS _gRPC_grpc_LIBRARY _gRPC_INCLUDE_DIR |
| VERSION_VAR gRPC_VERSION) |