1%YAML 1.2 2--- | 3 # GRPC global cmake file 4 # This currently builds C and C++ code. 5 # This file has been automatically generated from a template file. 6 # Please look at the templates directory instead. 7 # This file can be regenerated from the template by running 8 # tools/buildgen/generate_projects.sh 9 # 10 # Copyright 2015 gRPC authors. 11 # 12 # Licensed under the Apache License, Version 2.0 (the "License"); 13 # you may not use this file except in compliance with the License. 14 # You may obtain a copy of the License at 15 # 16 # http://www.apache.org/licenses/LICENSE-2.0 17 # 18 # Unless required by applicable law or agreed to in writing, software 19 # distributed under the License is distributed on an "AS IS" BASIS, 20 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 # See the License for the specific language governing permissions and 22 # limitations under the License. 23 24 <% 25 import re 26 27 proto_re = re.compile('(.*)\\.proto') 28 lib_map = {lib.name: lib for lib in libs} 29 30 third_party_proto_prefixes = {lib.proto_prefix for lib in external_proto_libraries} 31 32 gpr_libs = ['gpr'] 33 grpc_libs = ['grpc', 'grpc_unsecure'] 34 grpcxx_libs = ['grpc++', 'grpc++_unsecure'] 35 protoc_libs = ['benchmark_helpers', 'grpc++_reflection', 'grpcpp_channelz'] 36 37 def third_party_proto_import_path(path): 38 """Removes third_party prefix to match ProtoBuf's relative import path.""" 39 for prefix in third_party_proto_prefixes: 40 if path.startswith(prefix): 41 return path[len(prefix):] 42 return path 43 44 def proto_replace_ext(filename, ext): 45 """Replace the .proto extension with given extension.""" 46 m = proto_re.match(filename) 47 if not m: 48 return filename 49 return '${_gRPC_PROTO_GENS_DIR}/' + third_party_proto_import_path(m.group(1)) + ext 50 51 def is_absl_lib(lib_name): 52 """Returns True if the library is one of the abseil libraries.""" 53 return lib_name.startswith("absl/") 54 55 def get_absl_dep(lib_name): 56 """Gets the corresponding cmake target for given absl library.""" 57 # The "cmake_target" field originates from src/abseil-cpp/preprocessed_builds.yaml.gen.py 58 return lib_map[lib_name].cmake_target 59 60 def get_transitive_deps(lib_name): 61 """Get list of transitive deps for given library.""" 62 transitive_deps = [] 63 lib_metadata = lib_map.get(lib_name, None) 64 if lib_metadata: 65 transitive_deps = lib_metadata.transitive_deps 66 return list(transitive_deps) 67 68 def list_abseil_pkg_targets(lib): 69 # TODO(jtattermusch): this function is odd, try to eliminate it. 70 # This returns a list of abseil pkg targets which the given lib and 71 # its non-abseil transitive dependencies depend on. 72 # As a result, internal abseil libraries are excluded from the result. 73 absl_specs = set() 74 transitive_deps_and_self = [lib] + get_transitive_deps(lib) 75 for lib_name in transitive_deps_and_self: 76 if is_absl_lib(lib_name): continue 77 lib_metadata = lib_map.get(lib_name, None) 78 if lib_metadata: 79 for dep in lib_metadata.deps: 80 if is_absl_lib(dep): 81 absl_specs.add(get_absl_dep(dep).replace("::", "_")) 82 return list(sorted(absl_specs)) 83 84 def lib_name_to_pkgconfig_requires_private_name(lib_name): 85 """If library belongs to pkgconfig Requires.private section, return the name under which to include it.""" 86 # TODO(jtattermusch): extract the metadata to a centralized location. 87 deps_to_pkgconfig_requires_private = { 88 "cares": "libcares", 89 "libssl": "openssl", 90 "re2": "re2", 91 "z": "zlib", 92 } 93 return deps_to_pkgconfig_requires_private.get(lib_name, None) 94 95 def is_pkgconfig_package(lib_name): 96 """Returns True if a pkgconfig package exists for a given library.""" 97 # TODO(jtattermusch): extract the metadata to a centralized location. 98 if lib_name in ["address_sorting", "utf8_range_lib"]: 99 return False 100 if lib_name == "upb" or lib_name.startswith("upb_"): 101 # TODO(jtattermusch): Add better detection for what are the "upb" libs. 102 return False 103 return True 104 105 def get_pkgconfig_requires(lib): 106 """Returns "Requires" list for generating the pkgconfig .pc file for given library.""" 107 requires = set() 108 requires.update(list_abseil_pkg_targets(lib)) 109 for lib_name in get_transitive_deps(lib): 110 if not is_pkgconfig_package(lib_name): 111 # these deps go into Libs or Libs.Private 112 continue 113 if is_absl_lib(lib_name): 114 # absl libs have special handling 115 continue 116 if lib_name_to_pkgconfig_requires_private_name(lib_name) is not None: 117 # these deps go into Requires.private 118 continue 119 if lib_name == 'protobuf': 120 # TODO(jtattermusch): add better way of excluding explicit protobuf dependency. 121 continue 122 if lib_name == 'opentelemetry-cpp::api': 123 requires.add('opentelemetry_api') 124 else: 125 requires.add(lib_name) 126 return list(sorted(requires)) 127 128 def get_pkgconfig_requires_private(lib): 129 """Returns the "Requires.private" list for generating the pkgconfig .pc file for given library.""" 130 private_requires = set() 131 for lib_name in get_transitive_deps(lib): 132 if is_absl_lib(lib_name): 133 # absl deps to into Requires 134 continue 135 require_name = lib_name_to_pkgconfig_requires_private_name(lib_name) 136 if require_name: 137 private_requires.add(require_name) 138 return list(sorted(private_requires)) 139 140 def get_pkgconfig_libs(lib): 141 """The "Libs" list for generating the pkgconfig .pc file for given library.""" 142 libs = set() 143 # add self 144 libs.add("-l" + lib) 145 return list(sorted(libs)) 146 147 def get_pkgconfig_libs_private(lib): 148 """The "Libs.private" list for generating the pkgconfig .pc file for given library.""" 149 private_libs = [] 150 for lib_name in get_transitive_deps(lib): 151 if is_absl_lib(lib_name): 152 # absl deps to into Requires 153 continue 154 if is_pkgconfig_package(lib_name): 155 continue 156 # Transitive deps are pre-sorted in topological order. 157 # We must maintain that order to prevent linkage errors. 158 private_libs.append("-l" + lib_name) 159 return private_libs 160 161 def lib_type_for_lib(lib_name): 162 """Returns STATIC/SHARED to force a static or shared lib build depending on the library.""" 163 # grpc_csharp_ext is loaded by C# runtime and it 164 # only makes sense as a shared lib. 165 if lib_name in ['grpc_csharp_ext']: 166 return ' SHARED' 167 168 # upb always compiles as a static library on Windows 169 elif lib_name in ['upb','upb_collections_lib','upb_json_lib','upb_textformat_lib'] + protoc_libs: 170 return ' ${_gRPC_STATIC_WIN32}' 171 172 else: 173 return '' 174 175 def get_deps(target_dict): 176 # TODO(jtattermusch): remove special cases based on target names 177 deps = [] 178 deps.append("${_gRPC_ALLTARGETS_LIBRARIES}") 179 for d in target_dict.get('deps', []): 180 if d == 'z': 181 deps.append("${_gRPC_ZLIB_LIBRARIES}") 182 elif d == 'address_sorting': 183 deps.append("${_gRPC_ADDRESS_SORTING_LIBRARIES}") 184 elif d == 'benchmark': 185 deps.append("${_gRPC_BENCHMARK_LIBRARIES}") 186 elif d == 'libssl': 187 deps.append("${_gRPC_SSL_LIBRARIES}") 188 elif d == 're2': 189 deps.append("${_gRPC_RE2_LIBRARIES}") 190 elif d == 'cares': 191 deps.append("${_gRPC_CARES_LIBRARIES}") 192 elif d == 'protobuf': 193 deps.append("${_gRPC_PROTOBUF_LIBRARIES}") 194 elif d == 'protoc': 195 deps.append("${_gRPC_PROTOBUF_PROTOC_LIBRARIES}") 196 elif is_absl_lib(d): 197 deps.append(get_absl_dep(d)) 198 # TODO(jtattermusch): add handling for upb libraries 199 else: 200 deps.append(d) 201 return deps 202 203 def is_generate_cmake_target(lib_or_target): 204 """Returns True if a cmake target should be generated for given library/target.""" 205 # TODO(jtattermusch): extract the metadata to a centralized location. 206 if lib_or_target.build not in ["all", "plugin", "plugin_test", "protoc", "tool", "test", "private"]: 207 return False 208 if lib_or_target.boringssl: 209 # Don't generate target for boringssl libs or tests 210 return False 211 if lib_or_target.name in ['cares', 'benchmark', 're2', 'xxhash', 'z']: 212 # we rely on these target to be created by external cmake builds. 213 return False 214 if is_absl_lib(lib_or_target.name): 215 # we rely on absl targets to be created by an external cmake build. 216 return False 217 return True 218 219 def get_platforms_condition_begin(platforms): 220 if all(platform in platforms for platform in ['linux', 'mac', 'posix', 'windows']): 221 return '' 222 cond = ' OR '.join(['_gRPC_PLATFORM_%s' % platform.upper() for platform in platforms]) 223 return 'if(%s)' % cond 224 225 def get_platforms_condition_end(platforms): 226 if not get_platforms_condition_begin(platforms): 227 return '' 228 return 'endif()' 229 230 def platforms_condition_block(platforms): 231 def _func(text): 232 lines = text.split('\n') 233 cond = get_platforms_condition_begin(platforms) 234 if cond: 235 # Remove empty line following <%block> 236 del lines[0] 237 238 # Indent each line after 239 for i, line in enumerate(lines[:-1]): 240 if line: 241 lines[i] = ' ' + line 242 243 # Add the condition block 244 lines.insert(0, cond) 245 246 # Add endif() to the last line 247 lines[-1] += 'endif()' 248 else: 249 # Remove empty line following <%block> 250 del lines[0] 251 252 # Strip leading whitespace from first line 253 lines[0] = lines[0].lstrip(' ') 254 255 # Remove empty line before </%block> 256 del lines[-1] 257 258 return '\n'.join(lines) 259 return _func 260 261 %> 262 <% 263 # These files are added to a set so that they are not duplicated if multiple 264 # targets use them. Generating the same file multiple times with 265 # add_custom_command() is not allowed in CMake. 266 267 protobuf_gen_files = set() 268 for tgt in targets: 269 for src in tgt.src: 270 if proto_re.match(src): 271 protobuf_gen_files.add(src) 272 for lib in libs: 273 for src in lib.src: 274 if proto_re.match(src): 275 protobuf_gen_files.add(src) 276 %> 277 278 cmake_minimum_required(VERSION 3.16) 279 280 set(PACKAGE_NAME "grpc") 281 set(PACKAGE_VERSION "${settings.cpp_version}") 282 set(gRPC_CORE_VERSION "${settings.core_version}") 283 set(gRPC_CORE_SOVERSION "${settings.core_version.major}") 284 set(gRPC_CPP_VERSION "${settings.cpp_version}") 285 set(gRPC_CPP_SOVERSION "${settings.cpp_version.major}.${settings.cpp_version.minor}") 286 set(PACKAGE_STRING "<%text>${PACKAGE_NAME} ${PACKAGE_VERSION}</%text>") 287 set(PACKAGE_TARNAME "<%text>${PACKAGE_NAME}-${PACKAGE_VERSION}</%text>") 288 set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") 289 project(<%text>${PACKAGE_NAME}</%text> LANGUAGES C CXX) 290 291 if(BUILD_SHARED_LIBS AND MSVC) 292 set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) 293 endif() 294 295 set(gRPC_INSTALL_BINDIR "bin" CACHE STRING "Installation directory for executables") 296 set(gRPC_INSTALL_LIBDIR "lib" CACHE STRING "Installation directory for libraries") 297 set(gRPC_INSTALL_INCLUDEDIR "include" CACHE STRING "Installation directory for headers") 298 set(gRPC_INSTALL_CMAKEDIR "lib/cmake/<%text>${PACKAGE_NAME}</%text>" CACHE STRING "Installation directory for cmake config files") 299 set(gRPC_INSTALL_SHAREDIR "share/grpc" CACHE STRING "Installation directory for root certificates") 300 set(gRPC_BUILD_MSVC_MP_COUNT 0 CACHE STRING "The maximum number of processes for MSVC /MP option") 301 302 # Options 303 option(gRPC_BUILD_TESTS "Build tests" OFF) 304 option(gRPC_BUILD_CODEGEN "Build codegen" ON) 305 option(gRPC_DOWNLOAD_ARCHIVES "Download archives for empty 3rd party directories" ON) 306 307 set(gRPC_INSTALL_default ON) 308 if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) 309 # Disable gRPC_INSTALL by default if building as a submodule 310 set(gRPC_INSTALL_default OFF) 311 endif() 312 set(gRPC_INSTALL <%text>${gRPC_INSTALL_default}</%text> CACHE BOOL 313 "Generate installation target") 314 315 # We can install dependencies from submodules if we're running 316 # CMake v3.13 or newer. 317 if(CMAKE_VERSION VERSION_LESS 3.13) 318 set(_gRPC_INSTALL_SUPPORTED_FROM_MODULE OFF) 319 else() 320 set(_gRPC_INSTALL_SUPPORTED_FROM_MODULE ON) 321 endif() 322 323 # Providers for third-party dependencies (gRPC_*_PROVIDER properties): 324 # "module": build the dependency using sources from git submodule (under third_party) 325 # "package": use cmake's find_package functionality to locate a pre-installed dependency 326 327 set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library") 328 set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package") 329 330 set(gRPC_CARES_PROVIDER "module" CACHE STRING "Provider of c-ares library") 331 set_property(CACHE gRPC_CARES_PROVIDER PROPERTY STRINGS "module" "package") 332 333 set(gRPC_RE2_PROVIDER "module" CACHE STRING "Provider of re2 library") 334 set_property(CACHE gRPC_RE2_PROVIDER PROPERTY STRINGS "module" "package") 335 336 set(gRPC_SSL_PROVIDER "module" CACHE STRING "Provider of ssl library") 337 set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package") 338 339 set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library") 340 set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package") 341 342 if(gRPC_BUILD_TESTS) 343 set(gRPC_BENCHMARK_PROVIDER "module" CACHE STRING "Provider of benchmark library") 344 set_property(CACHE gRPC_BENCHMARK_PROVIDER PROPERTY STRINGS "module" "package") 345 else() 346 set(gRPC_BENCHMARK_PROVIDER "none") 347 endif() 348 349 set(gRPC_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library") 350 set_property(CACHE gRPC_ABSL_PROVIDER PROPERTY STRINGS "module" "package") 351 <% 352 # Collect all abseil rules used by gpr, grpc, so on. 353 used_abseil_rules = set() 354 for lib in libs: 355 if lib.get("baselib"): 356 for dep in lib.transitive_deps: 357 if is_absl_lib(dep): 358 used_abseil_rules.add(lib_map[dep].cmake_target.replace("::", "_")) 359 %> 360 set(gRPC_ABSL_USED_TARGETS 361 % for rule in sorted(used_abseil_rules): 362 ${rule} 363 % endfor 364 absl_meta 365 ) 366 367 # The OpenTelemetry plugin supports "package" build only at present. 368 set(gRPC_OPENTELEMETRY_PROVIDER "package") 369 # set(gRPC_OPENTELEMETRY_PROVIDER "module" CACHE STRING "Provider of opentelemetry library") 370 # set_property(CACHE gRPC_OPENTELEMETRY_PROVIDER PROPERTY STRINGS "module" "package") 371 372 set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library") 373 374 if(UNIX) 375 if(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Linux") 376 set(_gRPC_PLATFORM_LINUX ON) 377 if(NOT CMAKE_CROSSCOMPILING AND CMAKE_SIZEOF_VOID_P EQUAL 4) 378 message("+++ Enabling SSE2 for <%text>${CMAKE_SYSTEM_PROCESSOR}</%text>") 379 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> -msse2") 380 endif() 381 elseif(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Darwin") 382 set(_gRPC_PLATFORM_MAC ON) 383 elseif(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "iOS") 384 set(_gRPC_PLATFORM_IOS ON) 385 elseif(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Android") 386 set(_gRPC_PLATFORM_ANDROID ON) 387 else() 388 set(_gRPC_PLATFORM_POSIX ON) 389 endif() 390 endif() 391 if(WIN32) 392 set(_gRPC_PLATFORM_WINDOWS ON) 393 endif() 394 395 if (APPLE AND NOT DEFINED CMAKE_CXX_STANDARD) 396 # AppleClang defaults to C++98, so we bump it to C++17. 397 message("CMAKE_CXX_STANDARD was undefined, defaulting to C++17.") 398 set(CMAKE_CXX_STANDARD 17) 399 endif () 400 401 ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF 402 if (NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) 403 set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) 404 endif() 405 list(APPEND CMAKE_MODULE_PATH "<%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/cmake/modules") 406 407 if(MSVC) 408 include(cmake/msvc_static_runtime.cmake) 409 add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS) 410 # Set /MP option 411 if (gRPC_BUILD_MSVC_MP_COUNT GREATER 0) 412 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS} /MP${gRPC_BUILD_MSVC_MP_COUNT}</%text>") 413 elseif (gRPC_BUILD_MSVC_MP_COUNT LESS 0) 414 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /MP") 415 endif() 416 # needed to compile protobuf 417 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /wd4065 /wd4506") 418 # TODO(jtattermusch): revisit warnings that were silenced as part of upgrade to protobuf3.6.0 419 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /wd4200 /wd4291 /wd4244") 420 # TODO(jtattermusch): revisit C4267 occurrences throughout the code 421 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /wd4267") 422 # TODO(jtattermusch): needed to build boringssl with VS2017, revisit later 423 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /wd4987 /wd4774 /wd4819 /wd4996 /wd4619") 424 # Silences thousands of trucation warnings 425 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /wd4503") 426 # Tell MSVC to build grpc using utf-8 427 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /utf-8") 428 # Inconsistent object sizes can cause stack corruption and should be treated as an error 429 set(_gRPC_C_CXX_FLAGS "<%text>${_gRPC_C_CXX_FLAGS}</%text> /we4789") 430 # To decrease the size of PDB files 431 set(CMAKE_EXE_LINKER_FLAGS "/opt:ref /opt:icf /pdbcompress") 432 endif() 433 if (MINGW) 434 add_definitions(-D_WIN32_WINNT=0x600) 435 endif() 436 set(CMAKE_C_FLAGS "<%text>${CMAKE_C_FLAGS} ${_gRPC_C_CXX_FLAGS}</%text>") 437 set(CMAKE_CXX_FLAGS "<%text>${CMAKE_CXX_FLAGS} ${_gRPC_C_CXX_FLAGS}</%text>") 438 439 if(gRPC_USE_PROTO_LITE) 440 set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf-lite") 441 add_definitions("-DGRPC_USE_PROTO_LITE") 442 else() 443 set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") 444 endif() 445 446 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_IOS) 447 set(_gRPC_CORE_NOSTDCXX_FLAGS -fno-exceptions -fno-rtti) 448 else() 449 set(_gRPC_CORE_NOSTDCXX_FLAGS "") 450 endif() 451 452 if(UNIX AND NOT HAIKU) 453 # -pthread does more than -lpthread 454 set(THREADS_PREFER_PTHREAD_FLAG ON) 455 find_package(Threads) 456 set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> m Threads::Threads) 457 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) 458 find_library(LIBRT rt) 459 if(LIBRT) 460 set(_gRPC_ALLTARGETS_LIBRARIES <%text>${_gRPC_ALLTARGETS_LIBRARIES}</%text> rt) 461 endif() 462 endif() 463 endif() 464 465 include(CheckCXXSourceCompiles) 466 467 if(UNIX OR APPLE) 468 # Some systems require the __STDC_FORMAT_MACROS macro to be defined 469 # to get the fixed-width integer type formatter macros. 470 check_cxx_source_compiles("#include <inttypes.h> 471 #include <cstdio> 472 int main() 473 { 474 int64_t i64{}; 475 std::printf(\"%\" PRId64, i64); 476 }" 477 HAVE_STDC_FORMAT_MACROS) 478 if(NOT HAVE_STDC_FORMAT_MACROS) 479 add_definitions(-D__STDC_FORMAT_MACROS) 480 endif() 481 endif() 482 483 # configure ccache if requested 484 include(cmake/ccache.cmake) 485 486 include(cmake/abseil-cpp.cmake) 487 include(cmake/address_sorting.cmake) 488 include(cmake/benchmark.cmake) 489 include(cmake/cares.cmake) 490 include(cmake/protobuf.cmake) 491 include(cmake/re2.cmake) 492 include(cmake/ssl.cmake) 493 include(cmake/upb.cmake) 494 include(cmake/xxhash.cmake) 495 include(cmake/zlib.cmake) 496 include(cmake/download_archive.cmake) 497 498 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) 499 include(cmake/systemd.cmake) 500 set(_gRPC_ALLTARGETS_LIBRARIES <%text>${_gRPC_ALLTARGETS_LIBRARIES}</%text> <%text>${_gRPC_SYSTEMD_LIBRARIES}</%text>) 501 endif() 502 503 option(gRPC_BUILD_GRPCPP_OTEL_PLUGIN "Build grpcpp_otel_plugin" OFF) 504 if(gRPC_BUILD_GRPCPP_OTEL_PLUGIN) 505 include(cmake/opentelemetry-cpp.cmake) 506 endif() 507 508 % for external_proto_library in external_proto_libraries: 509 % if len(external_proto_library.urls) > 1: 510 # Setup external proto library at ${external_proto_library.destination} with ${len(external_proto_library.urls)} download URLs 511 % else: 512 # Setup external proto library at ${external_proto_library.destination} if it doesn't exist 513 % endif 514 % for download_url in external_proto_library.urls: 515 if (NOT EXISTS <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/${external_proto_library.destination} AND gRPC_DOWNLOAD_ARCHIVES) 516 # Download the archive via HTTP, validate the checksum, and extract to ${external_proto_library.destination}. 517 download_archive( 518 <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/${external_proto_library.destination} 519 ${download_url} 520 ${external_proto_library.hash} 521 ${external_proto_library.strip_prefix} 522 ) 523 endif() 524 % endfor 525 % endfor 526 527 if(WIN32) 528 set(_gRPC_ALLTARGETS_LIBRARIES <%text>${_gRPC_ALLTARGETS_LIBRARIES}</%text> ws2_32 crypt32) 529 set(_gRPC_STATIC_WIN32 STATIC) 530 endif() 531 532 if(BUILD_SHARED_LIBS AND WIN32) 533 534 # Currently for shared lib on Windows (i.e. a DLL) certain bits of source code 535 # are generated from protobuf definitions by upbc. This source code does not include 536 # annotations needed to export these functions from grpc.lib so we have to 537 # re-include a small subset of these. 538 # 539 # This is not an ideal situation because these functions will be unavailable 540 # to clients of grpc and the libraries that need this (e.g. grpc++) will 541 # include redundant duplicate code. Hence, the duplication is only activated 542 # for DLL builds - and should be completely removed when source files are 543 # generated with the necessary __declspec annotations. 544 set(gRPC_UPB_GEN_DUPL_SRC 545 src/core/ext/upb-gen/src/proto/grpc/gcp/altscontext.upb_minitable.c 546 src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb_minitable.c 547 src/core/ext/upb-gen/src/proto/grpc/gcp/transport_security_common.upb_minitable.c 548 ) 549 550 set(gRPC_ADDITIONAL_DLL_SRC 551 src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc 552 src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc 553 src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc 554 src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc 555 ) 556 557 set(gRPC_ADDITIONAL_DLL_CXX_SRC 558 src/cpp/common/tls_certificate_provider.cc 559 src/cpp/common/tls_certificate_verifier.cc 560 src/cpp/common/tls_credentials_options.cc 561 ) 562 563 endif() # BUILD_SHARED_LIBS AND WIN32 564 565 # Create directory for proto source files 566 set(_gRPC_PROTO_SRCS_DIR <%text>${CMAKE_BINARY_DIR}/protos</%text>) 567 file(MAKE_DIRECTORY <%text>${_gRPC_PROTO_SRCS_DIR}</%text>) 568 # Create directory for generated .proto files 569 set(_gRPC_PROTO_GENS_DIR <%text>${CMAKE_BINARY_DIR}/gens</%text>) 570 file(MAKE_DIRECTORY <%text>${_gRPC_PROTO_GENS_DIR}</%text>) 571 572 # protobuf_generate_grpc_cpp 573 # -------------------------- 574 # 575 # This method is no longer used by gRPC's CMake build process. However, it 576 # is used by many open source dependencies, that we might want to keep 577 # backward compatibility here. 578 # 579 # Add custom commands to process ``.proto`` files to C++ using protoc and 580 # GRPC plugin:: 581 # 582 # protobuf_generate_grpc_cpp [<ARGN>...] 583 # 584 # ``ARGN`` 585 # ``.proto`` files 586 # 587 function(protobuf_generate_grpc_cpp) 588 if(NOT ARGN) 589 message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files") 590 return() 591 endif() 592 593 foreach(FIL <%text>${ARGN}</%text>) 594 protobuf_generate_grpc_cpp_with_import_path_correction(<%text>${FIL}</%text> <%text>${FIL}</%text>) 595 endforeach() 596 endfunction() 597 598 # protobuf_generate_grpc_cpp_with_import_path_correction 599 # -------------------------- 600 # 601 # Add custom commands to process ``.proto`` files to C++ using protoc and 602 # GRPC plugin:: 603 # 604 # protobuf_generate_grpc_cpp_with_import_path_correction <FILE_LOCATION> <IMPORT_PATH> 605 # 606 # ``FILE_LOCATION`` 607 # The relative path of the ``.proto`` file to the project root 608 # ``IMPORT_PATH`` 609 # The proto import path that itself expected to be placed in. For 610 # example, a "bar.proto" file wants to be imported as 611 # `import "foo/bar.proto"`. Then we should place it under 612 # "<ProtoBuf_Include_Path>/foo/bar.proto" instead of 613 # "<ProtoBuf_Include_Path>/third_party/foo/bar.proto". This ensures 614 # correct symbol being generated and C++ include path being correct. 615 # More info can be found at https://github.com/grpc/grpc/pull/25272. 616 # 617 function(protobuf_generate_grpc_cpp_with_import_path_correction FILE_LOCATION IMPORT_PATH) 618 if(NOT FILE_LOCATION) 619 message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files") 620 return() 621 endif() 622 623 # Sets the include path for ProtoBuf files 624 set(_protobuf_include_path -I . -I <%text>${_gRPC_PROTOBUF_WELLKNOWN_INCLUDE_DIR}</%text>) 625 # The absolute path of the expected place for the input proto file 626 # For example, health proto has package name grpc.health.v1, it's expected to be: 627 # <%text>${_gRPC_PROTO_SRCS_DIR}/grpc/health/v1/health.proto</%text> 628 get_filename_component(ABS_FIL <%text>${_gRPC_PROTO_SRCS_DIR}/${IMPORT_PATH}</%text> ABSOLUTE) 629 # Get the name of the file, which used to generate output file names for 630 # this command. 631 # Example: "health" for "health.proto" 632 get_filename_component(FIL_WE <%text>${_gRPC_PROTO_SRCS_DIR}/${IMPORT_PATH}</%text> NAME_WE) 633 # Get the relative path between the expected place for the proto and the 634 # working directory. In normal cases, it would be equal IMPORT_PATH, but 635 # it's better to be agnostic to all the global folder locations (like the 636 # centralized location <%text>${_gRPC_PROTO_SRCS_DIR})</%text>. 637 # Example: grpc/health/v1/health.proto 638 file(RELATIVE_PATH REL_FIL <%text>${_gRPC_PROTO_SRCS_DIR}</%text> <%text>${ABS_FIL}</%text>) 639 # Get the directory of the relative path. 640 # Example: grpc/health/v1 641 get_filename_component(REL_DIR <%text>${REL_FIL}</%text> DIRECTORY) 642 # Get the directory and name for output filenames generation. 643 # Example: "grpc/health/v1/health", the file name extension is omitted. 644 set(RELFIL_WE "<%text>${REL_DIR}/${FIL_WE}</%text>") 645 # Copy the proto file to a centralized location, with the correct import 646 # path. For example, health proto has package name grpc.health.v1, the bash 647 # equivalent would be: 648 # cp src/proto/grpc/health/v1/health.proto <%text>${_gRPC_PROTO_SRCS_DIR}/grpc/health/v1</%text> 649 file(MAKE_DIRECTORY <%text>${_gRPC_PROTO_SRCS_DIR}/${REL_DIR}</%text>) 650 file(COPY <%text>${CMAKE_CURRENT_SOURCE_DIR}/${FILE_LOCATION}</%text> DESTINATION <%text>${_gRPC_PROTO_SRCS_DIR}/${REL_DIR}</%text>) 651 652 #if cross-compiling, find host plugin 653 if(CMAKE_CROSSCOMPILING) 654 find_program(_gRPC_CPP_PLUGIN grpc_cpp_plugin) 655 else() 656 set(_gRPC_CPP_PLUGIN $<TARGET_FILE:grpc_cpp_plugin>) 657 endif() 658 659 add_custom_command( 660 OUTPUT <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"</%text> 661 <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"</%text> 662 <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h"</%text> 663 <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"</%text> 664 <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"</%text> 665 COMMAND <%text>${_gRPC_PROTOBUF_PROTOC_EXECUTABLE}</%text> 666 ARGS --grpc_out=<%text>generate_mock_code=true:${_gRPC_PROTO_GENS_DIR}</%text> 667 --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR}</%text> 668 --plugin=protoc-gen-grpc=<%text>${_gRPC_CPP_PLUGIN}</%text> 669 <%text>${_protobuf_include_path}</%text> 670 <%text>${REL_FIL}</%text> 671 DEPENDS <%text>${CMAKE_CURRENT_SOURCE_DIR}/${FILE_LOCATION}</%text> <%text>${ABS_FIL}</%text> <%text>${_gRPC_PROTOBUF_PROTOC}</%text> <%text>${_gRPC_CPP_PLUGIN}</%text> 672 WORKING_DIRECTORY <%text>${_gRPC_PROTO_SRCS_DIR}</%text> 673 COMMENT "Running gRPC C++ protocol buffer compiler for <%text>${IMPORT_PATH}</%text>" 674 VERBATIM) 675 endfunction() 676 677 # These options allow users to enable or disable the building of the various 678 # protoc plugins. For example, running CMake with 679 # -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF will disable building the C# plugin. 680 set(_gRPC_PLUGIN_LIST) 681 % for tgt in targets: 682 % if tgt.build == 'protoc': 683 option(gRPC_BUILD_${tgt.name.upper()} "Build ${tgt.name}" ON) 684 if (gRPC_BUILD_${tgt.name.upper()}) 685 list(APPEND _gRPC_PLUGIN_LIST ${tgt.name}) 686 endif () 687 % endif 688 % endfor 689 690 add_custom_target(plugins 691 DEPENDS <%text>${_gRPC_PLUGIN_LIST}</%text> 692 ) 693 694 add_custom_target(tools_c 695 DEPENDS 696 % for tgt in targets: 697 % if tgt.build == 'tool' and not tgt.language == 'c++': 698 ${tgt.name} 699 % endif 700 % endfor 701 ) 702 703 add_custom_target(tools_cxx 704 DEPENDS 705 % for tgt in targets: 706 % if tgt.build == 'tool' and tgt.language == 'c++': 707 ${tgt.name} 708 % endif 709 % endfor 710 ) 711 712 add_custom_target(tools 713 DEPENDS tools_c tools_cxx) 714 715 % for src in sorted(protobuf_gen_files): 716 % if not src.startswith('third_party/'): 717 protobuf_generate_grpc_cpp_with_import_path_correction( 718 ${src} ${third_party_proto_import_path(src)} 719 ) 720 % endif 721 % endfor 722 723 # This enables CMake to build the project without requiring submodules 724 # in the third_party directory as long as test builds are disabled. 725 if (gRPC_BUILD_TESTS) 726 % for src in sorted(protobuf_gen_files): 727 % if src.startswith('third_party/'): 728 protobuf_generate_grpc_cpp_with_import_path_correction( 729 ${src} ${third_party_proto_import_path(src)} 730 ) 731 % endif 732 % endfor 733 endif() 734 735 if(gRPC_BUILD_TESTS) 736 add_custom_target(buildtests_c) 737 % for tgt in targets: 738 % if is_generate_cmake_target(tgt) and tgt.build == 'test' and not tgt.language == 'c++': 739 <%block filter='platforms_condition_block(tgt.platforms)'> 740 add_dependencies(buildtests_c ${tgt.name}) 741 </%block> 742 % endif 743 % endfor 744 745 add_custom_target(buildtests_cxx) 746 % for tgt in targets: 747 % if is_generate_cmake_target(tgt) and tgt.build == 'test' and tgt.language == 'c++': 748 <%block filter='platforms_condition_block(tgt.platforms)'> 749 add_dependencies(buildtests_cxx ${tgt.name}) 750 </%block> 751 % endif 752 % endfor 753 754 add_custom_target(buildtests 755 DEPENDS buildtests_c buildtests_cxx) 756 endif() 757 <% 758 cmake_libs = [] 759 for lib in libs: 760 if not is_generate_cmake_target(lib): continue 761 cmake_libs.append(lib) 762 %> 763 764 % for lib in cmake_libs: 765 % if lib.build in ["test", "private"]: 766 if(gRPC_BUILD_TESTS) 767 ${cc_library(lib)} 768 endif() 769 % else: 770 % if lib.build in ["plugin"]: 771 if(gRPC_BUILD_${lib.name.upper()}) 772 % endif 773 ${cc_library(lib)} 774 % if not lib.build in ["tool"]: 775 % if any(proto_re.match(src) for src in lib.src): 776 if(gRPC_BUILD_CODEGEN) 777 % endif 778 ${cc_install(lib)} 779 % if any(proto_re.match(src) for src in lib.src): 780 endif() 781 % endif 782 % endif 783 % if lib.build in ["plugin"]: 784 endif() 785 % endif 786 % endif 787 % endfor 788 789 % for tgt in targets: 790 % if is_generate_cmake_target(tgt): 791 % if tgt.build in ["test", "private"]: 792 if(gRPC_BUILD_TESTS) 793 <%block filter='platforms_condition_block(tgt.platforms)'> 794 ${cc_binary(tgt)} 795 </%block> 796 endif() 797 % elif tgt.build in ["plugin_test"]: 798 if(gRPC_BUILD_TESTS AND ${tgt.plugin_option}) 799 <%block filter='platforms_condition_block(tgt.platforms)'> 800 ${cc_binary(tgt)} 801 </%block> 802 endif() 803 % elif tgt.build in ["protoc"]: 804 if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_${tgt.name.upper()}) 805 <%block filter='platforms_condition_block(tgt.platforms)'> 806 ${cc_binary(tgt)} 807 ${cc_install(tgt)} 808 </%block> 809 endif() 810 % else: 811 <%block filter='platforms_condition_block(tgt.platforms)'> 812 ${cc_binary(tgt)} 813 % if not tgt.build in ["tool"]: 814 ${cc_install(tgt)} 815 % endif 816 </%block> 817 % endif 818 % endif 819 % endfor 820 821 <%def name="cc_library(lib)"> 822 % if any(proto_re.match(src) for src in lib.src): 823 % if lib.name == 'grpcpp_channelz': # TODO(jtattermusch): remove special case based on target name 824 # grpcpp_channelz doesn't build with protobuf-lite 825 # See https://github.com/grpc/grpc/issues/19473 826 if(gRPC_BUILD_CODEGEN AND NOT gRPC_USE_PROTO_LITE) 827 % else: 828 if(gRPC_BUILD_CODEGEN) 829 % endif 830 % endif 831 add_library(${lib.name}${lib_type_for_lib(lib.name)} 832 % for src in lib.src: 833 % if not proto_re.match(src): 834 ${src} 835 % else: 836 ${proto_replace_ext(src, '.pb.cc')} 837 ${proto_replace_ext(src, '.grpc.pb.cc')} 838 ${proto_replace_ext(src, '.pb.h')} 839 ${proto_replace_ext(src, '.grpc.pb.h')} 840 % if src in ["src/proto/grpc/testing/compiler_test.proto", "src/proto/grpc/testing/echo.proto"]: 841 ${proto_replace_ext(src, '_mock.grpc.pb.h')} 842 % endif 843 % endif 844 % endfor 845 % if lib.name in ['grpc++_alts', 'grpc++_unsecure', 'grpc++']: 846 <%text>${gRPC_UPB_GEN_DUPL_SRC}</%text> 847 % endif 848 % if lib.name in ['grpc_unsecure']: 849 <%text>${gRPC_ADDITIONAL_DLL_SRC}</%text> 850 % endif 851 % if lib.name in ['grpc++_unsecure']: 852 <%text>${gRPC_ADDITIONAL_DLL_CXX_SRC}</%text> 853 % endif 854 ) 855 856 target_compile_features(${lib.name} PUBLIC cxx_std_17) 857 858 set_target_properties(${lib.name} PROPERTIES 859 % if lib.language == 'c++': 860 VERSION <%text>${gRPC_CPP_VERSION}</%text> 861 SOVERSION <%text>${gRPC_CPP_SOVERSION}</%text> 862 % else: 863 VERSION <%text>${gRPC_CORE_VERSION}</%text> 864 SOVERSION <%text>${gRPC_CORE_SOVERSION}</%text> 865 % endif 866 ) 867 868 if(WIN32 AND MSVC) 869 set_target_properties(${lib.name} PROPERTIES COMPILE_PDB_NAME "${lib.name}" 870 COMPILE_PDB_OUTPUT_DIRECTORY <%text>"${CMAKE_BINARY_DIR}</%text>" 871 )<% 872 dll_annotations = [] 873 if lib.name in gpr_libs: 874 dll_annotations.append("GPR_DLL_EXPORTS") 875 if lib.name in grpc_libs: 876 dll_annotations.append("GRPC_DLL_EXPORTS") 877 if lib.name in grpcxx_libs: 878 dll_annotations.append("GRPCXX_DLL_EXPORTS") 879 if set(gpr_libs) & set(lib.transitive_deps): 880 dll_annotations.append("GPR_DLL_IMPORTS") 881 if set(grpc_libs) & set(lib.transitive_deps): 882 dll_annotations.append("GRPC_DLL_IMPORTS") 883 if set(grpcxx_libs) & set(lib.transitive_deps): 884 dll_annotations.append("GRPCXX_DLL_IMPORTS") 885 %> 886 % if dll_annotations: 887 if(BUILD_SHARED_LIBS) 888 target_compile_definitions(${lib.name} 889 PRIVATE 890 % for definition in dll_annotations: 891 "${definition}" 892 % endfor 893 ) 894 endif() 895 % endif 896 if(gRPC_INSTALL) 897 install(FILES <%text>${CMAKE_CURRENT_BINARY_DIR}/</%text>${lib.name}.pdb 898 DESTINATION <%text>${gRPC_INSTALL_LIBDIR}</%text> OPTIONAL 899 ) 900 endif() 901 endif() 902 903 target_include_directories(${lib.name} 904 PUBLIC <%text>$<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include></%text> 905 PRIVATE 906 <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text> 907 <%text>${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}</%text> 908 <%text>${_gRPC_RE2_INCLUDE_DIR}</%text> 909 <%text>${_gRPC_SSL_INCLUDE_DIR}</%text> 910 <%text>${_gRPC_UPB_GENERATED_DIR}</%text> 911 <%text>${_gRPC_UPB_GRPC_GENERATED_DIR}</%text> 912 <%text>${_gRPC_UPB_INCLUDE_DIR}</%text> 913 <%text>${_gRPC_XXHASH_INCLUDE_DIR}</%text> 914 <%text>${_gRPC_ZLIB_INCLUDE_DIR}</%text> 915 % if 'gtest' in lib.transitive_deps or lib.name == 'gtest': # TODO(jtattermusch): avoid special case based on target name 916 third_party/googletest/googletest/include 917 third_party/googletest/googletest 918 third_party/googletest/googlemock/include 919 third_party/googletest/googlemock 920 % endif 921 % if lib.language == 'c++': 922 <%text>${_gRPC_PROTO_GENS_DIR}</%text> 923 % endif 924 ) 925 % if len(get_deps(lib)) > 0: 926 target_link_libraries(${lib.name} 927 % for dep in get_deps(lib): 928 ${dep} 929 % endfor 930 ) 931 % endif 932 % if lib.name in ["gpr"]: # TODO(jtattermusch): avoid special case based on target name 933 if(_gRPC_PLATFORM_ANDROID) 934 target_link_libraries(gpr 935 android 936 log 937 ) 938 endif() 939 % endif 940 % if lib.name in ["grpc", "grpc_cronet", "grpc_test_util", \ 941 "grpc_test_util_unsecure", "grpc_unsecure", \ 942 "grpc++_cronet"]: # TODO(jtattermusch): remove special cases based on target names 943 if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) 944 target_link_libraries(${lib.name} "-framework CoreFoundation") 945 endif() 946 %endif 947 948 % if len(lib.get('public_headers', [])) > 0: 949 foreach(_hdr 950 % for hdr in lib.get('public_headers', []): 951 ${hdr} 952 % endfor 953 ) 954 string(REPLACE "include/" "" _path <%text>${_hdr}</%text>) 955 get_filename_component(_path <%text>${_path}</%text> PATH) 956 install(FILES <%text>${_hdr}</%text> 957 DESTINATION "<%text>${gRPC_INSTALL_INCLUDEDIR}/${_path}</%text>" 958 ) 959 endforeach() 960 % endif 961 % if any(proto_re.match(src) for src in lib.src): 962 endif() 963 % endif 964 </%def> 965 966 <%def name="cc_binary(tgt)"> 967 add_executable(${tgt.name} 968 % for src in tgt.src: 969 % if not proto_re.match(src): 970 ${src} 971 % else: 972 ${proto_replace_ext(src, '.pb.cc')} 973 ${proto_replace_ext(src, '.grpc.pb.cc')} 974 ${proto_replace_ext(src, '.pb.h')} 975 ${proto_replace_ext(src, '.grpc.pb.h')} 976 % endif 977 % endfor 978 )<% 979 dll_annotations = [] 980 if set(gpr_libs) & set(tgt.transitive_deps): 981 dll_annotations.append("GPR_DLL_IMPORTS") 982 if set(grpc_libs) & set(tgt.transitive_deps): 983 dll_annotations.append("GRPC_DLL_IMPORTS") 984 if set(grpcxx_libs) & set(tgt.transitive_deps): 985 dll_annotations.append("GRPCXX_DLL_IMPORTS") 986 %> 987 % if dll_annotations: 988 if(WIN32 AND MSVC) 989 if(BUILD_SHARED_LIBS) 990 target_compile_definitions(${tgt.name} 991 PRIVATE 992 % for definition in dll_annotations: 993 "${definition}" 994 % endfor 995 ) 996 endif() 997 endif() 998 % endif 999 target_compile_features(${tgt.name} PUBLIC cxx_std_17) 1000 target_include_directories(${tgt.name} 1001 PRIVATE 1002 <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text> 1003 <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/include 1004 <%text>${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}</%text> 1005 <%text>${_gRPC_RE2_INCLUDE_DIR}</%text> 1006 <%text>${_gRPC_SSL_INCLUDE_DIR}</%text> 1007 <%text>${_gRPC_UPB_GENERATED_DIR}</%text> 1008 <%text>${_gRPC_UPB_GRPC_GENERATED_DIR}</%text> 1009 <%text>${_gRPC_UPB_INCLUDE_DIR}</%text> 1010 <%text>${_gRPC_XXHASH_INCLUDE_DIR}</%text> 1011 <%text>${_gRPC_ZLIB_INCLUDE_DIR}</%text> 1012 % if 'gtest' in tgt.transitive_deps: 1013 third_party/googletest/googletest/include 1014 third_party/googletest/googletest 1015 third_party/googletest/googlemock/include 1016 third_party/googletest/googlemock 1017 % endif 1018 % if tgt.language == 'c++': 1019 <%text>${_gRPC_PROTO_GENS_DIR}</%text> 1020 % endif 1021 ) 1022 1023 % if len(get_deps(tgt)) > 0: 1024 target_link_libraries(${tgt.name} 1025 % for dep in get_deps(tgt): 1026 ${dep} 1027 % endfor 1028 ) 1029 1030 % endif 1031 </%def> 1032 1033 <%def name="cc_install(tgt)"> 1034 % if tgt.name == 'grpcpp_channelz': 1035 # grpcpp_channelz doesn't build with protobuf-lite, so no install required 1036 # See https://github.com/grpc/grpc/issues/22826 1037 if(gRPC_INSTALL AND NOT gRPC_USE_PROTO_LITE) 1038 % else: 1039 if(gRPC_INSTALL) 1040 % endif 1041 % if tgt.build == 'protoc' and 'grpc_plugin_support' in tgt.get('deps', []): 1042 install(TARGETS ${tgt.name} EXPORT gRPCPluginTargets 1043 % else: 1044 install(TARGETS ${tgt.name} EXPORT gRPCTargets 1045 % endif 1046 RUNTIME DESTINATION <%text>${gRPC_INSTALL_BINDIR}</%text> 1047 BUNDLE DESTINATION <%text>${gRPC_INSTALL_BINDIR}</%text> 1048 LIBRARY DESTINATION <%text>${gRPC_INSTALL_LIBDIR}</%text> 1049 ARCHIVE DESTINATION <%text>${gRPC_INSTALL_LIBDIR}</%text> 1050 ) 1051 endif() 1052 </%def> 1053 1054 if(gRPC_INSTALL) 1055 install(EXPORT gRPCTargets 1056 DESTINATION <%text>${gRPC_INSTALL_CMAKEDIR}</%text> 1057 NAMESPACE gRPC:: 1058 ) 1059 if(gRPC_BUILD_CODEGEN) 1060 install(EXPORT gRPCPluginTargets 1061 DESTINATION <%text>${gRPC_INSTALL_CMAKEDIR}</%text> 1062 NAMESPACE gRPC:: 1063 ) 1064 endif() 1065 endif() 1066 1067 include(CMakePackageConfigHelpers) 1068 1069 configure_file(cmake/gRPCConfig.cmake.in 1070 gRPCConfig.cmake @ONLY) 1071 write_basic_package_version_file(<%text>${CMAKE_CURRENT_BINARY_DIR}/</%text>gRPCConfigVersion.cmake 1072 VERSION <%text>${gRPC_CPP_VERSION}</%text> 1073 COMPATIBILITY AnyNewerVersion) 1074 install(FILES 1075 <%text>${CMAKE_CURRENT_BINARY_DIR}/</%text>gRPCConfig.cmake 1076 <%text>${CMAKE_CURRENT_BINARY_DIR}/</%text>gRPCConfigVersion.cmake 1077 DESTINATION <%text>${gRPC_INSTALL_CMAKEDIR}</%text> 1078 ) 1079 install(FILES 1080 <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/cmake/modules/Findc-ares.cmake 1081 <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/cmake/modules/Findre2.cmake 1082 <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/cmake/modules/Findsystemd.cmake 1083 DESTINATION <%text>${gRPC_INSTALL_CMAKEDIR}</%text>/modules 1084 ) 1085 1086 install(FILES <%text>${CMAKE_CURRENT_SOURCE_DIR}/etc/roots.pem</%text> 1087 DESTINATION <%text>${gRPC_INSTALL_SHAREDIR}</%text>) 1088 1089 # Function to generate pkg-config files. 1090 function(generate_pkgconfig name description version requires requires_private 1091 libs libs_private output_filename) 1092 set(PC_NAME "<%text>${name}</%text>") 1093 set(PC_DESCRIPTION "<%text>${description}</%text>") 1094 set(PC_VERSION "<%text>${version}</%text>") 1095 set(PC_REQUIRES "<%text>${requires}</%text>") 1096 set(PC_REQUIRES_PRIVATE "<%text>${requires_private}</%text>") 1097 set(PC_LIB "<%text>${libs}</%text>") 1098 set(PC_LIBS_PRIVATE "<%text>${libs_private}</%text>") 1099 set(output_filepath "<%text>${grpc_BINARY_DIR}/libs/opt/pkgconfig/${output_filename}</%text>") 1100 configure_file( 1101 "<%text>${grpc_SOURCE_DIR}/cmake/pkg-config-template.pc.in</%text>" 1102 "<%text>${output_filepath}</%text>" 1103 @ONLY) 1104 install(FILES "<%text>${output_filepath}</%text>" 1105 DESTINATION "<%text>${gRPC_INSTALL_LIBDIR}/pkgconfig</%text>") 1106 endfunction() 1107 1108 # gpr .pc file 1109 generate_pkgconfig( 1110 "gpr" 1111 "gRPC platform support library" 1112 "<%text>${gRPC_CORE_VERSION}</%text>" 1113 "${" ".join(get_pkgconfig_requires("gpr"))}" 1114 "${" ".join(get_pkgconfig_requires_private("gpr"))}" 1115 "${" ".join(get_pkgconfig_libs("gpr"))}" 1116 "${" ".join(get_pkgconfig_libs_private("gpr"))}" 1117 "gpr.pc") 1118 1119 # grpc .pc file 1120 generate_pkgconfig( 1121 "gRPC" 1122 "high performance general RPC framework" 1123 "<%text>${gRPC_CORE_VERSION}</%text>" 1124 "${" ".join(get_pkgconfig_requires("grpc"))}" 1125 "${" ".join(get_pkgconfig_requires_private("grpc"))}" 1126 "${" ".join(get_pkgconfig_libs("grpc"))}" 1127 "${" ".join(get_pkgconfig_libs_private("grpc"))}" 1128 "grpc.pc") 1129 1130 # grpc_unsecure .pc file 1131 generate_pkgconfig( 1132 "gRPC unsecure" 1133 "high performance general RPC framework without SSL" 1134 "<%text>${gRPC_CORE_VERSION}</%text>" 1135 "${" ".join(get_pkgconfig_requires("grpc_unsecure"))}" 1136 "${" ".join(get_pkgconfig_requires_private("grpc_unsecure"))}" 1137 "${" ".join(get_pkgconfig_libs("grpc_unsecure"))}" 1138 "${" ".join(get_pkgconfig_libs_private("grpc_unsecure"))}" 1139 "grpc_unsecure.pc") 1140 1141 # grpc++ .pc file 1142 generate_pkgconfig( 1143 "gRPC++" 1144 "C++ wrapper for gRPC" 1145 "<%text>${gRPC_CPP_VERSION}</%text>" 1146 "${" ".join(get_pkgconfig_requires("grpc++"))}" 1147 "${" ".join(get_pkgconfig_requires_private("grpc++"))}" 1148 "${" ".join(get_pkgconfig_libs("grpc++"))}" 1149 "${" ".join(get_pkgconfig_libs_private("grpc++"))}" 1150 "grpc++.pc") 1151 1152 # grpc++_unsecure .pc file 1153 generate_pkgconfig( 1154 "gRPC++ unsecure" 1155 "C++ wrapper for gRPC without SSL" 1156 "<%text>${gRPC_CPP_VERSION}</%text>" 1157 "${" ".join(get_pkgconfig_requires("grpc++_unsecure"))}" 1158 "${" ".join(get_pkgconfig_requires_private("grpc++_unsecure"))}" 1159 "${" ".join(get_pkgconfig_libs("grpc++_unsecure"))}" 1160 "${" ".join(get_pkgconfig_libs_private("grpc++_unsecure"))}" 1161 "grpc++_unsecure.pc") 1162 1163 # grpcpp_otel_plugin .pc file 1164 generate_pkgconfig( 1165 "gRPC++ OpenTelemetry Plugin" 1166 "OpenTelemetry Plugin for gRPC C++" 1167 "<%text>${gRPC_CPP_VERSION}</%text>" 1168 "${" ".join(get_pkgconfig_requires("grpcpp_otel_plugin"))}" 1169 "${" ".join(get_pkgconfig_requires_private("grpcpp_otel_plugin"))}" 1170 "${" ".join(get_pkgconfig_libs("grpcpp_otel_plugin"))}" 1171 "${" ".join(get_pkgconfig_libs_private("grpcpp_otel_plugin"))}" 1172 "grpcpp_otel_plugin.pc") 1173