From 3722deff12ec2e79c479ceae3a829752f92bb710 Mon Sep 17 00:00:00 2001 From: Gil Date: Tue, 26 Jun 2018 15:05:28 -0700 Subject: Install protobuf during CMake build (#1460) * Install protobuf * Use the built-in FindProtobuf.cmake * Add additional build configuration flags * Preserve generator configuration in the protobuf sub-build Without this, the build fails on Win64 because the default configuration builds a Win32 libprotobuf and the Win64 build rejects it. * Wire the installed protobuf into the gRPC build. * Install nanopb --- cmake/FindNanopb.cmake | 2 - cmake/FindProtobuf.cmake | 65 ------------------------------ cmake/external/grpc.cmake | 29 +++++++++++++- cmake/external/nanopb.cmake | 7 +--- cmake/external/protobuf.cmake | 93 +++++++++++++++++++++++++++++++++++++------ 5 files changed, 110 insertions(+), 86 deletions(-) delete mode 100644 cmake/FindProtobuf.cmake (limited to 'cmake') diff --git a/cmake/FindNanopb.cmake b/cmake/FindNanopb.cmake index eb7dfad..131be2a 100644 --- a/cmake/FindNanopb.cmake +++ b/cmake/FindNanopb.cmake @@ -18,13 +18,11 @@ set(BINARY_DIR ${FIREBASE_BINARY_DIR}/external/nanopb) find_path( NANOPB_INCLUDE_DIR pb.h - HINTS ${BINARY_DIR}/src/nanopb ) find_library( NANOPB_LIBRARY NAMES protobuf-nanopb protobuf-nanopbd - HINTS ${BINARY_DIR}/src/nanopb-build ) find_package_handle_standard_args( diff --git a/cmake/FindProtobuf.cmake b/cmake/FindProtobuf.cmake deleted file mode 100644 index ae438bb..0000000 --- a/cmake/FindProtobuf.cmake +++ /dev/null @@ -1,65 +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) - -set(BINARY_DIR ${FIREBASE_BINARY_DIR}/external/protobuf) - -find_path( - PROTOBUF_INCLUDE_DIR google/protobuf/stubs/common.h - HINTS ${BINARY_DIR}/src/protobuf/src -) - -find_library( - PROTOBUF_LIBRARY - NAMES protobuf protobufd - HINTS ${BINARY_DIR}/src/protobuf-build -) - -find_library( - PROTOBUFLITE_LIBRARY - NAMES protobuf-lite protobuf-lited - HINTS ${BINARY_DIR}/src/protobuf-build -) - -find_package_handle_standard_args( - protobuf - DEFAULT_MSG - PROTOBUF_INCLUDE_DIR - PROTOBUF_LIBRARY - PROTOBUFLITE_LIBRARY -) - -if(PROTOBUF_FOUND) - set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR}) - set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY} ${PROTOBUFLITE_LIBRARY}) - - if (NOT TARGET protobuf-lite) - add_library(protobuf-lite UNKNOWN IMPORTED) - set_target_properties( - protobuf-lite PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${PROTOBUF_INCLUDE_DIRS} - IMPORTED_LOCATION ${PROTOBUFLITE_LIBRARY} - ) - endif() - if (NOT TARGET protobuf) - add_library(protobuf UNKNOWN IMPORTED) - set_target_properties( - protobuf PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${PROTOBUF_INCLUDE_DIRS} - IMPORTED_LOCATION ${PROTOBUF_LIBRARY} - INTERFACE_LINK_LIBRARIES protobuf-lite - ) - endif() -endif(PROTOBUF_FOUND) diff --git a/cmake/external/grpc.cmake b/cmake/external/grpc.cmake index d192e94..ee4d246 100644 --- a/cmake/external/grpc.cmake +++ b/cmake/external/grpc.cmake @@ -31,8 +31,8 @@ else() set( CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DgRPC_BUILD_TESTS:BOOL=OFF -DBUILD_SHARED_LIBS: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 @@ -46,6 +46,29 @@ else() -DCMAKE_CXX_FLAGS=-DPB_FIELD_16BIT ) + + ## 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 (WIN32) + set(PROTOBUF_CMAKE_DIR "${FIREBASE_INSTALL_DIR}/cmake") + else() + set(PROTOBUF_CMAKE_DIR "${FIREBASE_INSTALL_DIR}/lib/cmake/protobuf") + endif() + + list( + APPEND CMAKE_ARGS + -DgRPC_PROTOBUF_PROVIDER:STRING=package + -DgRPC_PROTOBUF_PACKAGE_TYPE:STRING=CONFIG + -DProtobuf_DIR:PATH=${PROTOBUF_CMAKE_DIR} + ) + + + ## zlib + # zlib can be built by grpc but we can avoid it on platforms that provide it # by default. find_package(ZLIB) @@ -62,8 +85,8 @@ else() APPEND GIT_SUBMODULES third_party/zlib ) + endif() - endif(ZLIB_FOUND) ExternalProject_GitSource( GRPC_GIT @@ -74,6 +97,8 @@ else() ExternalProject_Add( grpc + DEPENDS + protobuf ${GRPC_GIT} diff --git a/cmake/external/nanopb.cmake b/cmake/external/nanopb.cmake index 368ecf0..39eb833 100644 --- a/cmake/external/nanopb.cmake +++ b/cmake/external/nanopb.cmake @@ -14,10 +14,7 @@ include(ExternalProject) -set( - NANOPB_PROTOC_BIN - ${FIREBASE_BINARY_DIR}/external/protobuf/src/protobuf-build/${CMAKE_CFG_INTDIR}/protoc -) +set(NANOPB_PROTOC_BIN ${FIREBASE_INSTALL_DIR}/bin/protoc) ExternalProject_Add( nanopb @@ -32,11 +29,11 @@ ExternalProject_Add( CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX:STRING=${FIREBASE_INSTALL_DIR} -DBUILD_SHARED_LIBS:BOOL=OFF -Dnanopb_BUILD_GENERATOR:BOOL=ON -Dnanopb_PROTOC_PATH:STRING=${NANOPB_PROTOC_BIN} UPDATE_COMMAND "" TEST_COMMAND "" - INSTALL_COMMAND "" ) diff --git a/cmake/external/protobuf.cmake b/cmake/external/protobuf.cmake index 21cfac3..66d1426 100644 --- a/cmake/external/protobuf.cmake +++ b/cmake/external/protobuf.cmake @@ -14,28 +14,97 @@ include(ExternalProject) +# 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}/external/protobuf/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() + ExternalProject_Add( protobuf DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} - DOWNLOAD_NAME protobuf-v3.5.11.tar.gz + DOWNLOAD_NAME protobuf-v3.5.1.1.tar.gz URL https://github.com/google/protobuf/archive/v3.5.1.1.tar.gz URL_HASH SHA256=56b5d9e1ab2bf4f5736c4cfba9f4981fbc6976246721e7ded5602fbaee6d6869 PREFIX ${PROJECT_BINARY_DIR}/external/protobuf + INSTALL_DIR ${FIREBASE_INSTALL_DIR} - # protobuf ships CMake files but not at the root of the repo, which confuses - # CMake by default. Unfortunately when you override CONFIGURE_COMMAND like - # this, CMake no longer automatically plumbs in CMAKE_ARGS and friends so - # those need to be manually passed in this command line. - CONFIGURE_COMMAND - ${CMAKE_COMMAND} - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX:PATH=${FIREBASE_INSTALL_DIR} - -Dprotobuf_BUILD_TESTS=OFF - ${PROJECT_BINARY_DIR}/external/protobuf/src/protobuf/cmake + ${commands} UPDATE_COMMAND "" TEST_COMMAND "" - INSTALL_COMMAND "" ) -- cgit v1.2.3