From cda87fa3afdacf20a097cf6ed90c5c2ef64e0437 Mon Sep 17 00:00:00 2001 From: Gil Date: Mon, 16 Jul 2018 08:50:53 -0700 Subject: Convert grpc and protobuf CMake builds to add_subdirectory (#1537) * Build zlib with grpc's add_subdirectory * Build grpc and its children with add_subdirectory. * Build c-ares with grpc's add_subdirectory * Convert protobuf to a download-only ExternalProject * Temporarily break protobuf within grpc This works because libgrpc has no actual dependency on protobuf * Update boringssl to master@{2018-07-10} --- Firestore/CMakeLists.txt | 45 ++++++- Firestore/Protos/CMakeLists.txt | 5 - .../src/firebase/firestore/remote/CMakeLists.txt | 2 +- cmake/FindGRPC.cmake | 130 --------------------- cmake/external/boringssl.cmake | 10 +- cmake/external/c-ares.cmake | 21 ++-- cmake/external/grpc.cmake | 107 ++--------------- cmake/external/protobuf.cmake | 89 ++------------ cmake/external/zlib.cmake | 13 ++- 9 files changed, 86 insertions(+), 336 deletions(-) delete mode 100644 cmake/FindGRPC.cmake diff --git a/Firestore/CMakeLists.txt b/Firestore/CMakeLists.txt index cbcd49d..039cb06 100644 --- a/Firestore/CMakeLists.txt +++ b/Firestore/CMakeLists.txt @@ -42,9 +42,8 @@ if(APPLE) find_package(FirebaseCore REQUIRED) find_package(GoogleUtilities REQUIRED) endif() -find_package(GRPC REQUIRED) find_package(LevelDB REQUIRED) -find_package(Protobuf REQUIRED) +find_package(ZLIB) # Googletest @@ -64,6 +63,48 @@ add_subdirectory( ) +# gRPC +if(ZLIB_FOUND) + set(gRPC_ZLIB_PROVIDER package CACHE STRING "Use external ZLIB") +endif() + +set(gRPC_BUILD_TESTS OFF CACHE BOOL "Disable gRPC tests") +add_subdirectory( + ${FIREBASE_BINARY_DIR}/src/grpc + ${FIREBASE_BINARY_DIR}/src/grpc-build + EXCLUDE_FROM_ALL +) + +# Fix up targets included by gRPC's build +add_alias(OpenSSL::Crypto crypto) +target_include_directories( + crypto + INTERFACE + $ +) + +add_alias(OpenSSL::SSL ssl) +target_include_directories( + ssl + INTERFACE + $ +) + +add_alias(protobuf::libprotobuf libprotobuf) +target_compile_options( + libprotobuf + PUBLIC -Wno-unused-parameter +) + +if(NOT ZLIB_FOUND) + target_include_directories( + zlibstatic + INTERFACE + $ + ) +endif() + + # nanopb set(nanopb_BUILD_GENERATOR ON CACHE BOOL "Enable the nanopb generator") set(nanopb_PROTOC_PATH ${NANOPB_PROTOC_BIN} CACHE STRING "Protoc location") diff --git a/Firestore/Protos/CMakeLists.txt b/Firestore/Protos/CMakeLists.txt index 214c15f..c2132ae 100644 --- a/Firestore/Protos/CMakeLists.txt +++ b/Firestore/Protos/CMakeLists.txt @@ -97,8 +97,3 @@ target_include_directories( firebase_firestore_protos_libprotobuf PUBLIC ${FIREBASE_SOURCE_DIR}/Firestore/Protos/cpp ) - -set_target_properties( - firebase_firestore_protos_libprotobuf - PROPERTIES COMPILE_FLAGS "-Wno-unused-parameter" -) diff --git a/Firestore/core/src/firebase/firestore/remote/CMakeLists.txt b/Firestore/core/src/firebase/firestore/remote/CMakeLists.txt index af62ab1..5de4648 100644 --- a/Firestore/core/src/firebase/firestore/remote/CMakeLists.txt +++ b/Firestore/core/src/firebase/firestore/remote/CMakeLists.txt @@ -29,5 +29,5 @@ cc_library( firebase_firestore_nanopb firebase_firestore_protos_nanopb firebase_firestore_util - grpc::grpc + grpc ) diff --git a/cmake/FindGRPC.cmake b/cmake/FindGRPC.cmake deleted file mode 100644 index 1e5fcf2..0000000 --- a/cmake/FindGRPC.cmake +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright 2018 Google -# -# 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(FindPackageHandleStandardArgs) -include(FindZLIB) - -## ZLIB - -# the grpc ExternalProject already figures out if zlib should be built or -# referenced from its installed location. If it elected to allow grpc to build -# zlib then it will be available at this location. -find_library( - ZLIB_LIBRARY - NAMES z - HINTS ${FIREBASE_BINARY_DIR}/src/grpc-build/third_party/zlib -) - -# If found above, the standard package will honor the ZLIB_LIBRARY variable. -find_package(ZLIB REQUIRED) - - -## BoringSSL/OpenSSL - -find_path( - OPENSSL_INCLUDE_DIR openssl/ssl.h - HINTS ${FIREBASE_BINARY_DIR}/src/grpc/third_party/boringssl/include -) - -find_library( - OPENSSL_SSL_LIBRARY - NAMES ssl - HINTS ${FIREBASE_BINARY_DIR}/src/grpc-build/third_party/boringssl/ssl -) - -find_library( - OPENSSL_CRYPTO_LIBRARY - NAMES crypto - HINTS ${FIREBASE_BINARY_DIR}/src/grpc-build/third_party/boringssl/crypto -) - -find_package(OpenSSL REQUIRED) - - -## C-Ares - -if(NOT c-ares_DIR) - set(c-ares_DIR ${FIREBASE_INSTALL_DIR}/lib/cmake/c-ares) -endif() -find_package(c-ares CONFIG REQUIRED) - - -## GRPC - -find_path( - GRPC_INCLUDE_DIR grpc/grpc.h - HINTS - $ENV{GRPC_ROOT}/include - ${GRPC_ROOT}/include - ${FIREBASE_BINARY_DIR}/src/grpc/include -) - -find_library( - GPR_LIBRARY - NAMES gpr - HINTS - $ENV{GRPC_ROOT}/lib - ${GRPC_ROOT}/lib - ${FIREBASE_BINARY_DIR}/src/grpc-build -) - -find_library( - GRPC_LIBRARY - NAMES grpc - HINTS - $ENV{GRPC_ROOT}/lib - ${GRPC_ROOT}/lib - ${FIREBASE_BINARY_DIR}/src/grpc-build -) - -find_package_handle_standard_args( - gRPC - DEFAULT_MSG - GRPC_INCLUDE_DIR - GRPC_LIBRARY - GPR_LIBRARY -) - -if(GRPC_FOUND) - set(GRPC_INCLUDE_DIRS ${GRPC_INCLUDE_DIR}) - set(GRPC_LIBRARIES ${GRPC_LIBRARY}) - - if (NOT TARGET grpc::gpr) - add_library(grpc::gpr UNKNOWN IMPORTED) - set_target_properties( - grpc::gpr PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} - IMPORTED_LOCATION ${GPR_LIBRARY} - ) - endif() - - if (NOT TARGET grpc::grpc) - set( - GRPC_LINK_LIBRARIES - c-ares::cares - grpc::gpr - OpenSSL::SSL - OpenSSL::Crypto - ZLIB::ZLIB - ) - - add_library(grpc::grpc UNKNOWN IMPORTED) - set_target_properties( - grpc::grpc PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} - INTERFACE_LINK_LIBRARIES "${GRPC_LINK_LIBRARIES}" - IMPORTED_LOCATION ${GRPC_LIBRARY} - ) - endif() -endif(GRPC_FOUND) diff --git a/cmake/external/boringssl.cmake b/cmake/external/boringssl.cmake index 4463ba8..71c6e8c 100644 --- a/cmake/external/boringssl.cmake +++ b/cmake/external/boringssl.cmake @@ -22,9 +22,11 @@ endif() # the SOURCE_DIR when unpacking so this must come after grpc despite the fact # that grpc logically depends upon this. -# This matches grpc at v1.8.3: -# https://github.com/grpc/grpc/tree/v1.8.3/third_party -set(commit be2ee342d3781ddb954f91f8a7e660c6f59e87e5) +# grpc at v1.8.3 includes boringssl at be2ee342d3781ddb954f91f8a7e660c6f59e87e5 +# (2017-02-03). Unfortunately, that boringssl includes a conflicting gtest +# target that makes it unsuitable for use via add_subdirectory. + +set(commit e0afc85719db9a0842bcfddcf4b15e856b253ee2) # master@{2018-07-10} ExternalProject_Add( boringssl @@ -34,7 +36,7 @@ ExternalProject_Add( DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} DOWNLOAD_NAME boringssl-${commit}.tar.gz URL https://github.com/google/boringssl/archive/${commit}.tar.gz - URL_HASH SHA256=8b9f399b8948ab36d51b5b979b208fdf4197e244a516e08d3ed3a9fbb387d463 + URL_HASH SHA256=2aa66e912651d2256ab266b712a2647c22e7e9347a09544e684732a599a194a8 PREFIX ${PROJECT_BINARY_DIR} SOURCE_DIR ${PROJECT_BINARY_DIR}/src/grpc/third_party/boringssl diff --git a/cmake/external/c-ares.cmake b/cmake/external/c-ares.cmake index dbe0eb0..01e1a79 100644 --- a/cmake/external/c-ares.cmake +++ b/cmake/external/c-ares.cmake @@ -18,21 +18,26 @@ if(TARGET c-ares) return() endif() +# The gRPC build fails if c-ares is not present in its expected location so +# this ExternalProject unpacks itself inside the gRPC source tree. CMake clears +# the SOURCE_DIR when unpacking so this must come after the grpc +# ExternalProject. + ExternalProject_Add( c-ares + DEPENDS + grpc-download + DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} URL https://github.com/c-ares/c-ares/archive/cares-1_14_0.tar.gz URL_HASH SHA256=62dd12f0557918f89ad6f5b759f0bf4727174ae9979499f5452c02be38d9d3e8 PREFIX ${PROJECT_BINARY_DIR} + SOURCE_DIR ${PROJECT_BINARY_DIR}/src/grpc/third_party/cares/cares - CMAKE_ARGS - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX:STRING=${FIREBASE_INSTALL_DIR} - -DCARES_STATIC:BOOL=ON - -DCARES_SHARED:BOOL=OFF - -DCARES_STATIC_PIC:BOOL=ON - - TEST_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" ) diff --git a/cmake/external/grpc.cmake b/cmake/external/grpc.cmake index 310d238..a2e9142 100644 --- a/cmake/external/grpc.cmake +++ b/cmake/external/grpc.cmake @@ -13,99 +13,13 @@ # limitations under the License. include(ExternalProject) -include(external/c-ares) -include(external/protobuf) -include(external/zlib) if(TARGET grpc) return() endif() -if(GRPC_ROOT) - # If the user has supplied a GRPC_ROOT then just use it. Add an empty custom - # target so that the superbuild dependencies still work. - add_custom_target(grpc) - return() -endif() - -set( - CMAKE_ARGS - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DBUILD_SHARED_LIBS:BOOL=OFF - -DgRPC_INSTALL:BOOL=OFF - -DgRPC_BUILD_TESTS:BOOL=OFF - - # TODO(rsgowman): We're currently building nanopb twice; once via grpc, and - # once via nanopb. The version from grpc is the one that actually ends up - # being used. We need to fix this such that either: - # a) we instruct grpc to use our nanopb - # b) we rely on grpc's nanopb instead of using our own. - # For now, we'll pass in the necessary nanopb cflags into grpc. (We require - # 16 bit fields. Without explicitly requesting this, nanopb uses 8 bit - # fields.) - -DCMAKE_C_FLAGS=-DPB_FIELD_16BIT - -DCMAKE_CXX_FLAGS=-DPB_FIELD_16BIT -) - - -## c-ares -if(NOT c-ares_DIR) - set(c-ares_DIR ${FIREBASE_INSTALL_DIR}/lib/cmake/c-ares) -endif() - -list( - APPEND CMAKE_ARGS - -DgRPC_CARES_PROVIDER:STRING=package - -Dc-ares_DIR:PATH=${c-ares_DIR} -) - - -## protobuf - -# Unlike other dependencies of gRPC, we control the protobuf version because we -# have checked-in protoc outputs that must match the runtime. - -# The location where protobuf-config.cmake will be installed varies by platform -if(NOT Protobuf_DIR) - if(WIN32) - set(Protobuf_DIR "${FIREBASE_INSTALL_DIR}/cmake") - else() - set(Protobuf_DIR "${FIREBASE_INSTALL_DIR}/lib/cmake/protobuf") - endif() -endif() - -list( - APPEND CMAKE_ARGS - -DgRPC_PROTOBUF_PROVIDER:STRING=package - -DgRPC_PROTOBUF_PACKAGE_TYPE:STRING=CONFIG - -DProtobuf_DIR:PATH=${Protobuf_DIR} -) - - -## zlib - -# cmake/external/zlib.cmake figures out whether or not to build zlib. Either -# way, from the gRPC build's point of view it's a package. -list( - APPEND CMAKE_ARGS - -DgRPC_ZLIB_PROVIDER:STRING=package -) -if(ZLIB_FOUND) - # Propagate possible user configuration to FindZLIB.cmake in the sub-build. - list( - APPEND CMAKE_ARGS - -DZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIR} - -DZLIB_LIBRARY=${ZLIB_LIBRARY} - ) -endif() - - ExternalProject_Add( grpc-download - DEPENDS - c-ares - protobuf - zlib DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} DOWNLOAD_NAME grpc-1.8.3.tar.gz @@ -128,23 +42,16 @@ ExternalProject_Add( # target. ExternalProject dependencies must already exist when declared so # these must come after the ExternalProject_Add block above. include(external/boringssl) +include(external/c-ares) +include(external/protobuf) +include(external/zlib) -ExternalProject_Add( +add_custom_target( grpc DEPENDS boringssl + c-ares grpc-download - - PREFIX ${PROJECT_BINARY_DIR} - SOURCE_DIR ${PROJECT_BINARY_DIR}/src/grpc - - CMAKE_ARGS - ${CMAKE_ARGS} - - BUILD_COMMAND - ${CMAKE_COMMAND} --build . --target grpc - - UPDATE_COMMAND "" - TEST_COMMAND "" - INSTALL_COMMAND "" + protobuf + zlib ) diff --git a/cmake/external/protobuf.cmake b/cmake/external/protobuf.cmake index 2cc632c..b85255e 100644 --- a/cmake/external/protobuf.cmake +++ b/cmake/external/protobuf.cmake @@ -18,86 +18,14 @@ if(TARGET protobuf) return() endif() -# Protubuf has CMake support, but includes it in a `cmake` subdirectory, which -# does not work with CMake's ExternalProject by default. CMake 3.7 added -# SOURCE_SUBDIR as a means of supporting this but that's too new to require -# yet. - -# Compose CMAKE_ARGS -set( - cmake_args - -DCMAKE_INSTALL_PREFIX:PATH= - -DBUILD_SHARED_LIBS:BOOL=OFF - -Dprotobuf_BUILD_TESTS:BOOL=OFF - -Dprotobuf_WITH_ZLIB:BOOL=OFF - -Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=ON -) - -# For single-configuration generators, pass CONFIG at configure time -if(NOT CMAKE_CONFIGURATION_TYPES) - list(APPEND cmake_args -DCMAKE_BUILD_TYPE=$) -endif() - - -if(CMAKE_VERSION VERSION_LESS "3.7") - # Manually compose the commands required to invoke CMake in the external - # project. - # - # Compose CONFIGURE_COMMAND so as to preserve the outer CMake's generator - # configuration in the sub-build. Without this the builds can invoke - # different compilers or disagree about word size or other fundamental - # parameters making the output of the sub-build useless. This is based on - # _ep_extract_configure_command in ExternalProject.cmake. - set(configure "${CMAKE_COMMAND}") - - if(CMAKE_EXTRA_GENERATOR) - list(APPEND configure "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") - else() - list(APPEND configure "-G${CMAKE_GENERATOR}") - endif() - - if(CMAKE_GENERATOR_PLATFORM) - list(APPEND configure "-A${CMAKE_GENERATOR_PLATFORM}") - endif() - - if(CMAKE_GENERATOR_TOOLSET) - list(APPEND configure "-T${CMAKE_GENERATOR_TOOLSET}") - endif() - - list( - APPEND configure - ${cmake_args} - "${PROJECT_BINARY_DIR}/src/protobuf/cmake" - ) - - # Compose BUILD_COMMAND and INSTALL_COMMAND - set(build "${CMAKE_COMMAND}" --build .) - - # For multi-configuration generators, pass CONFIG at build time. - if(CMAKE_CONFIGURATION_TYPES) - list(APPEND build --config $) - endif() - - set(install ${build} --target install) - - set( - commands - CONFIGURE_COMMAND ${configure} - BUILD_COMMAND ${build} - INSTALL_COMMAND ${install} - ) - -else() - # CMake 3.7 and above support this directly. - set( - commands - CMAKE_ARGS ${cmake_args} - SOURCE_SUBDIR cmake - ) -endif() +# This ExternalProject unpacks itself inside the gRPC source tree. CMake clears +# the SOURCE_DIR when unpacking so this must come after grpc despite the fact +# that grpc logically depends upon this. ExternalProject_Add( protobuf + DEPENDS + grpc-download DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} DOWNLOAD_NAME protobuf-v3.5.1.1.tar.gz @@ -105,9 +33,10 @@ ExternalProject_Add( URL_HASH SHA256=56b5d9e1ab2bf4f5736c4cfba9f4981fbc6976246721e7ded5602fbaee6d6869 PREFIX ${PROJECT_BINARY_DIR} - INSTALL_DIR ${FIREBASE_INSTALL_DIR} - - ${commands} + SOURCE_DIR ${PROJECT_BINARY_DIR}/src/grpc/third_party/protobuf + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" TEST_COMMAND "" ) diff --git a/cmake/external/zlib.cmake b/cmake/external/zlib.cmake index 70efa6b..7f86d96 100644 --- a/cmake/external/zlib.cmake +++ b/cmake/external/zlib.cmake @@ -27,6 +27,8 @@ endif() ExternalProject_Add( zlib + DEPENDS + grpc-download DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} DOWNLOAD_NAME zlib-v1.2.11.tar.gz @@ -34,11 +36,10 @@ ExternalProject_Add( URL_HASH SHA256=629380c90a77b964d896ed37163f5c3a34f6e6d897311f1df2a7016355c45eff PREFIX ${PROJECT_BINARY_DIR} + SOURCE_DIR ${PROJECT_BINARY_DIR}/src/grpc/third_party/zlib - CMAKE_ARGS - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX:STRING=${FIREBASE_INSTALL_DIR} - -DBUILD_SHARED_LIBS:BOOL=OFF - - TEST_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" ) -- cgit v1.2.3