%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' 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)

  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_16BIT)

  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()

  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>")

      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=$<TARGET_FILE:grpc_cpp_plugin>
             <%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)}
  ${cc_install(lib)}
  endif (gRPC_BUILD_CSHARP_EXT)
  % else:
  ${cc_library(lib)}
  % if not lib.build in ["tool"]:
  ${cc_install(lib)}
  % 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 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
  )
  % 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>)
