diff options
32 files changed, 254 insertions, 156 deletions
@@ -39,6 +39,7 @@ DerivedData # Vim *.swo *.swp +*~ # Bundler .bundle diff --git a/CMakeLists.txt b/CMakeLists.txt index 04d4c99..c2bf56d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ if(NOT CMAKE_BUILD_TYPE) endif() if(APPLE) - # When building on the apple platform certain Objective-C++ classes bridge + # When building on the Apple platform certain Objective-C++ classes bridge # back into other Firebase Cocoapods. This requires shelling out to xcodebuild # to verify the built frameworks are up-to-date. You can disable this to speed # up the build. @@ -36,14 +36,24 @@ endif(APPLE) list(INSERT CMAKE_MODULE_PATH 0 ${PROJECT_SOURCE_DIR}/cmake) -set(FIREBASE_INSTALL_DIR ${PROJECT_BINARY_DIR}) +set(FIREBASE_BINARY_DIR ${PROJECT_BINARY_DIR}) +set(FIREBASE_INSTALL_DIR ${PROJECT_BINARY_DIR}/opt) + +set( + FIREBASE_DOWNLOAD_DIR + ${PROJECT_BINARY_DIR}/downloads + CACHE PATH "Where to store downloaded files" +) enable_testing() +# These are ordered by a topological sort on DEPENDS attributes. This is +# required because CMake fails the build if you have a DEPENDS on a target that +# does not exist yet. include(external/FirebaseCore) include(external/googletest) include(external/leveldb) -include(external/grpc) include(external/protobuf) include(external/nanopb) +include(external/grpc) include(external/firestore) diff --git a/Example/Auth/Tests/FIREmailLinkSignInResponseTests.m b/Example/Auth/Tests/FIREmailLinkSignInResponseTests.m index cc2c544..e18e480 100644 --- a/Example/Auth/Tests/FIREmailLinkSignInResponseTests.m +++ b/Example/Auth/Tests/FIREmailLinkSignInResponseTests.m @@ -87,7 +87,7 @@ static const NSTimeInterval kTestTokenExpirationTimeInterval = 55 * 60; @brief The maximum difference between time two dates (in seconds), after which they will be considered different. */ -static const NSTimeInterval kMaxDifferenceBetweenDates = 0.0001; +static const NSTimeInterval kMaxDifferenceBetweenDates = 0.001; /** @var kFakeIsNewUSerFlag @brief The fake fake isNewUser flag in the response. diff --git a/Example/Firebase.xcodeproj/xcshareddata/xcschemes/AllUnitTests_iOS.xcscheme b/Example/Firebase.xcodeproj/xcshareddata/xcschemes/AllUnitTests_iOS.xcscheme index 7079a78..a2a13b0 100644 --- a/Example/Firebase.xcodeproj/xcshareddata/xcschemes/AllUnitTests_iOS.xcscheme +++ b/Example/Firebase.xcodeproj/xcshareddata/xcschemes/AllUnitTests_iOS.xcscheme @@ -110,7 +110,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" + disableMainThreadChecker = "YES" shouldUseLaunchSchemeArgsEnv = "YES"> <Testables> <TestableReference @@ -190,7 +190,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Example/Messaging/Tests/FIRMessagingRemoteNotificationsProxyTest.m b/Example/Messaging/Tests/FIRMessagingRemoteNotificationsProxyTest.m index 3453f11..6c7fcec 100644 --- a/Example/Messaging/Tests/FIRMessagingRemoteNotificationsProxyTest.m +++ b/Example/Messaging/Tests/FIRMessagingRemoteNotificationsProxyTest.m @@ -164,12 +164,14 @@ void FCM_swizzle_didReceiveNotificationResponseWithHandler( - (void)testSwizzledIncompleteAppDelegateRemoteNotificationMethod { IncompleteAppDelegate *incompleteAppDelegate = [[IncompleteAppDelegate alloc] init]; [self.mockProxy swizzleAppDelegateMethods:incompleteAppDelegate]; +#ifdef BUG_1451 SEL selector = @selector(application:didReceiveRemoteNotification:); XCTAssertTrue([incompleteAppDelegate respondsToSelector:selector]); [incompleteAppDelegate application:OCMClassMock([UIApplication class]) didReceiveRemoteNotification:@{}]; // Verify our swizzled method was called OCMVerify(FCM_swizzle_appDidReceiveRemoteNotification); +#endif } // If the remote notification with fetch handler is NOT implemented, we will force-implement @@ -181,8 +183,10 @@ void FCM_swizzle_didReceiveNotificationResponseWithHandler( @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:); XCTAssertFalse([incompleteAppDelegate respondsToSelector:remoteNotificationWithFetchHandler]); +#ifdef BUG_1451 SEL remoteNotification = @selector(application:didReceiveRemoteNotification:); XCTAssertTrue([incompleteAppDelegate respondsToSelector:remoteNotification]); +#endif } - (void)testSwizzledAppDelegateRemoteNotificationMethods { diff --git a/Firebase/Auth/CHANGELOG.md b/Firebase/Auth/CHANGELOG.md index 2669fc0..d5d0782 100644 --- a/Firebase/Auth/CHANGELOG.md +++ b/Firebase/Auth/CHANGELOG.md @@ -1,4 +1,5 @@ # v5.0.2 +- Fix an issue where JWT date timestamps weren't parsed correctly. - Fix an issue where anonymous accounts weren't correctly promoted to non-anonymous when linked with passwordless email auth accounts. diff --git a/Firebase/Auth/Source/FIRUser.m b/Firebase/Auth/Source/FIRUser.m index 3f5bf35..9bae744 100644 --- a/Firebase/Auth/Source/FIRUser.m +++ b/Firebase/Auth/Source/FIRUser.m @@ -890,12 +890,14 @@ static void callInMainThreadWithAuthDataResultAndError( return nil; } + // These are dates since 00:00:00 January 1 1970, as described by the Terminology section in + // the JWT spec. https://tools.ietf.org/html/rfc7519 NSDate *expDate = - [NSDate dateWithTimeIntervalSinceNow:[tokenPayloadDictionary[@"exp"] doubleValue]]; + [NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"exp"] doubleValue]]; NSDate *authDate = - [NSDate dateWithTimeIntervalSinceNow:[tokenPayloadDictionary[@"auth_time"] doubleValue]]; + [NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"auth_time"] doubleValue]]; NSDate *issuedDate = - [NSDate dateWithTimeIntervalSinceNow:[tokenPayloadDictionary[@"iat"] doubleValue]]; + [NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"iat"] doubleValue]]; FIRAuthTokenResult *result = [[FIRAuthTokenResult alloc] initWithToken:token expirationDate:expDate diff --git a/Firebase/Database/CHANGELOG.md b/Firebase/Database/CHANGELOG.md index 291ec08..b7eb71c 100644 --- a/Firebase/Database/CHANGELOG.md +++ b/Firebase/Database/CHANGELOG.md @@ -1,3 +1,6 @@ +# v5.0.2 +- [fixed] Fixed undefined behavior sanitizer issues. (#1443, #1444) + # v4.1.5 - [fixed] Fixes loss of precision for 64 bit numbers on older 32 bit iOS devices with persistence enabled. - [changed] Addresses CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF warnings that surface in newer versions of Xcode and CocoaPods. diff --git a/Firebase/Messaging/CHANGELOG.md b/Firebase/Messaging/CHANGELOG.md index a11be06..4148f76 100644 --- a/Firebase/Messaging/CHANGELOG.md +++ b/Firebase/Messaging/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2015-07-10 -- v3.0.3 +- Fixed an issue that client should suspend the topic requests when token is not available and resume the topic operation when the token is generated. +- Corrected the deprecation warning when subscribing to or unsubscribing from an invalid topic. (#1397) +- Removed unused heart beat time stamp tracking. + # 2015-06-12 -- v3.0.2 - Added a warning message when subscribing to topics with incorrect name formats. - Silenced a deprecation warning in FIRMessaging. diff --git a/Firebase/Messaging/FIRMessaging.m b/Firebase/Messaging/FIRMessaging.m index 100c18a..fa4bdbc 100644 --- a/Firebase/Messaging/FIRMessaging.m +++ b/Firebase/Messaging/FIRMessaging.m @@ -724,7 +724,7 @@ NSString *const kFIRMessagingPlistAutoInitEnabled = - (void)unsubscribeFromTopic:(NSString *)topic completion:(nullable FIRMessagingTopicOperationCompletion)completion { - if ([FIRMessagingPubSub hasTopicsPrefix:topic]) { + if ([FIRMessagingPubSub hasTopicsPrefix:topic]) { FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated, @"Format '%@' is deprecated. Only '%@' should be used in " @"unsubscribeFromTopic.", diff --git a/Firebase/Messaging/FIRMessagingConnection.h b/Firebase/Messaging/FIRMessagingConnection.h index e78adbf..25a018c 100644 --- a/Firebase/Messaging/FIRMessagingConnection.h +++ b/Firebase/Messaging/FIRMessagingConnection.h @@ -67,7 +67,6 @@ typedef NS_ENUM(NSUInteger, FIRMessagingConnectionCloseReason) { */ @interface FIRMessagingConnection : NSObject -@property(nonatomic, readwrite, assign) int64_t lastHeartbeatPingTimestamp; @property(nonatomic, readonly, assign) FIRMessagingConnectionState state; @property(nonatomic, readonly, copy) NSString *host; @property(nonatomic, readonly, assign) NSUInteger port; diff --git a/Firebase/Messaging/FIRMessagingConnection.m b/Firebase/Messaging/FIRMessagingConnection.m index afbd0ba..8694326 100644 --- a/Firebase/Messaging/FIRMessagingConnection.m +++ b/Firebase/Messaging/FIRMessagingConnection.m @@ -460,9 +460,6 @@ static NSString *const kRemoteFromAddress = @"from"; } - (void)didReceiveHeartbeatAck:(GtalkHeartbeatAck *)heartbeatAck { -#if FIRMessaging_PROBER - self.lastHeartbeatPingTimestamp = FIRMessagingCurrentTimestampInSeconds(); -#endif } - (void)didReceiveDataMessageStanza:(GtalkDataMessageStanza *)dataMessageStanza { diff --git a/Firebase/Messaging/FIRMessagingSecureSocket.m b/Firebase/Messaging/FIRMessagingSecureSocket.m index b7e8133..3a03ee3 100644 --- a/Firebase/Messaging/FIRMessagingSecureSocket.m +++ b/Firebase/Messaging/FIRMessagingSecureSocket.m @@ -129,10 +129,6 @@ static NSUInteger SerializedSize(int32_t value) { BOOL isVOIPSocket = NO; -#if FIRMessaging_PROBER - isVOIPSocket = YES; -#endif - [self openStream:self.outStream isVOIPStream:isVOIPSocket]; [self openStream:self.inStream isVOIPStream:isVOIPSocket]; } diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md index 15294ea..c7b745d 100644 --- a/Firestore/CHANGELOG.md +++ b/Firestore/CHANGELOG.md @@ -1,5 +1,8 @@ # Unreleased +# v0.12.5 +- [changed] Internal improvements. + # v0.12.4 - [fixed] `setData` methods taking `mergeFields:` arguments can now delete fields using `FieldValue.delete()`. diff --git a/Firestore/CMakeLists.txt b/Firestore/CMakeLists.txt index 652b895..d5027ce 100644 --- a/Firestore/CMakeLists.txt +++ b/Firestore/CMakeLists.txt @@ -65,32 +65,24 @@ set(FIREBASE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) # # If you want to use this project directly in e.g. CLion, make sure you # configure this. +# +# The superbuild passes CMAKE_INSTALL_PREFIX with a value of +# ${FIREBASE_INSTALL_DIR} which is ${PROJECT_BINARY_DIR}/opt. set(FIREBASE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}) +# Expect that the source and binary directory structures will parallel each +# other. +set(FIREBASE_BINARY_DIR ${PROJECT_BINARY_DIR}/..) + list(INSERT CMAKE_MODULE_PATH 0 ${FIREBASE_SOURCE_DIR}/cmake) include(utils) -# Include GoogleTest directly in the build. -set(gtest_dir ${FIREBASE_INSTALL_DIR}/external/googletest) -add_subdirectory( - ${gtest_dir}/src/googletest - ${gtest_dir}/src/googletest-build - EXCLUDE_FROM_ALL -) - -# Set up aliases with the same names as available via FindGTest. -add_library( - GTest::GTest ALIAS gtest -) - -add_library( - GTest::Main ALIAS gtest_main -) - +find_package(GTest REQUIRED) +find_package(GMock REQUIRED) find_package(LevelDB REQUIRED) -find_package(GRPC REQUIRED) find_package(Nanopb REQUIRED) find_package(Protobuf REQUIRED) +find_package(GRPC REQUIRED) if(APPLE) find_package(FirebaseCore REQUIRED) @@ -101,8 +93,11 @@ add_subdirectory(third_party/abseil-cpp) include(CompilerSetup) +# Superbuild installed results +include_directories(${FIREBASE_INSTALL_DIR}/include) + # Generated sources will be relative to the binary directory. -include_directories(${FIREBASE_INSTALL_DIR}) +include_directories(${FIREBASE_BINARY_DIR}) # Fully qualified imports, project wide include_directories(${FIREBASE_SOURCE_DIR}) diff --git a/Firestore/Protos/CMakeLists.txt b/Firestore/Protos/CMakeLists.txt index 5c0fda0..831b53d 100644 --- a/Firestore/Protos/CMakeLists.txt +++ b/Firestore/Protos/CMakeLists.txt @@ -82,7 +82,7 @@ cc_library( cpp/google/type/latlng.pb.cc cpp/google/type/latlng.pb.h DEPENDS - protobuf + protobuf::libprotobuf EXCLUDE_FROM_ALL ) diff --git a/Firestore/Source/Remote/FSTOnlineStateTracker.h b/Firestore/Source/Remote/FSTOnlineStateTracker.h index 2521c84..340b641 100644 --- a/Firestore/Source/Remote/FSTOnlineStateTracker.h +++ b/Firestore/Source/Remote/FSTOnlineStateTracker.h @@ -57,7 +57,7 @@ NS_ASSUME_NONNULL_BEGIN * We then may allow multiple failures (based on kMaxWatchStreamFailures) before we actually * transition to FSTOnlineStateOffline. */ -- (void)handleWatchStreamFailure; +- (void)handleWatchStreamFailure:(NSError *)error; /** * Explicitly sets the FSTOnlineState to the specified state. diff --git a/Firestore/Source/Remote/FSTOnlineStateTracker.mm b/Firestore/Source/Remote/FSTOnlineStateTracker.mm index fb993e5..a5c2b38 100644 --- a/Firestore/Source/Remote/FSTOnlineStateTracker.mm +++ b/Firestore/Source/Remote/FSTOnlineStateTracker.mm @@ -84,11 +84,10 @@ static const NSTimeInterval kOnlineStateTimeout = 10; HARD_ASSERT( self.state == FSTOnlineStateUnknown, "Timer should be canceled if we transitioned to a different state."); - LOG_DEBUG( - "Watch stream didn't reach Online or Offline within %s seconds. " - "Considering client offline.", - kOnlineStateTimeout); - [self logClientOfflineWarningIfNecessary]; + [self logClientOfflineWarningIfNecessaryWithReason: + [NSString + stringWithFormat:@"Backend didn't respond within %f seconds.", + kOnlineStateTimeout]]; [self setAndBroadcastState:FSTOnlineStateOffline]; // NOTE: handleWatchStreamFailure will continue to increment @@ -98,7 +97,7 @@ static const NSTimeInterval kOnlineStateTimeout = 10; } } -- (void)handleWatchStreamFailure { +- (void)handleWatchStreamFailure:(NSError *)error { if (self.state == FSTOnlineStateOnline) { [self setAndBroadcastState:FSTOnlineStateUnknown]; @@ -110,7 +109,9 @@ static const NSTimeInterval kOnlineStateTimeout = 10; self.watchStreamFailures++; if (self.watchStreamFailures >= kMaxWatchStreamFailures) { [self clearOnlineStateTimer]; - [self logClientOfflineWarningIfNecessary]; + [self logClientOfflineWarningIfNecessaryWithReason: + [NSString stringWithFormat:@"Connection failed %d times. Most recent error: %@", + kMaxWatchStreamFailures, error]]; [self setAndBroadcastState:FSTOnlineStateOffline]; } } @@ -136,10 +137,18 @@ static const NSTimeInterval kOnlineStateTimeout = 10; } } -- (void)logClientOfflineWarningIfNecessary { +- (void)logClientOfflineWarningIfNecessaryWithReason:(NSString *)reason { + NSString *message = [NSString + stringWithFormat: + @"Could not reach Cloud Firestore backend. %@\n This typically indicates that your " + @"device does not have a healthy Internet connection at the moment. The client will " + @"operate in offline mode until it is able to successfully connect to the backend.", + reason]; if (self.shouldWarnClientIsOffline) { - LOG_WARN("Could not reach Firestore backend."); + LOG_WARN("%s", message); self.shouldWarnClientIsOffline = NO; + } else { + LOG_DEBUG("%s", message); } } diff --git a/Firestore/Source/Remote/FSTRemoteStore.mm b/Firestore/Source/Remote/FSTRemoteStore.mm index 4309c74..4d8aa7e 100644 --- a/Firestore/Source/Remote/FSTRemoteStore.mm +++ b/Firestore/Source/Remote/FSTRemoteStore.mm @@ -323,11 +323,15 @@ static const int kMaxPendingWrites = 10; "enabled"); [self cleanUpWatchStreamState]; - [self.onlineStateTracker handleWatchStreamFailure]; // If the watch stream closed due to an error, retry the connection if there are any active // watch targets. if ([self shouldStartWatchStream]) { + if (error) { + // There should generally be an error if the watch stream was closed when it's still needed, + // but it's not quite worth asserting. + [self.onlineStateTracker handleWatchStreamFailure:error]; + } [self startWatchStream]; } else { // We don't need to restart the watch stream because there are no active targets. The online diff --git a/Firestore/core/test/firebase/firestore/util/CMakeLists.txt b/Firestore/core/test/firebase/firestore/util/CMakeLists.txt index 0345f7c..45245ff 100644 --- a/Firestore/core/test/firebase/firestore/util/CMakeLists.txt +++ b/Firestore/core/test/firebase/firestore/util/CMakeLists.txt @@ -137,7 +137,7 @@ cc_test( absl_base absl_strings firebase_firestore_util - gmock + GMock::GMock ) if(APPLE) diff --git a/Firestore/third_party/abseil-cpp/CMakeLists.txt b/Firestore/third_party/abseil-cpp/CMakeLists.txt index 7318cd3..4b939fa 100644 --- a/Firestore/third_party/abseil-cpp/CMakeLists.txt +++ b/Firestore/third_party/abseil-cpp/CMakeLists.txt @@ -76,14 +76,14 @@ endif() ## check targets if(BUILD_TESTING) - check_target(gtest) - check_target(gtest_main) - check_target(gmock) + check_target(GTest::GTest) + check_target(GTest::Main) + check_target(GMock::GMock) list(APPEND ABSL_TEST_COMMON_LIBRARIES - gtest_main - gtest - gmock + GTest::GTest + GTest::Main + GMock::GMock ${CMAKE_THREAD_LIBS_INIT} ) endif() diff --git a/cmake/FindGMock.cmake b/cmake/FindGMock.cmake new file mode 100644 index 0000000..76ce227 --- /dev/null +++ b/cmake/FindGMock.cmake @@ -0,0 +1,47 @@ +# 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) + +find_path( + GMOCK_INCLUDE_DIR gmock/gmock.h + HINTS ${FIREBASE_INSTALL_DIR}/include +) + +find_library( + GMOCK_LIBRARY + NAMES gmock + HINTS ${FIREBASE_INSTALL_DIR}/lib +) + +find_package_handle_standard_args( + gmock + DEFAULT_MSG + GMOCK_INCLUDE_DIR + GMOCK_LIBRARY +) + +if(GMOCK_FOUND) + set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR}) + set(GMOCK_LIBRARIES ${GMOCK_LIBRARY}) + + if (NOT TARGET GMock::GMock) + add_library(GMock::GMock UNKNOWN IMPORTED) + set_target_properties( + GMock::GMock PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GMOCK_INCLUDE_DIRS} + IMPORTED_LOCATION ${GMOCK_LIBRARY} + ) + endif() +endif(GMOCK_FOUND) diff --git a/cmake/FindGRPC.cmake b/cmake/FindGRPC.cmake index f594b9e..22c9655 100644 --- a/cmake/FindGRPC.cmake +++ b/cmake/FindGRPC.cmake @@ -15,7 +15,7 @@ include(FindPackageHandleStandardArgs) include(FindZLIB) -set(BINARY_DIR ${FIREBASE_INSTALL_DIR}/external/grpc) +set(BINARY_DIR ${FIREBASE_BINARY_DIR}/external/grpc) ## ZLIB diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index b664fa8..56f10e1 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(binary_dir ${FIREBASE_INSTALL_DIR}/external/leveldb/src/leveldb) +set(binary_dir ${FIREBASE_BINARY_DIR}/external/leveldb/src/leveldb) find_path( LEVELDB_INCLUDE_DIR leveldb/db.h diff --git a/cmake/FindNanopb.cmake b/cmake/FindNanopb.cmake index b5d844d..131be2a 100644 --- a/cmake/FindNanopb.cmake +++ b/cmake/FindNanopb.cmake @@ -14,17 +14,15 @@ include(FindPackageHandleStandardArgs) -set(BINARY_DIR ${FIREBASE_INSTALL_DIR}/external/nanopb) +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 60a2e34..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_INSTALL_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/googletest.cmake b/cmake/external/googletest.cmake index 24da386..3af136e 100644 --- a/cmake/external/googletest.cmake +++ b/cmake/external/googletest.cmake @@ -17,17 +17,16 @@ include(ExternalProject) ExternalProject_Add( googletest - DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/downloads + DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} DOWNLOAD_NAME googletest-1.8.0.tar.gz URL https://github.com/google/googletest/archive/release-1.8.0.tar.gz URL_HASH SHA256=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8 PREFIX ${PROJECT_BINARY_DIR}/external/googletest - # Just download the sources without building. + CMAKE_CACHE_ARGS + -DCMAKE_INSTALL_PREFIX:STRING=${FIREBASE_INSTALL_DIR} + UPDATE_COMMAND "" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" TEST_COMMAND "" ) 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/leveldb.cmake b/cmake/external/leveldb.cmake index dcbef6c..db8aa4c 100644 --- a/cmake/external/leveldb.cmake +++ b/cmake/external/leveldb.cmake @@ -44,12 +44,12 @@ else() ExternalProject_Add( leveldb - DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/downloads + DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} DOWNLOAD_NAME leveldb-v1.20.tar.gz URL https://github.com/google/leveldb/archive/v1.20.tar.gz URL_HASH SHA256=f5abe8b5b209c2f36560b75f32ce61412f39a2922f7045ae764a2c23335b6664 - PREFIX ${PROJECT_BINARY_DIR}/external/leveldb + PREFIX ${FIREBASE_BINARY_DIR}/external/leveldb # LevelDB's configuration is done in the Makefile CONFIGURE_COMMAND "" diff --git a/cmake/external/nanopb.cmake b/cmake/external/nanopb.cmake index 6ca47c0..39eb833 100644 --- a/cmake/external/nanopb.cmake +++ b/cmake/external/nanopb.cmake @@ -14,17 +14,14 @@ include(ExternalProject) -set( - NANOPB_PROTOC_BIN - ${FIREBASE_INSTALL_DIR}/external/protobuf/src/protobuf-build/${CMAKE_CFG_INTDIR}/protoc -) +set(NANOPB_PROTOC_BIN ${FIREBASE_INSTALL_DIR}/bin/protoc) ExternalProject_Add( nanopb DEPENDS protobuf - DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/downloads + DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} URL https://github.com/nanopb/nanopb/archive/nanopb-0.3.9.1.tar.gz URL_HASH SHA256=67460d0c0ad331ef4d5369ad337056d0cd2f900c94887628d287eb56c69324bc @@ -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 acc5a96..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=<INSTALL_DIR> + -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=$<CONFIG>) +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 $<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 ${PROJECT_BINARY_DIR}/downloads - DOWNLOAD_NAME protobuf-v3.5.11.tar.gz + DOWNLOAD_DIR ${FIREBASE_DOWNLOAD_DIR} + 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 "" ) diff --git a/cmake/xcodebuild.cmake b/cmake/xcodebuild.cmake index 01a2961..3c7be51 100644 --- a/cmake/xcodebuild.cmake +++ b/cmake/xcodebuild.cmake @@ -67,7 +67,7 @@ function(xcodebuild framework) # The source directory doesn't actually matter SOURCE_DIR ${PROJECT_SOURCE_DIR} - BINARY_DIR ${PROJECT_BINARY_DIR}/Frameworks + INSTALL_DIR ${FIREBASE_INSTALL_DIR}/Frameworks CONFIGURE_COMMAND "" @@ -77,7 +77,7 @@ function(xcodebuild framework) -scheme ${scheme} -configuration ${configuration} -destination ${destination} - CONFIGURATION_BUILD_DIR=<BINARY_DIR> + CONFIGURATION_BUILD_DIR=<INSTALL_DIR> build ${pipe_xcpretty} BUILD_ALWAYS ${BUILD_PODS} |