From eab5cb57dd38531023b1e7e7a529882c268d1333 Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Fri, 28 Jun 2019 15:01:33 -0400 Subject: Initial set of files. The make install target is not working for .proto files, but otherwise it seems to work. --- .cmake-format.py | 42 +++++ .editorconfig | 22 +++ .gitignore | 25 +++ CMakeLists.txt | 371 ++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 55 ++++++ LICENSE | 201 ++++++++++++++++++++++ README.md | 68 ++++++++ cmake/CompileProtos.cmake | 286 +++++++++++++++++++++++++++++++ cmake/FindProtobufTargets.cmake | 207 ++++++++++++++++++++++ cmake/FindgRPC.cmake | 343 +++++++++++++++++++++++++++++++++++++ cmake/SelectMSVCRuntime.cmake | 46 +++++ cmake/config-version.cmake.in | 35 ++++ cmake/config.cmake.in | 36 ++++ cmake/config.pc.in | 26 +++ 14 files changed, 1763 insertions(+) create mode 100644 .cmake-format.py create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 cmake/CompileProtos.cmake create mode 100644 cmake/FindProtobufTargets.cmake create mode 100644 cmake/FindgRPC.cmake create mode 100644 cmake/SelectMSVCRuntime.cmake create mode 100644 cmake/config-version.cmake.in create mode 100644 cmake/config.cmake.in create mode 100644 cmake/config.pc.in diff --git a/.cmake-format.py b/.cmake-format.py new file mode 100644 index 0000000000..f6ceafc1aa --- /dev/null +++ b/.cmake-format.py @@ -0,0 +1,42 @@ +# 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 +# +# 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. + +tab_size = 4 +separate_ctrl_name_with_space = True + +additional_commands = { + "externalproject_add": { + "flags": [ + ], + "kwargs": { + "BUILD_COMMAND": "+", + "BUILD_BYPRODUCTS": "+", + "CMAKE_ARGS": "+", + "COMMAND": "+", + "CONFIGURE_COMMAND": "+", + "DEPENDS": "+", + "DOWNLOAD_COMMAND": "+", + "EXCLUDE_FROM_ALL": 1, + "INSTALL_COMMAND": "+", + "INSTALL_DIR": 1, + "LOG_BUILD": 1, + "LOG_CONFIGURE": 1, + "LOG_DOWNLOAD": 1, + "LOG_INSTALL": 1, + "PREFIX": 1, + "URL": 1, + "URL_HASH": 1, + } + } +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..0983572c65 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space + +[BUILD] +indent_size = 4 + +[CMakeLists.*] +indent_size = 4 + +[*.h,*.cc] +indent_size = 2 + +[*.md] +indent_size = 2 + +[*.sh] +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..765f3e124b --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Common build output directory names +.build/ +_build/ +build-output/ +cmake-out/ + +# Common bazel output directories +bazel-* + +# Backup files for Emacs +*~ + +# Ignore IDEA / IntelliJ files +.idea/ +cmake-build-*/ + +# This is a staging directory used to upload the documents to gihub.io +github-io-staging/ + +# Ignore Visual Studio Code files +.vsbuild/ +.vscode/ + +google/cloud/storage/testbench/__pycache__/ +google/cloud/storage/testbench/*.pyc diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..edc8f23205 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,371 @@ +# ~~~ +# 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 +# +# 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. +# ~~~ + +cmake_minimum_required(VERSION 3.5) + +# Define the project name and where to report bugs. +set(PACKAGE_BUGREPORT "https://github.com/googleapis/google-cloud-cpp/issues") +project(googleapis-cpp-protos CXX C) + +set(GOOGLEAPIS_CPP_PROTOS_VERSION_MAJOR 0) +set(GOOGLEAPIS_CPP_PROTOS_VERSION_MINOR 2) +set(GOOGLEAPIS_CPP_PROTOS_VERSION_PATCH 0) + +string(CONCAT GOOGLE_APIS_CPP_PROTOS_VERSION + "${GOOGLEAPIS_CPP_PROTOS_VERSION_MAJOR}" + "." + "${GOOGLEAPIS_CPP_PROTOS_VERSION_MINOR}" + "." + "${GOOGLEAPIS_CPP_PROTOS_VERSION_PATCH}") + +# Configure the compiler options, we will be using C++11 features. +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Give application developers a hook to configure the version and hash +# downloaded from GitHub. +set( + GOOGLE_CLOUD_CPP_GOOGLEAPIS_URL + "https://github.com/googleapis/googleapis/archive/a8ee1416f4c588f2ab92da72e7c1f588c784d3e6.tar.gz" + ) +set(GOOGLE_CLOUD_CPP_GOOGLEAPIS_SHA256 + "6b8a9b2bcb4476e9a5a9872869996f0d639c8d5df76dd8a893e79201f211b1cf") + +include(ExternalProject) +externalproject_add(googleapis_download + EXCLUDE_FROM_ALL ON + PREFIX "${CMAKE_BINARY_DIR}/external/googleapis" + URL ${GOOGLE_CLOUD_CPP_GOOGLEAPIS_URL} + URL_HASH SHA256=${GOOGLE_CLOUD_CPP_GOOGLEAPIS_SHA256} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD OFF) +externalproject_get_property(googleapis_download SOURCE_DIR) +set(GOOGLEAPIS_CPP_SOURCE "${SOURCE_DIR}") + +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") +find_package(ProtobufTargets REQUIRED) +find_package(gRPC REQUIRED) + +# Sometimes (this happens often with vcpkg) protobuf is installed in a non- +# standard directory. We need to find out where, and then add that directory to +# the search path for protos. +find_path(PROTO_INCLUDE_DIR google/protobuf/descriptor.proto) +if (PROTO_INCLUDE_DIR) + list(INSERT PROTOBUF_IMPORT_DIRS 0 "${PROTO_INCLUDE_DIR}") +endif () + +add_library(googleapis_cpp_common_flags INTERFACE) + +include(SelectMSVCRuntime) + +# Include the functions to compile proto files. +include(CompileProtos) + +google_cloud_cpp_add_protos_property() + +function (googleapis_cpp_set_version_and_alias short_name) + add_dependencies("googleapis_cpp_${short_name}" googleapis_download) + set_target_properties("googleapis_cpp_${short_name}" + PROPERTIES VERSION + "${GOOGLE_APIS_CPP_PROTOS_VERSION}" + SOVERSION + ${GOOGLEAPIS_CPP_PROTOS_VERSION_MAJOR}) + add_library("googleapis-c++::${short_name}" ALIAS + "googleapis_cpp_${short_name}") +endfunction () + +google_cloud_cpp_grpcpp_library(googleapis_cpp_api_http_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/api/http.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(api_http_protos) +target_link_libraries(googleapis_cpp_api_http_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_api_annotations_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/api/annotations.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(api_annotations_protos) +target_link_libraries(googleapis_cpp_api_annotations_protos + PUBLIC googleapis-c++::api_http_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library(googleapis_cpp_api_auth_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/api/auth.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(api_auth_protos) +target_link_libraries(googleapis_cpp_api_auth_protos + PUBLIC googleapis-c++::api_annotations_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_api_resource_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/api/resource.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(api_resource_protos) +target_link_libraries(googleapis_cpp_api_resource_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_type_expr_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/type/expr.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(type_expr_protos) +target_link_libraries(googleapis_cpp_type_expr_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_rpc_error_details_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/rpc/error_details.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(rpc_error_details_protos) +target_link_libraries(googleapis_cpp_rpc_error_details_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_rpc_status_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/rpc/status.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(rpc_status_protos) +target_link_libraries(googleapis_cpp_rpc_status_protos + PUBLIC googleapis-c++::rpc_error_details_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_iam_v1_policy_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/iam/v1/policy.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(iam_v1_policy_protos) +target_link_libraries(googleapis_cpp_iam_v1_policy_protos + PUBLIC googleapis-c++::api_annotations_protos + googleapis-c++::api_resource_protos + googleapis-c++::type_expr_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_iam_v1_iam_policy_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/iam/v1/iam_policy.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(iam_v1_iam_policy_protos) +target_link_libraries(googleapis_cpp_iam_v1_iam_policy_protos + PUBLIC googleapis-c++::api_annotations_protos + googleapis-c++::iam_v1_policy_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_longrunning_operations_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/longrunning/operations.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(longrunning_operations_protos) +target_link_libraries(googleapis_cpp_longrunning_operations_protos + PUBLIC googleapis-c++::api_annotations_protos + googleapis-c++::rpc_status_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_bigtable_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/bigtable/admin/v2/bigtable_instance_admin.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/bigtable/admin/v2/bigtable_table_admin.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/bigtable/admin/v2/common.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/bigtable/admin/v2/instance.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/bigtable/admin/v2/table.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/bigtable/v2/bigtable.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/bigtable/v2/data.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(bigtable_protos) +target_link_libraries(googleapis_cpp_bigtable_protos + PUBLIC googleapis-c++::api_annotations_protos + googleapis-c++::api_auth_protos + googleapis-c++::longrunning_operations_protos + googleapis-c++::rpc_status_protos + googleapis-c++::iam_v1_iam_policy_protos + PRIVATE googleapis_cpp_common_flags) + +google_cloud_cpp_grpcpp_library( + googleapis_cpp_spanner_protos + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/admin/database/v1/spanner_database_admin.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/admin/instance/v1/spanner_instance_admin.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/v1/keys.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/v1/mutation.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/v1/query_plan.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/v1/result_set.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/v1/spanner.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/v1/transaction.proto" + "${GOOGLEAPIS_CPP_SOURCE}/google/spanner/v1/type.proto" + PROTO_PATH_DIRECTORIES + "${GOOGLEAPIS_CPP_SOURCE}" + "${PROTO_INCLUDE_DIR}") +googleapis_cpp_set_version_and_alias(spanner_protos) +target_link_libraries(googleapis_cpp_spanner_protos + PUBLIC googleapis-c++::api_annotations_protos + googleapis-c++::longrunning_operations_protos + googleapis-c++::rpc_status_protos + googleapis-c++::iam_v1_iam_policy_protos + PRIVATE googleapis_cpp_common_flags) + +# Install the libraries and headers in the locations determined by +# GNUInstallDirs +include(GNUInstallDirs) + +set(googleapis_cpp_installed_libraries_list + googleapis_cpp_bigtable_protos + googleapis_cpp_spanner_protos + googleapis_cpp_longrunning_operations_protos + googleapis_cpp_api_http_protos + googleapis_cpp_api_annotations_protos + googleapis_cpp_api_auth_protos + googleapis_cpp_api_resource_protos + googleapis_cpp_iam_v1_policy_protos + googleapis_cpp_iam_v1_iam_policy_protos + googleapis_cpp_rpc_error_details_protos + googleapis_cpp_rpc_status_protos + googleapis_cpp_type_expr_protos) + +install(TARGETS ${googleapis_cpp_installed_libraries_list} + googleapis_cpp_common_flags + EXPORT googleapis-targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +foreach (target ${googleapis_cpp_installed_libraries_list}) + google_cloud_cpp_install_proto_library_headers("${target}") + google_cloud_cpp_install_proto_library_protos("${target}") +endforeach () + +# Export the CMake targets to make it easy to create configuration files. +install(EXPORT googleapis-targets + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/googleapis") + +# Setup global variables used in the following *.in files. +set( + GOOGLE_CLOUD_CPP_CONFIG_VERSION_MAJOR ${GOOGLEAPIS_CPP_PROTOS_VERSION_MAJOR} + ) +set( + GOOGLE_CLOUD_CPP_CONFIG_VERSION_MINOR ${GOOGLEAPIS_CPP_PROTOS_VERSION_MINOR} + ) +set( + GOOGLE_CLOUD_CPP_CONFIG_VERSION_PATCH ${GOOGLEAPIS_CPP_PROTOS_VERSION_PATCH} + ) + +# Use a function to create a scope for the variables. +function (googleapis_cpp_install_pc target) + string(REPLACE "googleapis_cpp_" + "" + _short_name + ${target}) + string(REPLACE "_protos" + "" + _short_name + ${_short_name}) + set(GOOGLE_CLOUD_CPP_PC_NAME + "The Google APIS C++ ${_short_name} Proto Library") + set(GOOGLE_CLOUD_CPP_PC_DESCRIPTION "Compiled proto for C++.") + # Examine the target LINK_LIBRARIES property, use that to pull the + # dependencies between the googleapis-c++::* libraries. + set(_target_pc_requires) + get_target_property(_target_deps ${target} LINK_LIBRARIES) + foreach (dep ${_target_deps}) + if ("${dep}" MATCHES "^googleapis-c\\+\\+::") + string(REPLACE "googleapis-c++::" + "googleapis_cpp_" + dep + "${dep}") + list(APPEND _target_pc_requires " " "${dep}") + endif () + endforeach () + # These dependencies are required for all the googleapis-c++::* libraries. + list(APPEND _target_pc_requires + " grpc++" + " grpc" + " openssl" + " protobuf" + " zlib" + " libcares") + string(CONCAT GOOGLE_CLOUD_CPP_PC_REQUIRES ${_target_pc_requires}) + set(GOOGLE_CLOUD_CPP_PC_LIBS "-l${target}") + configure_file("cmake/config.pc.in" "${target}.pc" @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${target}.pc" DESTINATION + "${CMAKE_INSTALL_LIBDIR}/pkgconfig") +endfunction () + +# Create and install the pkg-config files. +foreach (target ${googleapis_cpp_installed_libraries_list}) + googleapis_cpp_install_pc("${target}") +endforeach () + +# Create and install the googleapis pkg-config file for backwards compatibility. +set(GOOGLE_CLOUD_CPP_PC_NAME "The Google APIS C++ Proto Library") +set(GOOGLE_CLOUD_CPP_PC_DESCRIPTION + "Provides C++ APIs to access Google Cloud Platforms.") +# Note the use of spaces, `string(JOIN)` is not available in cmake-3.5, so we +# need to add the separator ourselves. +string(CONCAT GOOGLE_CLOUD_CPP_PC_REQUIRES + "googleapis_cpp_bigtable_protos" + " googleapis_cpp_iam_v1_iam_policy_protos" + " googleapis_cpp_iam_v1_policy_protos" + " googleapis_cpp_longrunning_operations_protos" + " googleapis_cpp_api_auth_protos" + " googleapis_cpp_api_annotations_protos" + " googleapis_cpp_api_http_protos" + " googleapis_cpp_rpc_status_protos" + " googleapis_cpp_rpc_error_details_protos" + " grpc++" + " grpc" + " openssl" + " protobuf" + " zlib" + " libcares") +set(GOOGLE_CLOUD_CPP_PC_LIBS "") +configure_file("cmake/config.pc.in" "googleapis.pc" @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/googleapis.pc" DESTINATION + "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + +# Create and install the CMake configuration files. +configure_file("cmake/config.cmake.in" "googleapis-config.cmake" @ONLY) +configure_file("cmake/config-version.cmake.in" "googleapis-config-version.cmake" + @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/googleapis-config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/googleapis-config-version.cmake" + "${PROJECT_SOURCE_DIR}/cmake/FindgRPC.cmake" + "${PROJECT_SOURCE_DIR}/cmake/FindProtobufTargets.cmake" + "${PROJECT_SOURCE_DIR}/cmake/CompileProtos.cmake" + DESTINATION + "${CMAKE_INSTALL_LIBDIR}/cmake/googleapis") diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..33497a3798 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,55 @@ +# How to become a contributor and submit your own code + +## Contributor License Agreements + +We'd love to accept your patches! Before we can take them, we +have to jump a couple of legal hurdles. + +Please fill out either the individual or corporate Contributor License Agreement +(CLA). + + * If you are an individual writing original source code and you're sure you + own the intellectual property, then you'll need to sign an + [individual CLA](https://developers.google.com/open-source/cla/individual). + * If you work for a company that wants to allow you to contribute your work, + then you'll need to sign a + [corporate CLA](https://developers.google.com/open-source/cla/corporate). + +Follow either of the two links above to access the appropriate CLA and +instructions for how to sign and return it. Once we receive it, we'll be able to +accept your pull requests. + +## Contributing A Patch + +1. Submit an issue describing your proposed change to the repo in question. +1. The repo owner will respond to your issue promptly. +1. If your proposed change is accepted, and you haven't already done so, sign a + Contributor License Agreement (see details above). +1. Fork the desired repo, develop and test your code changes. +1. Ensure that your code adheres to the existing style in the sample to which + you are contributing. +1. Ensure that your code has an appropriate set of unit tests which all pass. +1. Submit a pull request. + +## Style + +This repository follow the [Google C++ Style Guide]( +https://google.github.io/styleguide/cppguide.html). +Please make sure your contributions adhere to the style guide. + +### Formatting + +The code in this project is formatted with `clang-format(1)`, and our CI builds +will check that the code matches the format generated by this tool before +accepting a pull request. Please configure your editor or IDE to use the Google +style for indentation and other whitespace. If you need to reformat one or more +files, you can simply run `clang-format` manually: + +```console +$ clang-format -i .... +``` + +If you need to reformat one of the files to match the Google style. Please be +advised that `clang-format` has been known to generate slightly different +formatting in different versions. We use version 7; use the same version if you +run into problems. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..5c2a711938 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# Google Cloud Platform C++ Proto Libraries + +Compile the protocol buffer definitions into C++ libraries. + +## Requirements + +#### Compiler + +The Google Cloud C++ libraries are tested with the following compilers: + +| Compiler | Minimum Version | +| ----------- | --------------- | +| GCC | 4.8 | +| Clang | 3.8 | +| MSVC++ | 14.1 | +| Apple Clang | 8.1 | + +#### Build Tools + +The Google Cloud C++ Client Libraries can be built with +[CMake](https://cmake.org) or [Bazel](https://bazel.io). The minimal versions +of these tools we test with are: + +| Tool | Minimum Version | +| ---------- | --------------- | +| CMake | 3.5 | +| Bazel | 0.24.0 | + +#### Libraries + +The libraries also depend on gRPC, libcurl, and the dependencies of those +libraries. The Google Cloud C++ Client libraries are tested with the following +versions of these dependencies: + +| Library | Minimum version | +| ------- | --------------- | +| gRPC | v1.16.x | +| libcurl | 7.47.0 | + + +## Versioning + +Please note that the Google Cloud C++ client libraries do **not** follow +[Semantic Versioning](http://semver.org/). + +**GA**: Libraries defined at a GA quality level are expected to be stable and +any backwards-incompatible changes will be noted in the documentation. Major +changes to the API will signaled by changing major version number +(e.g. 1.x.y -> 2.0.0). + +**Beta**: Libraries defined at a Beta quality level are expected to be mostly +stable and we're working towards their release candidate. We will address issues +and requests with a higher priority. + +**Alpha**: Libraries defined at an Alpha quality level are still a +work-in-progress and are more likely to get backwards-incompatible updates. +Additionally, it's possible for Alpha libraries to get deprecated and deleted +before ever being promoted to Beta or GA. + +## Contributing changes + +See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details on how to contribute to +this project, including how to build and test your changes as well as how to +properly format your code. + +## Licensing + +Apache 2.0; see [`LICENSE`](LICENSE) for details. diff --git a/cmake/CompileProtos.cmake b/cmake/CompileProtos.cmake new file mode 100644 index 0000000000..a01a90b825 --- /dev/null +++ b/cmake/CompileProtos.cmake @@ -0,0 +1,286 @@ +# ~~~ +# 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 +# +# 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. +# ~~~ + +# Introduce a new TARGET property to associate proto files with a target. +# +# We use a function to define the property so it can be called multiple times +# without introducing the property over and over. +function (google_cloud_cpp_add_protos_property) + set_property(TARGET + PROPERTY PROTO_SOURCES + BRIEF_DOCS + "The list of .proto files for a target." + FULL_DOCS + "List of .proto files specified for a target.") +endfunction () + +# Generate C++ for .proto files preserving the directory hierarchy +# +# Receives a list of `.proto` file names and (a) creates the runs to convert +# these files to `.pb.h` and `.pb.cc` output files, (b) returns the list of +# `.pb.cc` files and `.pb.h` files in @p HDRS, and (c) creates the list of files +# preserving the directory hierarchy, such that if a `.proto` file says: +# +# import "foo/bar/baz.proto" +# +# the resulting C++ code says: +# +# #include +# +# Use the `PROTO_PATH` option to provide one or more directories to search for +# proto files in the import. +# +# @par Example +# +# google_cloud_cpp_generate_proto( MY_PB_FILES "foo/bar/baz.proto" +# "foo/bar/qux.proto" PROTO_PATH_DIRECTORIES "another/dir/with/protos") +# +# Note that `protoc` the protocol buffer compiler requires your protos to be +# somewhere in the search path defined by the `--proto_path` (aka -I) options. +# For example, if you want to generate the `.pb.{h,cc}` files for +# `foo/bar/baz.proto` then the directory containing `foo` must be in the search +# path. +function (google_cloud_cpp_generate_proto SRCS) + cmake_parse_arguments(_opt "" "" "PROTO_PATH_DIRECTORIES" ${ARGN}) + if (NOT _opt_UNPARSED_ARGUMENTS) + message(SEND_ERROR "Error: google_cloud_cpp_generate_proto() called" + " without any proto files") + return() + endif () + + # Build the list of `--proto_path` options. Use the absolute path for each + # option given, and do not include any path more than once. + set(protobuf_include_path) + foreach (dir ${_opt_PROTO_PATH_DIRECTORIES}) + get_filename_component(absolute_path ${dir} ABSOLUTE) + list(FIND protobuf_include_path "${absolute_path}" + already_in_search_path) + if (${already_in_search_path} EQUAL -1) + list(APPEND protobuf_include_path "--proto_path" "${absolute_path}") + endif () + endforeach () + + set(${SRCS}) + foreach (filename ${_opt_UNPARSED_ARGUMENTS}) + get_filename_component(file_directory "${filename}" DIRECTORY) + # This gets the filename without the extension, analogous to $(basename + # "${filename}" .proto) + get_filename_component(file_stem "${filename}" NAME_WE) + + # Strip all the prefixes in ${_opt_PROTO_PATH_DIRECTORIES} from the + # source proto directory + set(D "${file_directory}") + if (DEFINED _opt_PROTO_PATH_DIRECTORIES) + foreach (P ${_opt_PROTO_PATH_DIRECTORIES}) + string(REGEX + REPLACE "^${P}" + "" + T + "${D}") + set(D ${T}) + endforeach () + endif () + set(pb_cc "${CMAKE_CURRENT_BINARY_DIR}/${D}/${file_stem}.pb.cc") + set(pb_h "${CMAKE_CURRENT_BINARY_DIR}/${D}/${file_stem}.pb.h") + list(APPEND ${SRCS} "${pb_cc}" "${pb_h}") + add_custom_command( + OUTPUT "${pb_cc}" "${pb_h}" + COMMAND $ + ARGS + --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" + ${protobuf_include_path} "${filename}" + DEPENDS "${filename}" protobuf::protoc + COMMENT "Running C++ protocol buffer compiler on ${filename}" + VERBATIM) + endforeach () + + set_source_files_properties(${${SRCS}} PROPERTIES GENERATED TRUE) + set(${SRCS} ${${SRCS}} PARENT_SCOPE) +endfunction () + +# Generate gRPC C++ files from .proto files preserving the directory hierarchy. +# +# Receives a list of `.proto` file names and (a) creates the runs to convert +# these files to `.grpc.pb.h` and `.grpc.pb.cc` output files, (b) returns the +# list of `.grpc.pb.cc` and `.pb.h` files in @p SRCS, and (c) creates the list +# of files preserving the directory hierarchy, such that if a `.proto` file says +# +# import "foo/bar/baz.proto" +# +# the resulting C++ code says: +# +# #include +# +# Use the `PROTO_PATH` option to provide one or more directories to search for +# proto files in the import. +# +# @par Example +# +# google_cloud_cpp_generate_grpc( MY_GRPC_PB_FILES "foo/bar/baz.proto" +# "foo/bar/qux.proto" PROTO_PATH_DIRECTORIES "another/dir/with/protos") +# +# Note that `protoc` the protocol buffer compiler requires your protos to be +# somewhere in the search path defined by the `--proto_path` (aka -I) options. +# For example, if you want to generate the `.pb.{h,cc}` files for +# `foo/bar/baz.proto` then the directory containing `foo` must be in the search +# path. +function (google_cloud_cpp_generate_grpcpp SRCS) + cmake_parse_arguments(_opt "" "" "PROTO_PATH_DIRECTORIES" ${ARGN}) + if (NOT _opt_UNPARSED_ARGUMENTS) + message( + SEND_ERROR "Error: google_cloud_cpp_generate_grpc() called without" + " any proto files") + return() + endif () + + # Build the list of `--proto_path` options. Use the absolute path for each + # option given, and do not include any path more than once. + set(protobuf_include_path) + foreach (dir ${_opt_PROTO_PATH_DIRECTORIES}) + get_filename_component(absolute_path ${dir} ABSOLUTE) + list(FIND protobuf_include_path "${absolute_path}" + already_in_search_path) + if (${already_in_search_path} EQUAL -1) + list(APPEND protobuf_include_path "--proto_path" "${absolute_path}") + endif () + endforeach () + + set(${SRCS}) + foreach (filename ${_opt_UNPARSED_ARGUMENTS}) + get_filename_component(file_directory "${filename}" DIRECTORY) + # This gets the filename without the extension, analogous to $(basename + # "${filename}" .proto) + get_filename_component(file_stem "${filename}" NAME_WE) + + # Strip all the prefixes in ${_opt_PROTO_PATH_DIRECTORIES} from the + # source proto directory + set(D "${file_directory}") + if (DEFINED _opt_PROTO_PATH_DIRECTORIES) + foreach (P ${_opt_PROTO_PATH_DIRECTORIES}) + string(REGEX + REPLACE "^${P}" + "" + T + "${D}") + set(D ${T}) + endforeach () + endif () + set(grpc_pb_cc + "${CMAKE_CURRENT_BINARY_DIR}/${D}/${file_stem}.grpc.pb.cc") + set(grpc_pb_h "${CMAKE_CURRENT_BINARY_DIR}/${D}/${file_stem}.grpc.pb.h") + list(APPEND ${SRCS} "${grpc_pb_cc}" "${grpc_pb_h}") + add_custom_command( + OUTPUT "${grpc_pb_cc}" "${grpc_pb_h}" + COMMAND + $ + ARGS + --plugin=protoc-gen-grpc=$ + "--grpc_out=${CMAKE_CURRENT_BINARY_DIR}" + "--cpp_out=${CMAKE_CURRENT_BINARY_DIR}" + ${protobuf_include_path} "${filename}" + DEPENDS "${filename}" protobuf::protoc gRPC::grpc_cpp_plugin + COMMENT "Running gRPC C++ protocol buffer compiler on ${filename}" + VERBATIM) + endforeach () + + set_source_files_properties(${${SRCS}} PROPERTIES GENERATED TRUE) + set(${SRCS} ${${SRCS}} PARENT_SCOPE) +endfunction () + +include(GNUInstallDirs) + +# Install headers for a C++ proto library. +function (google_cloud_cpp_install_proto_library_headers target) + get_target_property(target_sources ${target} SOURCES) + foreach (header ${target_sources}) + # Skip anything that is not a header file. + if (NOT "${header}" MATCHES "\\.h$") + continue() + endif () + string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" + "" + relative + "${header}") + get_filename_component(dir "${relative}" DIRECTORY) + install(FILES "${header}" DESTINATION + "${CMAKE_INSTALL_INCLUDEDIR}/${dir}") + endforeach () +endfunction () + +# Install protos for a C++ proto library. +function (google_cloud_cpp_install_proto_library_protos target) + get_target_property(target_protos ${target} PROTO_SOURCES) + foreach (header ${target_protos}) + # Skip anything that is not a header file. + if (NOT "${header}" MATCHES "\\.proto$") + continue() + endif () + string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" + "" + relative + "${header}") + get_filename_component(dir "${relative}" DIRECTORY) + # This is modeled after the Protobuf library, it installs the basic + # protos (think google/protobuf/any.proto) in the include directory for + # C/C++ code. :shrug: + install(FILES "${header}" DESTINATION + "${CMAKE_INSTALL_INCLUDEDIR}/${dir}") + endforeach () +endfunction () + +function (google_cloud_cpp_proto_library libname) + cmake_parse_arguments(_opt "" "" "PROTO_PATH_DIRECTORIES" ${ARGN}) + if (NOT _opt_UNPARSED_ARGUMENTS) + message(SEND_ERROR "Error: google_cloud_cpp_proto_library() called" + " without any proto files") + return() + endif () + + google_cloud_cpp_generate_proto(proto_sources + ${_opt_UNPARSED_ARGUMENTS} + PROTO_PATH_DIRECTORIES + ${_opt_PROTO_PATH_DIRECTORIES}) + + add_library(${libname} ${proto_sources}) + set_property(TARGET ${libname} + PROPERTY PROTO_SOURCES ${_opt_UNPARSED_ARGUMENTS}) + target_link_libraries(${libname} + PUBLIC gRPC::grpc++ gRPC::grpc protobuf::libprotobuf) + target_include_directories( + ${libname} + PUBLIC $ + $ + $) +endfunction () + +function (google_cloud_cpp_grpcpp_library libname) + cmake_parse_arguments(_opt "" "" "PROTO_PATH_DIRECTORIES" ${ARGN}) + if (NOT _opt_UNPARSED_ARGUMENTS) + message(SEND_ERROR "Error: google_cloud_cpp_proto_library() called" + " without any proto files") + return() + endif () + + google_cloud_cpp_generate_grpcpp(grpcpp_sources + ${_opt_UNPARSED_ARGUMENTS} + PROTO_PATH_DIRECTORIES + ${_opt_PROTO_PATH_DIRECTORIES}) + google_cloud_cpp_proto_library(${libname} + ${_opt_UNPARSED_ARGUMENTS} + PROTO_PATH_DIRECTORIES + ${_opt_PROTO_PATH_DIRECTORIES}) + target_sources(${libname} PRIVATE ${grpcpp_sources}) +endfunction () diff --git a/cmake/FindProtobufTargets.cmake b/cmake/FindProtobufTargets.cmake new file mode 100644 index 0000000000..db260280d3 --- /dev/null +++ b/cmake/FindProtobufTargets.cmake @@ -0,0 +1,207 @@ +# ~~~ +# 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 +# +# 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. +# ~~~ + +#[=======================================================================[.rst: +FindProtobufTargets +------------------- + +A module to use `Protobuf` with less complications. + +Using ``find_package(Protobuf)`` should be simple, but it is not. + +CMake provides a ``FindProtobuf`` module. Unfortunately it does not generate +`protobuf::*` targets until CMake-3.9, and `protobuf::protoc` does not +appear until CMake-3.10. + +The CMake-config files generated by `protobuf` always create these targets, +but on some Linux distributions (e.g. Fedora>=29, and openSUSE-Tumbleweed) there +are system packages for protobuf, but these packages are installed without the +CMake-config files. One must either use the ``FindProtobuf`` module, find the +libraries via `pkg-config`, or find the libraries manually. + +When the CMake-config files are installed they produce the same targets as +recent versions of ``FindProtobuf``. However, they do not produce the +`Protobuf_LIBRARY`, `Protobuf_INCLUDE_DIR`, etc. that are generated by the +module. Furthermore, the `protobuf::protoc` library is not usable when loaded +from the CMake-config files: its ``IMPORTED_LOCATION`` variable is not defined. + +This module is designed to provide a single, uniform, ``find_package()`` +module that always produces the same outputs: + +- It always generates the ``protobuf::*`` targets. +- It always defines ``ProtobufTargets_FOUND`` and ``ProtobufTargets_VERSION``. +- It *prefers* using the CMake config files if they are available. +- It fallsback on the ``FindProtobuf`` module if the config files are not found. +- It populates any missing targets and their properties. + +The following :prop_tgt:`IMPORTED` targets are defined: + +``protobuf::libprotobuf`` + The protobuf library. +``protobuf::libprotobuf-lite`` + The protobuf lite library. +``protobuf::libprotoc`` + The protoc library. +``protobuf::protoc`` + The protoc compiler. + +Example: + +.. code-block:: cmake + + find_package(ProtobufTargets REQUIRED) + add_executable(bar bar.cc) + target_link_libraries(bar PRIVATE protobuf::libprotobuf) + +#]=======================================================================] + +if (protobuf_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "protobuf_USE_STATIC_LIBS = ${protobuf_USE_STATIC_LIBS}" + " ProtobufTargets = ${ProtobufTargets_FOUND}") +endif () + +# Always load thread support, even on Windows. +find_package(Threads REQUIRED) + +# First try to use the ``protobufConfig.cmake`` or ``protobuf-config.cmake`` +# file if it was installed. This is common on systems (or package managers) +# where protobuf was compiled and installed with `CMake`. Note that on Linux +# this *must* be all lowercase ``protobuf``, while on Windows it does not +# matter. +find_package(protobuf CONFIG) + +if (protobuf_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "protobuf_FOUND = ${protobuf_FOUND}" + " protobuf_VERSION = ${protobuf_VERSION}") +endif () + +if (protobuf_FOUND) + set(ProtobufTargets_FOUND 1) + set(ProtobufTargets_VERSION ${protobuf_VERSION}) + if (protobuf_DEBUG) + message( + STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}" + " ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}") + endif () +else() + find_package(Protobuf QUIET) + if (Protobuf_FOUND) + set(ProtobufTargets_FOUND 1) + set(ProtobufTargets_VERSION ${Protobuf_VERSION}) + + if (NOT TARGET protobuf::libprotobuf) + add_library(protobuf::libprotobuf INTERFACE IMPORTED) + set_property(TARGET protobuf::libprotobuf + PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${Protobuf_INCLUDE_DIR}) + set_property(TARGET protobuf::libprotobuf + APPEND + PROPERTY INTERFACE_LINK_LIBRARIES ${Protobuf_LIBRARY} + Threads::Threads) + endif () + + if (NOT TARGET protobuf::libprotobuf-lite) + add_library(protobuf::libprotobuf-lite INTERFACE IMPORTED) + set_property(TARGET protobuf::libprotobuf-lite + PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${Protobuf_INCLUDE_DIR}) + set_property(TARGET protobuf::libprotobuf-lite + APPEND + PROPERTY INTERFACE_LINK_LIBRARIES + ${Protobuf_LITE_LIBRARY} Threads::Threads) + endif () + + if (NOT TARGET protobuf::libprotoc) + add_library(protobuf::libprotoc INTERFACE IMPORTED) + set_property(TARGET protobuf::libprotoc + PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${Protobuf_INCLUDE_DIR}) + set_property(TARGET protobuf::libprotoc + APPEND + PROPERTY INTERFACE_LINK_LIBRARIES + ${Protobuf_PROTOC_LIBRARY} Threads::Threads) + endif () + endif () +endif () + +if (protobuf_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}" + " ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}") +endif () + +# We also should try to find the protobuf C++ plugin for the protocol buffers +# compiler. +if (ProtobufTargets_FOUND AND NOT TARGET protobuf::protoc) + add_executable(protobuf::protoc IMPORTED) + + # Discover the protoc compiler location. + find_program(_protobuf_PROTOC_EXECUTABLE + NAMES protoc + DOC "The Google Protocol Buffers Compiler") + if (protobuf_DEBUG) + message( + STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}" + " ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}" + " EXE = ${_protobuf_PROTOC_EXECUTABLE}") + endif () + set_property(TARGET protobuf::protoc + PROPERTY IMPORTED_LOCATION ${_protobuf_PROTOC_EXECUTABLE}) + set_property( + TARGET protobuf::protoc + PROPERTY IMPORTED_LOCATION_DEBUG ${_protobuf_PROTOC_EXECUTABLE}) + set_property(TARGET protobuf::protoc + PROPERTY IMPORTED_LOCATION_RELEASE + ${_protobuf_PROTOC_EXECUTABLE}) + unset(_protobuf_PROTOC_EXECUTABLE) + + if (protobuf_DEBUG) + get_target_property(_protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION) + message( + STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "LOCATION=${_protobuf_PROTOC_EXECUTABLE}") + endif () +endif () + +if (protobuf_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "ProtobufTargets_FOUND = ${ProtobufTargets_FOUND}" + " ProtobufTargets_VERSION = ${ProtobufTargets_VERSION}") + if (ProtobufTargets_FOUND) + foreach (_target + protobuf::libprotobuf + protobuf::libprotobuf-lite + protobuf::libprotoc) + if (NOT TARGET ${_target}) + message( + STATUS + "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "target=${_target} is NOT a target") + endif () + endforeach () + unset(_target) + endif () +endif () + +find_package_handle_standard_args(ProtobufTargets + REQUIRED_VARS + ProtobufTargets_FOUND + ProtobufTargets_VERSION) diff --git a/cmake/FindgRPC.cmake b/cmake/FindgRPC.cmake new file mode 100644 index 0000000000..5895cf067c --- /dev/null +++ b/cmake/FindgRPC.cmake @@ -0,0 +1,343 @@ +# ~~~ +# 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 +# +# 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. +# ~~~ + +#[=======================================================================[.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 :prop_tgt:`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. +include(${CMAKE_CURRENT_LIST_DIR}/FindProtobufTargets.cmake) + +# 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++11, but only CMake-3.8 introduced a target + # compiler feature to meet that requirement. + set_property(TARGET gRPC::grpc++ + APPEND + PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_11) + 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++11") + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set_property(TARGET gRPC::grpc++ + APPEND + PROPERTY INTERFACE_COMPILE_OPTIONS "-std=c++11") + else() + message( + WARNING + "gRPC::grpc++ requires C++11, 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++11 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 +#include +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) diff --git a/cmake/SelectMSVCRuntime.cmake b/cmake/SelectMSVCRuntime.cmake new file mode 100644 index 0000000000..eb7f8f9e95 --- /dev/null +++ b/cmake/SelectMSVCRuntime.cmake @@ -0,0 +1,46 @@ +# ~~~ +# 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 +# +# 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. +# ~~~ + +# When compiling against *-static vcpkg packages we need to use the static C++ +# runtime with MSVC. The default is to use the dynamic runtime, which does not +# work in this case. This seems to be the recommended way to change the +# runtime: +# +# ~~~ +# https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-can-i-build-my-msvc-application-with-a-static-runtime +# ~~~ +# +# Note that currently we use VCPKG_TARGET_TRIPLET to determine if the static +# runtime is needed. In the future we may need to use a more complex expression +# to determine this, but this is a good start. +# +if (MSVC AND VCPKG_TARGET_TRIPLET MATCHES "-static$") + foreach (flag_var + CMAKE_CXX_FLAGS + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if (${flag_var} MATCHES "/MD") + string(REGEX + REPLACE "/MD" + "/MT" + ${flag_var} + "${${flag_var}}") + endif () + endforeach (flag_var) + unset(flag_var) +endif () diff --git a/cmake/config-version.cmake.in b/cmake/config-version.cmake.in new file mode 100644 index 0000000000..29891a6bde --- /dev/null +++ b/cmake/config-version.cmake.in @@ -0,0 +1,35 @@ +# 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 +# +# 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. + +set(PACKAGE_VERSION @DOXYGEN_PROJECT_NUMBER@) + +# This package has not reached 1.0, there are no compatibility guarantees +# before then. +if (@GOOGLE_CLOUD_CPP_CONFIG_VERSION_MAJOR@ EQUAL 0) + if ("${PACKAGE_FIND_VERSION}" STREQUAL "") + set(PACKAGE_VERSION_COMPATIBLE TRUE) + elseif ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE TRUE) + set(PACKAGE_VERSION_EXACT TRUE) + else () + set(PACKAGE_VERSION_UNSUITABLE TRUE) + endif () +elseif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/cmake/config.cmake.in b/cmake/config.cmake.in new file mode 100644 index 0000000000..50ddd6bbd1 --- /dev/null +++ b/cmake/config.cmake.in @@ -0,0 +1,36 @@ +# 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 +# +# 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. + +include("${CMAKE_CURRENT_LIST_DIR}/FindProtobufTargets.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/FindgRPC.cmake") + +include("${CMAKE_CURRENT_LIST_DIR}/googleapis-targets.cmake") + +foreach (_target + api_http + api_annotations + api_auth + rpc_status + rpc_error_details + longrunning_operations + iam_v1_policy + iam_v1_iam_policy + bigtable + spanner) + set(scoped_name "googleapis-c++::${_target}_protos") + set(imported_name "googleapis_cpp_${_target}_protos") + add_library(${scoped_name} IMPORTED INTERFACE) + set_target_properties(${scoped_name} PROPERTIES + INTERFACE_LINK_LIBRARIES ${imported_name}) +endforeach () diff --git a/cmake/config.pc.in b/cmake/config.pc.in new file mode 100644 index 0000000000..af068beb74 --- /dev/null +++ b/cmake/config.pc.in @@ -0,0 +1,26 @@ +# 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 +# +# 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. + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix}/@CMAKE_INSTALL_BINDIR@ +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: @GOOGLE_CLOUD_CPP_PC_NAME@ +Description: @GOOGLE_CLOUD_CPP_PC_DESCRIPTION@ +Requires: @GOOGLE_CLOUD_CPP_PC_REQUIRES@ +Version: @DOXYGEN_PROJECT_NUMBER@ + +Libs: -L${libdir} @GOOGLE_CLOUD_CPP_PC_LIBS@ +Cflags: -I${includedir} -- cgit 1.4.1