Browse Source

Fixes for compatibility with builds in firebase-cpp-sdk (#4984)

* Don't modify CMAKE_CXX_FLAGS

* Avoid conflict on RANDOM_FILE

* Only conditionally build tests

* Remove alias provided by the upstream build

* Set SOURCE_DIR and BINARY_DIR for each external library

* Compute repo root without git

This supports building Firestore from a source archive

* Make empty files C++

This makes it possible to compile with a single set of flags for every
cc_library.
Gil 6 years ago
parent
commit
d4e86ba091
5 changed files with 93 additions and 80 deletions
  1. 15 2
      CMakeLists.txt
  2. 52 45
      cmake/cc_rules.cmake
  3. 0 8
      cmake/compiler_setup.cmake
  4. 18 5
      cmake/external_rules.cmake
  5. 8 20
      scripts/binary_to_array.py

+ 15 - 2
CMakeLists.txt

@@ -60,6 +60,12 @@ endif()
 enable_language(C)
 enable_language(CXX)
 
+option(
+  FIREBASE_IOS_BUILD_TESTS
+  "Enable building of C++ and Objective-C tests for this project"
+  ON
+)
+
 
 list(INSERT CMAKE_MODULE_PATH 0 ${PROJECT_SOURCE_DIR}/cmake)
 include(compiler_id)
@@ -140,6 +146,12 @@ endif()
 
 
 # gRPC
+
+# libcurl and c-ares conflict in their usage of this variable. Prevent
+# libcurl's setting of this variable from affecting the c-ares build that's
+# pulled in indirectly via gRPC.
+unset(RANDOM_FILE CACHE)
+
 find_package(OpenSSL QUIET)
 if(OPENSSL_FOUND)
   set(gRPC_SSL_PROVIDER package CACHE STRING "Use external OpenSSL")
@@ -187,7 +199,6 @@ else()
   )
 endif()
 
-add_alias(protobuf::libprotobuf libprotobuf)
 if(CXX_CLANG OR CXX_GNU)
   target_compile_options(
     libprotobuf
@@ -245,7 +256,9 @@ if(APPLE)
 endif()
 
 
-enable_testing()
+if(FIREBASE_IOS_BUILD_TESTS)
+  enable_testing()
+endif()
 include(compiler_setup)
 
 add_subdirectory(FirebaseCore)

+ 52 - 45
cmake/cc_rules.cmake

@@ -45,6 +45,7 @@ function(cc_library name)
     ${FIREBASE_SOURCE_DIR}
   )
 
+  target_compile_options(${name} PRIVATE ${FIREBASE_CXX_FLAGS})
   target_link_libraries(${name} PUBLIC ${ccl_DEPENDS})
 
   if(ccl_EXCLUDE_FROM_ALL)
@@ -135,6 +136,10 @@ endfunction()
 # Defines a new test executable target with the given target name, sources, and
 # dependencies.  Implicitly adds DEPENDS on GTest::GTest and GTest::Main.
 function(cc_test name)
+  if(NOT FIREBASE_IOS_BUILD_TESTS)
+    return()
+  endif()
+
   set(multi DEPENDS SOURCES)
   cmake_parse_arguments(cct "" "" "${multi}" ${ARGN})
 
@@ -184,6 +189,8 @@ function(cc_fuzz_test name)
     DEPENDS ${ccf_DEPENDS}
   )
 
+  target_compile_options(${name} PRIVATE ${FIREBASE_CXX_FLAGS})
+
   # Copy the dictionary file and corpus directory, if they are defined.
   if(DEFINED ccf_DICTIONARY)
     add_custom_command(
@@ -314,6 +321,7 @@ function(objc_framework target)
       INTERFACE
         -F${CMAKE_CURRENT_BINARY_DIR}
       PRIVATE
+        ${FIREBASE_CXX_FLAGS}
         ${OBJC_FLAGS}
         -fno-autolink
         -Wno-unused-parameter
@@ -356,56 +364,55 @@ function(objc_framework target)
 endfunction()
 
 function(objc_test target)
-  if(APPLE)
-    set(flag EXCLUDE_FROM_ALL)
-    set(single HOST VERSION WORKING_DIRECTORY)
-    set(multi DEPENDS DEFINES HEADERS INCLUDES SOURCES)
-    cmake_parse_arguments(ot "${flag}" "${single}" "${multi}" ${ARGN})
+  if(NOT APPLE OR NOT FIREBASE_IOS_BUILD_TESTS)
+    return()
+  endif()
 
-    xctest_add_bundle(
-      ${target}
-      ${ot_HOST}
-      ${ot_SOURCES}
-    )
+  set(flag EXCLUDE_FROM_ALL)
+  set(single HOST VERSION WORKING_DIRECTORY)
+  set(multi DEPENDS DEFINES HEADERS INCLUDES SOURCES)
+  cmake_parse_arguments(ot "${flag}" "${single}" "${multi}" ${ARGN})
+
+  xctest_add_bundle(
+    ${target}
+    ${ot_HOST}
+    ${ot_SOURCES}
+  )
 
-    add_objc_flags(
-      ${target}
-      ${ot_SOURCES}
-    )
+  add_objc_flags(
+    ${target}
+    ${ot_SOURCES}
+  )
 
-    target_link_libraries(
-      ${target}
-      PRIVATE
-        ${ot_DEPENDS}
-    )
+  target_compile_options(${target} PRIVATE ${FIREBASE_CXX_FLAGS})
+  target_link_libraries(${target} PRIVATE ${ot_DEPENDS})
 
-    xctest_add_test(
-      ${target}
-      ${target}
-    )
+  xctest_add_test(
+    ${target}
+    ${target}
+  )
 
-    if(ot_WORKING_DIRECTORY)
-      set_property(
-        TEST ${target} PROPERTY
-        WORKING_DIRECTORY ${ot_WORKING_DIRECTORY}
-      )
-    endif()
+  if(ot_WORKING_DIRECTORY)
+    set_property(
+      TEST ${target} PROPERTY
+      WORKING_DIRECTORY ${ot_WORKING_DIRECTORY}
+    )
+  endif()
 
-    if(APPLE AND WITH_ASAN)
-      set_property(
-        TEST ${target} APPEND PROPERTY
-        ENVIRONMENT
-        DYLD_INSERT_LIBRARIES=${CLANG_ASAN_DYLIB}
-      )
-    endif()
+  if(WITH_ASAN)
+    set_property(
+      TEST ${target} APPEND PROPERTY
+      ENVIRONMENT
+      DYLD_INSERT_LIBRARIES=${CLANG_ASAN_DYLIB}
+    )
+  endif()
 
-    if(APPLE AND WITH_TSAN)
-      set_property(
-        TEST ${target} APPEND PROPERTY
-        ENVIRONMENT
-        DYLD_INSERT_LIBRARIES=${CLANG_TSAN_DYLIB}
-      )
-    endif()
+  if(WITH_TSAN)
+    set_property(
+      TEST ${target} APPEND PROPERTY
+      ENVIRONMENT
+      DYLD_INSERT_LIBRARIES=${CLANG_TSAN_DYLIB}
+    )
   endif()
 endfunction()
 
@@ -416,14 +423,14 @@ endfunction()
 #
 # Appends the generated source file name to the list named by sources_list.
 macro(generate_dummy_source name sources_list)
-  set(__empty_header_only_file "${CMAKE_CURRENT_BINARY_DIR}/${name}_header_only_empty.c")
+  set(__empty_header_only_file "${CMAKE_CURRENT_BINARY_DIR}/${name}_header_only_empty.cc")
 
   if(NOT EXISTS ${__empty_header_only_file})
     file(WRITE ${__empty_header_only_file}
       "// Generated file that keeps header-only CMake libraries happy.
 
       // single meaningless symbol
-      void ${name}_header_only_fakesym(void) {}
+      void ${name}_header_only_fakesym() {}
       "
     )
   endif()

+ 0 - 8
cmake/compiler_setup.cmake

@@ -116,14 +116,6 @@ if(MSVC)
   )
 endif()
 
-foreach(flag ${common_flags} ${c_flags})
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
-endforeach()
-
-foreach(flag ${common_flags} ${cxx_flags})
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
-endforeach()
-
 foreach(flag ${common_flags} ${c_flags})
   list(APPEND FIREBASE_C_FLAGS ${flag})
 endforeach()

+ 18 - 5
cmake/external_rules.cmake

@@ -36,9 +36,22 @@ function(download_external_sources)
 endfunction()
 
 function(add_external_subdirectory NAME)
-  add_subdirectory(
-    ${FIREBASE_BINARY_DIR}/external/src/${NAME}
-    ${FIREBASE_BINARY_DIR}/external/src/${NAME}-build
-    EXCLUDE_FROM_ALL
-  )
+  string(TOUPPER ${NAME} UPPER_NAME)
+  if (NOT EXISTS ${${UPPER_NAME}_SOURCE_DIR})
+    set(${UPPER_NAME}_SOURCE_DIR "${FIREBASE_BINARY_DIR}/external/src/${NAME}")
+    set(${UPPER_NAME}_SOURCE_DIR "${${UPPER_NAME}_SOURCE_DIR}" PARENT_SCOPE)
+  endif()
+
+  if (NOT EXISTS ${${UPPER_NAME}_BINARY_DIR})
+    set(${UPPER_NAME}_BINARY_DIR "${${UPPER_NAME}_SOURCE_DIR}-build")
+    set(${UPPER_NAME}_BINARY_DIR "${${UPPER_NAME}_BINARY_DIR}" PARENT_SCOPE)
+  endif()
+
+  if (EXISTS "${${UPPER_NAME}_SOURCE_DIR}/CMakeLists.txt")
+    add_subdirectory(
+      ${${UPPER_NAME}_SOURCE_DIR}
+      ${${UPPER_NAME}_BINARY_DIR}
+      EXCLUDE_FROM_ALL
+    )
+  endif()
 endfunction()

+ 8 - 20
scripts/binary_to_array.py

@@ -1,6 +1,6 @@
 #!/usr/bin/env python2
 
-# Copyright 2018 Google
+# Copyright 2018 Google LLC
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -48,8 +48,6 @@ import argparse
 import logging
 import os
 
-from lib import git
-
 arg_parser = argparse.ArgumentParser()
 
 arg_parser.add_argument("input",
@@ -223,26 +221,16 @@ def source(namespaces, array_name, array_size_name, fileid, filename,
   return data
 
 
-def _get_repo_root(filename):
-  """Returns the root of the repository containing the given file.
-
-  Args:
-    filename: A source file or directory in the repository.
+def _get_repo_root():
+  """Returns the root of the source repository.
   """
 
-  # CMake builds can be run out of source tree, so use the directory containing
-  # a source file as the starting point for the calculation.
-  if os.path.isdir(filename):
-    dir_in_repo = filename
-  else:
-    dir_in_repo = os.path.dirname(filename)
-
-  starting_dir = os.getcwd()
+  scripts_dir = os.path.abspath(os.path.dirname(__file__))
+  assert os.path.basename(scripts_dir) == 'scripts'
 
-  os.chdir(dir_in_repo)
-  root_dir = git.get_repo_root()
+  root_dir = os.path.dirname(scripts_dir)
+  assert os.path.isdir(os.path.join(root_dir, '.github'))
 
-  os.chdir(starting_dir)
   return root_dir
 
 
@@ -265,8 +253,8 @@ def main():
     output_header = input_file_base + ".h"
     logging.debug("Using default --output_header='%s'", output_header)
 
+  root_dir = _get_repo_root()
   absolute_dir = path.dirname(output_header)
-  root_dir = _get_repo_root(absolute_dir)
 
   relative_dir = path.relpath(absolute_dir, root_dir)
   relative_header_path = path.join(relative_dir, path.basename(output_header))