%YAML 1.2
--- |
  # GRPC global cmake file
  # This currently builds C and C++ code.
  # This file has been automatically generated from a template file.
  # Please look at the templates directory instead.
  # This file can be regenerated from the template by running
  # tools/buildgen/generate_projects.sh
  #
  # Copyright 2015 gRPC authors.
  #
  # 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
  #
  #     http://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.

  <%!

  import re

  proto_re = re.compile('(.*)\\.proto')

  def proto_replace_ext(filename, ext):
      m = proto_re.match(filename)
      if not m:
        return filename
      return '${_gRPC_PROTO_GENS_DIR}/' + m.group(1) + ext

  def get_deps(target_dict):
    deps = []
    if target_dict.get('baselib', False) or target_dict['name'] == 'address_sorting':
      deps.append("${_gRPC_BASELIB_LIBRARIES}")
    if target_dict.get('build', None) in ['protoc']:
      deps.append("${_gRPC_PROTOBUF_PROTOC_LIBRARIES}")
    if target_dict.get('secure', False):
      deps.append("${_gRPC_SSL_LIBRARIES}")
    if target_dict.language == 'c++':
      deps.append("${_gRPC_PROTOBUF_LIBRARIES}")
    if target_dict['name'] in ['grpc', 'grpc_cronet', 'grpc_unsecure']:
      deps.append("${_gRPC_ZLIB_LIBRARIES}")
      deps.append("${_gRPC_CARES_LIBRARIES}")
      deps.append("${_gRPC_ADDRESS_SORTING_LIBRARIES}")
    deps.append("${_gRPC_ALLTARGETS_LIBRARIES}")
    for d in target_dict.get('deps', []):
      if d == 'benchmark':
        deps.append("${_gRPC_BENCHMARK_LIBRARIES}")
      else:
        deps.append(d)
    if (target_dict.build == 'test' or target_dict.build == 'private') and target_dict.language == 'c++':
      deps.append("${_gRPC_GFLAGS_LIBRARIES}")
    return deps

  def get_platforms_condition_begin(platforms):
    if all(platform in platforms for platform in ['linux', 'mac', 'posix', 'windows']):
      return ''
    cond = ' OR '.join(['_gRPC_PLATFORM_%s' % platform.upper() for platform in platforms])
    return 'if(%s)\n' % cond

  def get_platforms_condition_end(platforms):
    if not get_platforms_condition_begin(platforms):
      return ''
    return 'endif()\n'
  %>

  cmake_minimum_required(VERSION 2.8)

  set(PACKAGE_NAME      "grpc")
  set(PACKAGE_VERSION   "${settings.cpp_version}")
  set(PACKAGE_STRING    "<%text>${PACKAGE_NAME} ${PACKAGE_VERSION}</%text>")
  set(PACKAGE_TARNAME   "<%text>${PACKAGE_NAME}-${PACKAGE_VERSION}</%text>")
  set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
  project(<%text>${PACKAGE_NAME}</%text> C CXX)

  set(gRPC_INSTALL_BINDIR "bin" CACHE STRING "Installation directory for executables")
  set(gRPC_INSTALL_LIBDIR "lib" CACHE STRING "Installation directory for libraries")
  set(gRPC_INSTALL_INCLUDEDIR "include" CACHE STRING "Installation directory for headers")
  set(gRPC_INSTALL_CMAKEDIR "lib/cmake/<%text>${PACKAGE_NAME}</%text>" CACHE STRING "Installation directory for cmake config files")
  set(gRPC_INSTALL_SHAREDIR "share/grpc" CACHE STRING "Installation directory for root certificates")

  # Options
  option(gRPC_BUILD_TESTS "Build tests" OFF)
  option(gRPC_BUILD_CODEGEN "Build codegen" ON)
  option(gRPC_BUILD_CSHARP_EXT "Build C# extensions" ON)
  option(gRPC_BACKWARDS_COMPATIBILITY_MODE "Build libraries that are binary compatible across a larger number of OS and libc versions" OFF)

  set(gRPC_INSTALL_default ON)
  if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    # Disable gRPC_INSTALL by default if building as a submodule
    set(gRPC_INSTALL_default OFF)
  endif()
  set(gRPC_INSTALL <%text>${gRPC_INSTALL_default}</%text> CACHE BOOL
      "Generate installation target: gRPC_ZLIB_PROVIDER, gRPC_CARES_PROVIDER, gRPC_SSL_PROVIDER and gRPC_PROTOBUF_PROVIDER must all be \"package\"")

  # Providers for third-party dependencies (gRPC_*_PROVIDER properties):
  # "module": build the dependency using sources from git submodule (under third_party)
  # "package": use cmake's find_package functionality to locate a pre-installed dependency
  
  set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library")
  set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package")

  set(gRPC_CARES_PROVIDER "module" CACHE STRING "Provider of c-ares library")
  set_property(CACHE gRPC_CARES_PROVIDER PROPERTY STRINGS "module" "package")

  set(gRPC_SSL_PROVIDER "module" CACHE STRING "Provider of ssl library")
  set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package")

  set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library")
  set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package")

  set(gRPC_PROTOBUF_PACKAGE_TYPE "" CACHE STRING "Algorithm for searching protobuf package")
  set_property(CACHE gRPC_PROTOBUF_PACKAGE_TYPE PROPERTY STRINGS "CONFIG" "MODULE")

  set(gRPC_GFLAGS_PROVIDER "module" CACHE STRING "Provider of gflags library")
  set_property(CACHE gRPC_GFLAGS_PROVIDER PROPERTY STRINGS "module" "package")

  set(gRPC_BENCHMARK_PROVIDER "module" CACHE STRING "Provider of benchmark library")
  set_property(CACHE gRPC_BENCHMARK_PROVIDER PROPERTY STRINGS "module" "package")

  set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")

  if(UNIX)
    if(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Linux")
      set(_gRPC_PLATFORM_LINUX ON)
    elseif(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Darwin")
      set(_gRPC_PLATFORM_MAC ON)
    elseif(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Android")
      set(_gRPC_PLATFORM_ANDROID ON)
    else()
      set(_gRPC_PLATFORM_POSIX ON)
    endif()
  endif()
  if(WIN32)
    set(_gRPC_PLATFORM_WINDOWS ON)
  endif()

  ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF
  set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
  
  add_definitions(-DPB_FIELD_32BIT)

  if (MSVC)
    include(cmake/msvc_static_runtime.cmake)
    add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS)
    # needed to compile protobuf
    add_definitions(/wd4065 /wd4506)
    # TODO(jtattermusch): revisit warnings that were silenced as part of upgrade to protobuf3.6.0
    add_definitions(/wd4200 /wd4291 /wd4244)
    # TODO(jtattermusch): revisit C4267 occurrences throughout the code
    add_definitions(/wd4267)
    # TODO(jtattermusch): needed to build boringssl with VS2017, revisit later
    add_definitions(/wd4987 /wd4774 /wd4819 /wd4996 /wd4619)
  endif()

  if (gRPC_USE_PROTO_LITE)
    set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf-lite")
    add_definitions("-DGRPC_USE_PROTO_LITE")
  else()
    set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf")
  endif()

  if(gRPC_BACKWARDS_COMPATIBILITY_MODE)
    add_definitions(-DGPR_BACKWARDS_COMPATIBILITY_MODE)
    if (_gRPC_PLATFORM_MAC)
      # some C++11 constructs not supported before OS X 10.9
      set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
    endif()
  endif()

  if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC)
    # C core has C++ source code, but should not depend on libstc++ (for better portability).
    # We need to use a few tricks to convince cmake to do that.
    # https://stackoverflow.com/questions/15058403/how-to-stop-cmake-from-linking-against-libstdc
    set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
    # Exceptions and RTTI must be off to avoid dependency on libstdc++
    set(_gRPC_CORE_NOSTDCXX_FLAGS -fno-exceptions -fno-rtti)
  else()
    set(_gRPC_CORE_NOSTDCXX_FLAGS "")
  endif()

  include(cmake/zlib.cmake)
  include(cmake/cares.cmake)
  include(cmake/protobuf.cmake)
  include(cmake/ssl.cmake)
  include(cmake/gflags.cmake)
  include(cmake/benchmark.cmake)
  include(cmake/address_sorting.cmake)
  include(cmake/nanopb.cmake)

  if(NOT MSVC)
    set(CMAKE_C_FLAGS   "<%text>${CMAKE_C_FLAGS}</%text> -std=c99")
    set(CMAKE_CXX_FLAGS "<%text>${CMAKE_CXX_FLAGS}</%text> -std=c++11")
  endif()

  if(_gRPC_PLATFORM_MAC)
    set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> m pthread)
  elseif(_gRPC_PLATFORM_ANDROID)
    set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> m)
  elseif(UNIX)
    set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> rt m pthread)
  endif()

  if(WIN32 AND MSVC)
    set(_gRPC_BASELIB_LIBRARIES wsock32 ws2_32)
  endif()

  # Create directory for generated .proto files
  set(_gRPC_PROTO_GENS_DIR <%text>${CMAKE_BINARY_DIR}/gens</%text>)
  file(MAKE_DIRECTORY <%text>${_gRPC_PROTO_GENS_DIR}</%text>)

  #  protobuf_generate_grpc_cpp
  #  --------------------------
  #
  #   Add custom commands to process ``.proto`` files to C++ using protoc and
  #   GRPC plugin::
  #
  #     protobuf_generate_grpc_cpp [<ARGN>...]
  #
  #   ``ARGN``
  #     ``.proto`` files
  #
  function(protobuf_generate_grpc_cpp)
    if(NOT ARGN)
      message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files")
      return()
    endif()

    set(_protobuf_include_path -I . -I <%text>${_gRPC_PROTOBUF_WELLKNOWN_INCLUDE_DIR}</%text>)
    foreach(FIL <%text>${ARGN}</%text>)
      get_filename_component(ABS_FIL <%text>${FIL}</%text> ABSOLUTE)
      get_filename_component(FIL_WE <%text>${FIL}</%text> NAME_WE)
      file(RELATIVE_PATH REL_FIL <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text> <%text>${ABS_FIL}</%text>)
      get_filename_component(REL_DIR <%text>${REL_FIL}</%text> DIRECTORY)
      set(RELFIL_WE "<%text>${REL_DIR}/${FIL_WE}</%text>")

      #if cross-compiling, find host plugin
      if(CMAKE_CROSSCOMPILING)
          find_program(_gRPC_CPP_PLUGIN grpc_cpp_plugin)
      else()
          set(_gRPC_CPP_PLUGIN $<TARGET_FILE:grpc_cpp_plugin>)
      endif()

      add_custom_command(
        OUTPUT <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"</%text>
               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"</%text>
               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h"</%text>
               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"</%text>
               <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"</%text>
        COMMAND <%text>${_gRPC_PROTOBUF_PROTOC_EXECUTABLE}</%text>
        ARGS --grpc_out=<%text>generate_mock_code=true:${_gRPC_PROTO_GENS_DIR}</%text>
             --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR}</%text>
             --plugin=protoc-gen-grpc=<%text>${_gRPC_CPP_PLUGIN}</%text>
             <%text>${_protobuf_include_path}</%text>
             <%text>${REL_FIL}</%text>
        DEPENDS <%text>${ABS_FIL}</%text> <%text>${_gRPC_PROTOBUF_PROTOC}</%text> grpc_cpp_plugin
        WORKING_DIRECTORY <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>
        COMMENT "Running gRPC C++ protocol buffer compiler on <%text>${FIL}</%text>"
        VERBATIM)

        <%text>set_source_files_properties("${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"  "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" PROPERTIES GENERATED TRUE)</%text>
    endforeach()
  endfunction()

  add_custom_target(plugins
    DEPENDS
  % for tgt in targets:
  % if tgt.build == 'protoc':
    ${tgt.name}
  % endif
  % endfor
  )

  add_custom_target(tools_c
    DEPENDS
  % for tgt in targets:
  % if tgt.build == 'tool' and not tgt.language == 'c++':
    ${tgt.name}
  % endif
  % endfor
  )

  add_custom_target(tools_cxx
    DEPENDS
  % for tgt in targets:
  % if tgt.build == 'tool' and tgt.language == 'c++':
    ${tgt.name}
  % endif
  % endfor
  )

  add_custom_target(tools
    DEPENDS tools_c tools_cxx)

  if (gRPC_BUILD_TESTS)
  add_custom_target(buildtests_c)
  % for tgt in targets:
  % if tgt.build == 'test' and not tgt.language == 'c++' and not tgt.get('external_deps', None) and not tgt.boringssl:
  ${get_platforms_condition_begin(tgt.platforms)}\
  add_dependencies(buildtests_c ${tgt.name})
  ${get_platforms_condition_end(tgt.platforms)}\
  % endif
  % endfor

  add_custom_target(buildtests_cxx)
  % for tgt in targets:
  % if tgt.build == 'test' and tgt.language == 'c++' and not tgt.get('external_deps', None) and not tgt.boringssl:
  ${get_platforms_condition_begin(tgt.platforms)}\
  add_dependencies(buildtests_cxx ${tgt.name})
  ${get_platforms_condition_end(tgt.platforms)}\
  % endif
  % endfor

  add_custom_target(buildtests
    DEPENDS buildtests_c buildtests_cxx)
  endif (gRPC_BUILD_TESTS)

  % for lib in libs:
  % if lib.build in ["all", "protoc", "tool", "test", "private"] and not lib.boringssl:
  % if not lib.get('build_system', []) or 'cmake' in lib.get('build_system', []):
  % if not lib.name in ['ares', 'benchmark', 'z']:  # we build these using CMake instead
  % if lib.build in ["test", "private"]:
  if (gRPC_BUILD_TESTS)
  ${cc_library(lib)}
  endif (gRPC_BUILD_TESTS)
  % elif lib.name in ['grpc_csharp_ext']:
  if (gRPC_BUILD_CSHARP_EXT)
  ${cc_library(lib)}
  % if any(proto_re.match(src) for src in lib.src):
  if (gRPC_BUILD_CODEGEN)
  % endif
  ${cc_install(lib)}
  % if any(proto_re.match(src) for src in lib.src):
  endif (gRPC_BUILD_CODEGEN)
  % endif
  endif (gRPC_BUILD_CSHARP_EXT)
  % else:
  ${cc_library(lib)}
  % if not lib.build in ["tool"]:
  % if any(proto_re.match(src) for src in lib.src):
  if (gRPC_BUILD_CODEGEN)
  % endif
  ${cc_install(lib)}
  % if any(proto_re.match(src) for src in lib.src):
  endif (gRPC_BUILD_CODEGEN)
  % endif
  % endif
  % endif
  % endif
  % endif
  % endif
  % endfor

  % for tgt in targets:
  % if tgt.build in ["all", "protoc", "tool", "test", "private"] and not tgt.boringssl:
  % if tgt.build in ["test", "private"]:
  if (gRPC_BUILD_TESTS)
  ${get_platforms_condition_begin(tgt.platforms)}\
  ${cc_binary(tgt)}
  ${get_platforms_condition_end(tgt.platforms)}\
  endif (gRPC_BUILD_TESTS)
  % elif tgt.build in ["protoc"]:
  if (gRPC_BUILD_CODEGEN)
  ${get_platforms_condition_begin(tgt.platforms)}\
  ${cc_binary(tgt)}
  ${cc_install(tgt)}
  ${get_platforms_condition_end(tgt.platforms)}\
  endif (gRPC_BUILD_CODEGEN)
  % else:
  ${get_platforms_condition_begin(tgt.platforms)}\
  ${cc_binary(tgt)}
  % if not tgt.build in ["tool"]:
  ${cc_install(tgt)}
  % endif
  ${get_platforms_condition_end(tgt.platforms)}\
  % endif
  % endif
  % endfor

  <%def name="cc_library(lib)">
  % if any(proto_re.match(src) for src in lib.src):
  if (gRPC_BUILD_CODEGEN)
  % endif
  add_library(${lib.name}${' SHARED' if lib.get('dll', None) == 'only' else ''}
  % for src in lib.src:
  % if not proto_re.match(src):
    ${src}
  % else:
    ${proto_replace_ext(src, '.pb.cc')}
    ${proto_replace_ext(src, '.grpc.pb.cc')}
    ${proto_replace_ext(src, '.pb.h')}
    ${proto_replace_ext(src, '.grpc.pb.h')}
    % if src in ["src/proto/grpc/testing/compiler_test.proto", "src/proto/grpc/testing/echo.proto"]:
    ${proto_replace_ext(src, '_mock.grpc.pb.h')}
    % endif
  % endif
  % endfor
  )

  if(WIN32 AND MSVC)
    set_target_properties(${lib.name} PROPERTIES COMPILE_PDB_NAME "${lib.name}"
      COMPILE_PDB_OUTPUT_DIRECTORY <%text>"${CMAKE_BINARY_DIR}</%text>"
    )
    if (gRPC_INSTALL)
      install(FILES <%text>${CMAKE_CURRENT_BINARY_DIR}/</%text>${lib.name}.pdb
        DESTINATION <%text>${gRPC_INSTALL_LIBDIR}</%text> OPTIONAL
      )
    endif()
  endif()

  % for src in lib.src:
  % if proto_re.match(src):
  protobuf_generate_grpc_cpp(
    ${src}
  )
  % endif
  % endfor

  target_include_directories(${lib.name}
    PUBLIC <%text>$<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include></%text>
    PRIVATE <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>
    PRIVATE <%text>${_gRPC_SSL_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_PROTOBUF_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_ZLIB_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_BENCHMARK_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_CARES_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_GFLAGS_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_NANOPB_INCLUDE_DIR}</%text>
  % if lib.build in ['test', 'private'] and lib.language == 'c++':
    PRIVATE third_party/googletest/googletest/include
    PRIVATE third_party/googletest/googletest
    PRIVATE third_party/googletest/googlemock/include
    PRIVATE third_party/googletest/googlemock
  % endif
  % if lib.language == 'c++':
    PRIVATE <%text>${_gRPC_PROTO_GENS_DIR}</%text>
  % endif
  )
  % if lib.language in ['c', 'csharp']:
    # avoid dependency on libstdc++
    if (_gRPC_CORE_NOSTDCXX_FLAGS)
      set_target_properties(${lib.name} PROPERTIES LINKER_LANGUAGE C)
      # only use the flags for C++ source files
      target_compile_options(${lib.name} PRIVATE <%text>$<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}></%text>)
    endif()
  % endif
  % if len(get_deps(lib)) > 0:
  target_link_libraries(${lib.name}
  % for dep in get_deps(lib):
    ${dep}
  % endfor
  )
  % endif
  % if lib.name in ["gpr"]:
  if (_gRPC_PLATFORM_ANDROID)
    target_link_libraries(gpr
      android
      log
    )
  endif (_gRPC_PLATFORM_ANDROID)
  % endif

  % if len(lib.get('public_headers', [])) > 0:
  foreach(_hdr
  % for hdr in lib.get('public_headers', []):
    ${hdr}
  % endfor
  )
    string(REPLACE "include/" "" _path <%text>${_hdr}</%text>)
    get_filename_component(_path <%text>${_path}</%text> PATH)
    install(FILES <%text>${_hdr}</%text>
      DESTINATION "<%text>${gRPC_INSTALL_INCLUDEDIR}/${_path}</%text>"
    )
  endforeach()
  % endif
  % if any(proto_re.match(src) for src in lib.src):
  endif (gRPC_BUILD_CODEGEN)
  % endif
  </%def>

  <%def name="cc_binary(tgt)">
  add_executable(${tgt.name}
  % for src in tgt.src:
  % if not proto_re.match(src):
    ${src}
  % else:
    ${proto_replace_ext(src, '.pb.cc')}
    ${proto_replace_ext(src, '.grpc.pb.cc')}
    ${proto_replace_ext(src, '.pb.h')}
    ${proto_replace_ext(src, '.grpc.pb.h')}
  % endif
  % endfor
  % if tgt.build == 'test' and tgt.language == 'c++':
    third_party/googletest/googletest/src/gtest-all.cc
    third_party/googletest/googlemock/src/gmock-all.cc
  % endif
  )

  % for src in tgt.src:
  % if proto_re.match(src):
  protobuf_generate_grpc_cpp(
    ${src}
  )
  % endif
  % endfor

  target_include_directories(${tgt.name}
    PRIVATE <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>
    PRIVATE <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/include
    PRIVATE <%text>${_gRPC_SSL_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_PROTOBUF_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_ZLIB_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_BENCHMARK_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_CARES_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_GFLAGS_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}</%text>
    PRIVATE <%text>${_gRPC_NANOPB_INCLUDE_DIR}</%text>
  % if tgt.build in ['test', 'private'] and tgt.language == 'c++':
    PRIVATE third_party/googletest/googletest/include
    PRIVATE third_party/googletest/googletest
    PRIVATE third_party/googletest/googlemock/include
    PRIVATE third_party/googletest/googlemock
  % endif
  % if tgt.language == 'c++':
    PRIVATE <%text>${_gRPC_PROTO_GENS_DIR}</%text>
  % endif
  )

  % if len(get_deps(tgt)) > 0:
  target_link_libraries(${tgt.name}
  % for dep in get_deps(tgt):
    ${dep}
  % endfor
  )

  % if tgt.language in ['c', 'csharp']:
    # avoid dependency on libstdc++
    if (_gRPC_CORE_NOSTDCXX_FLAGS)
      set_target_properties(${tgt.name} PROPERTIES LINKER_LANGUAGE C)
      target_compile_options(${tgt.name} PRIVATE <%text>$<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}></%text>)
    endif()
  % endif
  % endif
  </%def>

  <%def name="cc_install(tgt)">
  if (gRPC_INSTALL)
    install(TARGETS ${tgt.name} EXPORT gRPCTargets
      RUNTIME DESTINATION <%text>${gRPC_INSTALL_BINDIR}</%text>
      LIBRARY DESTINATION <%text>${gRPC_INSTALL_LIBDIR}</%text>
      ARCHIVE DESTINATION <%text>${gRPC_INSTALL_LIBDIR}</%text>
    )
  endif()
  </%def>

  if (gRPC_INSTALL)
    install(EXPORT gRPCTargets
      DESTINATION <%text>${gRPC_INSTALL_CMAKEDIR}</%text>
      NAMESPACE gRPC::
    )
  endif()

  foreach(_config gRPCConfig gRPCConfigVersion)
    configure_file(cmake/<%text>${_config}</%text>.cmake.in
      <%text>${_config}</%text>.cmake @ONLY)
    install(FILES <%text>${CMAKE_CURRENT_BINARY_DIR}/${_config}</%text>.cmake
      DESTINATION <%text>${gRPC_INSTALL_CMAKEDIR}</%text>
    )
  endforeach()
  
  install(FILES <%text>${CMAKE_CURRENT_SOURCE_DIR}/etc/roots.pem</%text>
    DESTINATION <%text>${gRPC_INSTALL_SHAREDIR}</%text>)
