From d47474823b5a8abdc2d9cee798b3437c250bb207 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 9 Apr 2026 09:32:47 -0400 Subject: [PATCH 1/9] StoreKit2 support for Apple devices --- CMakeLists.txt | 6 + analytics/CMakeLists.txt | 76 ++++++++++- analytics/integration_test/readme.md | 31 +++++ .../integration_test/src/integration_test.cc | 19 +++ analytics/src/analytics_android.cc | 24 ++++ analytics/src/analytics_common.h | 5 +- analytics/src/analytics_desktop.cc | 24 ++++ analytics/src/analytics_ios.mm | 54 +++++++- analytics/src/include/firebase/analytics.h | 31 +++++ analytics/src/ios/swift/StoreKit2Bridge.swift | 37 ++++++ app/CMakeLists.txt | 125 ++++++++---------- release_build_files/readme.md | 1 + scripts/gha/build_ios_tvos.py | 43 ++++-- test_mac_ios_simulator.sh | 7 +- 14 files changed, 387 insertions(+), 96 deletions(-) create mode 100644 analytics/src/ios/swift/StoreKit2Bridge.swift mode change 100644 => 100755 test_mac_ios_simulator.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index c1bbe08a9b..f956830507 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,8 +96,14 @@ set(FIREBASE_XCODE_TARGET_FORMAT "frameworks" CACHE STRING set(FIREBASE_CPP_SDK_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) project (firebase NONE) + +set(CMAKE_Swift_LANGUAGE_VERSION 5.9) + enable_language(C) enable_language(CXX) +if (IOS) + enable_language(Swift) +endif() if(NOT DEFINED CMAKE_CXX_COMPILER_LAUNCHER) find_program(CCACHE_PROGRAM ccache) diff --git a/analytics/CMakeLists.txt b/analytics/CMakeLists.txt index 63d33b125f..b40b6c78d0 100644 --- a/analytics/CMakeLists.txt +++ b/analytics/CMakeLists.txt @@ -72,7 +72,8 @@ set(android_SRCS # Source files used by the iOS implementation. set(ios_SRCS - src/analytics_ios.mm) + src/analytics_ios.mm + src/ios/swift/StoreKit2Bridge.swift) # Source files used by the desktop / stub implementation. set(desktop_SRCS @@ -88,8 +89,12 @@ if(ANDROID) set(analytics_platform_SRCS "${android_SRCS}") elseif(IOS) + if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") + message(FATAL_ERROR "Swift is not supported by the 'Unix Makefiles' generator on iOS. Please use the Xcode generator (-G Xcode) or Ninja (-G Ninja).") + endif() set(analytics_platform_SRCS "${ios_SRCS}") + else() set(analytics_platform_SRCS "${desktop_SRCS}") @@ -99,6 +104,9 @@ add_library(firebase_analytics STATIC ${common_SRCS} ${analytics_platform_SRCS}) + +add_dependencies(firebase_analytics FIREBASE_ANALYTICS_GENERATED_HEADERS) + set_property(TARGET firebase_analytics PROPERTY FOLDER "Firebase Cpp") # Set up the dependency on Firebase App. @@ -123,19 +131,73 @@ target_compile_definitions(firebase_analytics ) # Automatically include headers that might not be declared. if(MSVC) - add_definitions(/FI"assert.h" /FI"string.h" /FI"stdint.h") + target_compile_options(firebase_analytics PRIVATE + $<$>:/FI"assert.h"> + $<$>:/FI"string.h"> + $<$>:/FI"stdint.h">) else() - add_definitions(-include assert.h -include string.h) + target_compile_options(firebase_analytics PRIVATE + $<$>:SHELL:-include assert.h -include string.h> + ) endif() if(ANDROID) firebase_cpp_proguard_file(analytics) elseif(IOS) - # Enable Automatic Reference Counting (ARC) and Bitcode. + # Enable Automatic Reference Counting (ARC) and Bitcode specifically for Objective-C++ files. + # Note: -fembed-bitcode is placed here for src/analytics_ios.mm so that it is not passed + # to the Swift compiler, which does not support the flag. + set_source_files_properties(src/analytics_ios.mm PROPERTIES COMPILE_OPTIONS "-fobjc-arc;-fembed-bitcode") + + target_include_directories(firebase_analytics + PRIVATE + "$(DERIVED_FILE_DIR)" + ) + +if(IOS OR TVOS) + # Swift needs to find the FirebaseAnalytics module from CocoaPods + set(pods_dir "${FIREBASE_POD_DIR}/Pods") + + # Point to the base directories containing the .xcframework folders. + # Xcode natively handles XCFrameworks and will pick the right slice automatically. + # Determine the xcframework architecture slice based on the target platform + # and if it is running on simulator or device. + if(IOS) + string(TOLOWER "${CMAKE_OSX_SYSROOT}" sysroot_lower) + if(sysroot_lower MATCHES "simulator") + set(analytics_slice "ios-arm64_x86_64-simulator") + else() + set(analytics_slice "ios-arm64") + endif() + elseif(TVOS) + string(TOLOWER "${CMAKE_OSX_SYSROOT}" sysroot_lower) + if(sysroot_lower MATCHES "simulator") + set(analytics_slice "tvos-arm64_x86_64-simulator") + else() + set(analytics_slice "tvos-arm64") + endif() + endif() + + set(analytics_framework_dir "${pods_dir}/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/${analytics_slice}") + set(measurement_framework_dir "${pods_dir}/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/${analytics_slice}") + target_compile_options(firebase_analytics - PUBLIC "-fobjc-arc" "-fembed-bitcode") - target_link_libraries(firebase_analytics - PUBLIC "-fembed-bitcode") + PRIVATE + $<$:-F${analytics_framework_dir}> + $<$:-F${measurement_framework_dir}> + ) + + target_link_options(firebase_analytics + PUBLIC + "-F${analytics_framework_dir}" + "-F${measurement_framework_dir}" + ) + + # Prevent Xcode from trying to build or evaluate headers for unused architectures + set_target_properties(firebase_analytics PROPERTIES + XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "YES" + ) +endif() setup_pod_headers( firebase_analytics diff --git a/analytics/integration_test/readme.md b/analytics/integration_test/readme.md index 18599e5952..7aac97e26a 100644 --- a/analytics/integration_test/readme.md +++ b/analytics/integration_test/readme.md @@ -64,6 +64,37 @@ Building and Running the sample "Analytics" tab accessible from [https://firebase.google.com/console/](https://firebase.google.com/console/). +#### iOS Testing LogAppleTransaction + +To test the log apple transaction function, you should use the existing test app and xcode's simulated transactions. +The manual test will involve running the integration test: `firebase_analytics_test/TestLogAppleTransaction` and verifying that it logs a transaction to the console. + + - Step 1: Set up the Local Xcode Environment + - In Xcode, go to File > New > File from Template and create a StoreKit Configuration File (.storekit). + - Give the configuration any name. + - Target both integration_test and integration_test_tvos + - Add at least one dummy product to this file. + - Do this by selecting the file in xcode and clicking the + button in the bottom left corner. + - Choose a Non-Consumable in app purchase product. + - Give it a Reference name of your choice (e.g. "ReferenceAppleIapProduct"). + - Give it a Product ID of your choice (e.g. "com.example.nonconsumable"). + - Make the app use the store kit file. In the top bar go to Product > Scheme > Edit Scheme... > + - In the left hand menu select Run + - Select the Options tab on the right + - Set the StoreKit Configuration dropdown to your new .storekit file. + - Step 2: Validate logging transactions + - Try running the test app with the dummy transaction ID. It should return an error from the + LogAppleTransactions function. + - After runnign the app once you can create a simulated transaction for testing. + - To create a simulated transaction ID: + - Go to Debug > StoreKit > Manage Transactions. + - Click the + button in the bottom left corner. + - Select the Non-Consumable in app purchase product. + - Copy the transaction ID to the test case and replace 'dummy_transaction_id' with your new transaction ID. e.g. '0' + - Make sure to update the testcase to now expect success. + - Then try running the test app again with the simulated transaction ID. + - It should log the transaction to the console. Both the Xcode console and firebase console should show a log for an in app purchase. + ### Android - Register your Android app with Firebase. - Create a new app on the [Firebase console](https://firebase.google.com/console/), and attach diff --git a/analytics/integration_test/src/integration_test.cc b/analytics/integration_test/src/integration_test.cc index 54016135d9..462b9b5912 100644 --- a/analytics/integration_test/src/integration_test.cc +++ b/analytics/integration_test/src/integration_test.cc @@ -22,6 +22,10 @@ #include #include +#if defined(__APPLE__) +#include +#endif + #include "app_framework.h" // NOLINT #include "firebase/analytics.h" #include "firebase/analytics/event_names.h" @@ -299,6 +303,21 @@ TEST_F(FirebaseAnalyticsTest, TestDesktopDebugMode) { firebase::analytics::SetDesktopDebugMode(false); } +TEST_F(FirebaseAnalyticsTest, TestLogAppleTransaction) { + auto future = + firebase::analytics::LogAppleTransaction("dummy_transaction_id"); + WaitForCompletionAnyResult(future, "LogAppleTransaction"); +#if defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV) + // On iOS/tvOS, passing a dummy transaction ID will fail to find a verified + // transaction. + EXPECT_NE(future.error(), 0); +#else + // On Android and Desktop (including macOS), LogAppleTransaction is a no-op + // that returns success. + EXPECT_EQ(future.error(), 0); +#endif +} + TEST_F(FirebaseAnalyticsTest, TestLogEvents) { // Log an event with no parameters. firebase::analytics::LogEvent(firebase::analytics::kEventLogin); diff --git a/analytics/src/analytics_android.cc b/analytics/src/analytics_android.cc index fe1ba4235a..9d097a847c 100644 --- a/analytics/src/analytics_android.cc +++ b/analytics/src/analytics_android.cc @@ -502,6 +502,30 @@ void LogEvent(const char* name) { LogEvent(name, nullptr, static_cast(0)); } +/// Log an Apple StoreKit 2 transaction. This is a no-op on Android and returns +/// success. +Future LogAppleTransaction(const char* transaction_id) { + auto* api = internal::FutureData::Get() ? internal::FutureData::Get()->api() + : nullptr; + if (!api) { + return Future(); + } + const auto future_handle = + api->SafeAlloc(internal::kAnalyticsFnLogAppleTransaction); + api->Complete(future_handle, 0, ""); + return Future(api, future_handle.get()); +} + +Future LogAppleTransactionLastResult() { + auto* api = internal::FutureData::Get() ? internal::FutureData::Get()->api() + : nullptr; + if (!api) { + return Future(); + } + return static_cast&>( + api->LastResult(internal::kAnalyticsFnLogAppleTransaction)); +} + // Log an event with associated parameters. void LogEvent(const char* name, const Parameter* parameters, size_t number_of_parameters) { diff --git a/analytics/src/analytics_common.h b/analytics/src/analytics_common.h index 90de297d7a..edad4ce07f 100644 --- a/analytics/src/analytics_common.h +++ b/analytics/src/analytics_common.h @@ -24,9 +24,10 @@ namespace analytics { namespace internal { enum AnalyticsFn { - kAnalyticsFnGetAnalyticsInstanceId, + kAnalyticsFnGetAnalyticsInstanceId = 0, kAnalyticsFnGetSessionId, - kAnalyticsFnCount + kAnalyticsFnLogAppleTransaction, + kAnalyticsFnCount, }; // Data structure which holds the Future API for this module. diff --git a/analytics/src/analytics_desktop.cc b/analytics/src/analytics_desktop.cc index 880c3936a9..c3181621e9 100644 --- a/analytics/src/analytics_desktop.cc +++ b/analytics/src/analytics_desktop.cc @@ -467,6 +467,30 @@ void LogEvent(const char* name) { LogEvent(name, static_cast(nullptr), 0); } +/// Log an Apple StoreKit 2 transaction. This is a no-op on Desktop and returns +/// success. +Future LogAppleTransaction(const char* transaction_id) { + auto* api = internal::FutureData::Get() ? internal::FutureData::Get()->api() + : nullptr; + if (!api) { + return Future(); + } + const auto future_handle = + api->SafeAlloc(internal::kAnalyticsFnLogAppleTransaction); + api->Complete(future_handle, 0, ""); + return Future(api, future_handle.get()); +} + +Future LogAppleTransactionLastResult() { + auto* api = internal::FutureData::Get() ? internal::FutureData::Get()->api() + : nullptr; + if (!api) { + return Future(); + } + return static_cast&>( + api->LastResult(internal::kAnalyticsFnLogAppleTransaction)); +} + void LogEvent(const char* name, const char* parameter_name, const char* parameter_value) { if (parameter_name == nullptr) { diff --git a/analytics/src/analytics_ios.mm b/analytics/src/analytics_ios.mm index 38aa5275e7..92c852ba88 100644 --- a/analytics/src/analytics_ios.mm +++ b/analytics/src/analytics_ios.mm @@ -20,9 +20,12 @@ #import "FIRAnalytics+OnDevice.h" #import "FIRAnalytics.h" +#include "analytics/src/analytics_common.h" #include "analytics/src/include/firebase/analytics.h" -#include "analytics/src/analytics_common.h" +// Include the generated Swift header for the C++ bridge. +#include + #include "app/src/assert.h" #include "app/src/include/firebase/internal/mutex.h" #include "app/src/include/firebase/version.h" @@ -231,6 +234,55 @@ void LogEvent(const char* name) { [FIRAnalytics logEventWithName:@(name) parameters:@{}]; } +extern "C" { +void CompleteLogAppleTransaction(const void* context, bool success) { + FIREBASE_ASSERT_RETURN_VOID(context != nullptr); + auto* handle_ptr = static_cast*>(const_cast(context)); + + MutexLock lock(g_mutex); + if (!internal::IsInitialized()) { + delete handle_ptr; + return; + } + + auto* api = internal::FutureData::Get()->api(); + if (success) { + api->Complete(*handle_ptr, 0, ""); + } else { + api->Complete(*handle_ptr, -1, "StoreKit 2 transaction not found."); + } + delete handle_ptr; +} +} + +Future LogAppleTransaction(const char* transaction_id) { + MutexLock lock(g_mutex); + FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized()); + + auto* api = internal::FutureData::Get()->api(); + const auto future_handle = api->SafeAlloc(internal::kAnalyticsFnLogAppleTransaction); + + if (!transaction_id) { + api->Complete(future_handle, -1, "Transaction ID is null"); + return Future(api, future_handle.get()); + } + + SafeFutureHandle* handle_ptr = new SafeFutureHandle(future_handle); + + [StoreKit2Bridge logTransaction:SafeString(transaction_id) + context:handle_ptr + completion:CompleteLogAppleTransaction]; + + return Future(api, future_handle.get()); +} + +Future LogAppleTransactionLastResult() { + MutexLock lock(g_mutex); + FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized()); + return static_cast&>( + internal::FutureData::Get()->api()->LastResult(internal::kAnalyticsFnLogAppleTransaction)); +} + // Declared here so that it can be used, defined below. NSDictionary* MapToDictionary(const std::map& map); diff --git a/analytics/src/include/firebase/analytics.h b/analytics/src/include/firebase/analytics.h index 47a5aab72b..fcdb723403 100644 --- a/analytics/src/include/firebase/analytics.h +++ b/analytics/src/include/firebase/analytics.h @@ -455,6 +455,37 @@ void LogEvent(const char* name, const char* parameter_name, /// @endif void LogEvent(const char* name); +/// @brief Logs an in-app purchase transaction specifically for Apple's +/// StoreKit 2. +/// +/// This function is intended for developers on iOS who process transactions +/// via custom native plugins or engines and need to securely log those +/// transactions natively through Google Analytics. The provided ID must map 1:1 +/// with the native Apple `Transaction.id`. If a matching transaction is not +/// found in the Apple device's purchase history, nothing will be logged to +/// Analytics. +/// +/// @note Finished consumable transactions are removed from the local +/// transaction history and cannot be retrieved by this function once +/// finished. Developers should either call this function before finishing +/// the transaction or use `FirebaseAnalytics.LogEvent` directly as a +/// fallback. +/// +/// @param transaction_id The native Apple transaction identifier as a +/// null-terminated string. +/// +/// @returns A Future that completes successfully when the native +/// StoreKit 2 transaction is found and logged. If the transaction +/// cannot be found, the Future will complete with a non-zero error(). +Future LogAppleTransaction(const char* transaction_id); + +/// @brief Get the result of the most recent LogAppleTransaction() call. +/// +/// @returns A Future that completes successfully when the native +/// StoreKit 2 transaction is found and logged. If the transaction +/// cannot be found, the Future will complete with a non-zero error(). +Future LogAppleTransactionLastResult(); + /// @brief Log an event with associated parameters. /// /// An Event is an important occurrence in your app that you want to diff --git a/analytics/src/ios/swift/StoreKit2Bridge.swift b/analytics/src/ios/swift/StoreKit2Bridge.swift new file mode 100644 index 0000000000..1b7c1edeba --- /dev/null +++ b/analytics/src/ios/swift/StoreKit2Bridge.swift @@ -0,0 +1,37 @@ +// Copyright 2026 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. + +import Foundation +import StoreKit +import FirebaseAnalytics + +@objc public class StoreKit2Bridge: NSObject { + + @objc public static func logTransaction(_ transactionId: String, context: UnsafeRawPointer, completion: @escaping @convention(c) (UnsafeRawPointer, Bool) -> Void) { + if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) { + Task { + for await case .verified(let transaction) in Transaction.all { + if String(transaction.id) == transactionId { + Analytics.logTransaction(transaction) + completion(context, true) + return + } + } + completion(context, false) + } + } else { + completion(context, false) + } + } +} \ No newline at end of file diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index c92f9124f8..2bd4e3f07e 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -320,6 +320,9 @@ add_library(firebase_app STATIC ${FIREBASE_GEN_FILE_DIR}/app/google_services_generated.h ${app_flatbuffers_srcs}) +add_dependencies(firebase_app FIREBASE_APP_GENERATED_HEADERS) +add_dependencies(firebase_app app_generated_google_services_includes) + set_property(TARGET firebase_app PROPERTY FOLDER "Firebase Cpp") # Disable exceptions in std @@ -364,22 +367,19 @@ target_link_libraries(firebase_app ${app_flatbuffers_lib} ${LIBSECRET_LIBRARIES} ) -# Automatically include headers that might not be declared. -if(MSVC) - add_definitions(/FI"assert.h" /FI"string.h" /FI"stdint.h") -else() - add_definitions(-include assert.h -include string.h) -endif() + target_compile_options(firebase_app PRIVATE + "$<$:SHELL:-include assert.h>" + "$<$:SHELL:-include string.h>" + "$<$:SHELL:-include assert.h>" + "$<$:SHELL:-include string.h>") if(ANDROID) firebase_cpp_proguard_file(app) elseif(IOS) # Enable Automatic Reference Counting (ARC) and Bitcode. + # Enable Automatic Reference Counting (ARC) for Objective-C/Swift interop target_compile_options(firebase_app - PUBLIC "-fobjc-arc" "-fembed-bitcode") - target_link_libraries(firebase_app - PUBLIC "-fembed-bitcode") - + PUBLIC $<$>:-fobjc-arc>) # Add empty include path to get root include folder '.' setup_pod_headers( firebase_app @@ -417,38 +417,16 @@ if (IOS) ) endif() - # Generate the analytics header file - # Copy from analytics/CMakeList.txt - function(generate_analytics_header OBJC_FILE CPP_FILE) - add_custom_command( - OUTPUT ${CPP_FILE} - COMMAND ${FIREBASE_PYTHON_EXECUTABLE} "${FIREBASE_SOURCE_DIR}/analytics/generate_constants.py" - "--objc_header=${OBJC_FILE}" - "--cpp_header=${CPP_FILE}" - DEPENDS ${OBJC_FILE} - COMMENT "Generating ${CPP_FILE}" - ) - endfunction() - set(analytics_generated_headers_dir - ${FIREBASE_GEN_FILE_DIR}/analytics/src/include/firebase/analytics) - file(MAKE_DIRECTORY ${FIREBASE_GEN_FILE_DIR}/analytics/src/include/firebase/analytics) - generate_analytics_header( - "${FIREBASE_SOURCE_DIR}/analytics/ios_headers/FIREventNames.h" - "${analytics_generated_headers_dir}/event_names.h" - ) - generate_analytics_header( - "${FIREBASE_SOURCE_DIR}/analytics/ios_headers/FIRParameterNames.h" - "${analytics_generated_headers_dir}/parameter_names.h" - ) - generate_analytics_header( - "${FIREBASE_SOURCE_DIR}/analytics/ios_headers/FIRUserPropertyNames.h" - "${analytics_generated_headers_dir}/user_property_names.h" - ) - set(analytics_HDRS - ${FIREBASE_SOURCE_DIR}/analytics/src/include/firebase/analytics.h - ${analytics_generated_headers_dir}/event_names.h - ${analytics_generated_headers_dir}/parameter_names.h - ${analytics_generated_headers_dir}/user_property_names.h) + if (FIREBASE_XCODE_TARGET_FORMAT STREQUAL "frameworks") + if (FIREBASE_INCLUDE_ANALYTICS) + set(analytics_HDRS + ${FIREBASE_SOURCE_DIR}/analytics/src/include/firebase/analytics.h + ${FIREBASE_GEN_FILE_DIR}/analytics/src/include/firebase/analytics/event_names.h + ${FIREBASE_GEN_FILE_DIR}/analytics/src/include/firebase/analytics/parameter_names.h + ${FIREBASE_GEN_FILE_DIR}/analytics/src/include/firebase/analytics/user_property_names.h) + else() + set(analytics_HDRS "") + endif() set(app_check_HDRS ${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check.h ${FIREBASE_SOURCE_DIR}/app_check/src/include/firebase/app_check/app_attest_provider.h @@ -470,35 +448,39 @@ if (IOS) ${FIREBASE_SOURCE_DIR}/database/src/include/firebase/database/mutable_data.h ${FIREBASE_SOURCE_DIR}/database/src/include/firebase/database/query.h ${FIREBASE_SOURCE_DIR}/database/src/include/firebase/database/transaction.h) - set(firestore_HDRS - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_query.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_query_snapshot.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_source.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/collection_reference.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_change.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_reference.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_snapshot.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/field_path.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/field_value.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/filter.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/listener_registration.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/load_bundle_task_progress.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/map_field_value.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/metadata_changes.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/query_snapshot.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/query.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/set_options.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/settings.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/snapshot_metadata.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/source.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/transaction.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/transaction_options.h - ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/write_batch.h - ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/firestore_errors.h - ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/firestore_version.h - ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/geo_point.h - ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/timestamp.h) + if (EXISTS "${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal") + set(firestore_HDRS + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_query.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_query_snapshot.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_source.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/collection_reference.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_change.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_reference.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_snapshot.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/field_path.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/field_value.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/filter.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/listener_registration.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/load_bundle_task_progress.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/map_field_value.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/metadata_changes.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/query_snapshot.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/query.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/set_options.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/settings.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/snapshot_metadata.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/source.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/transaction.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/transaction_options.h + ${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/write_batch.h + ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/firestore_errors.h + ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/firestore_version.h + ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/geo_point.h + ${FIREBASE_POD_DIR}/Pods/FirebaseFirestoreInternal/Firestore/core/include/firebase/firestore/timestamp.h) + else() + set(firestore_HDRS "") + endif() set(functions_HDRS ${FIREBASE_SOURCE_DIR}/functions/src/include/firebase/functions.h ${FIREBASE_SOURCE_DIR}/functions/src/include/firebase/functions/callable_reference.h @@ -563,4 +545,5 @@ if (IOS) # to destination dir "Headers/google_play_services/*" set_property(SOURCE "src/include/google_play_services/availability.h" PROPERTY MACOSX_PACKAGE_LOCATION Headers/google_play_services) + endif() # framework_HDRS endif() diff --git a/release_build_files/readme.md b/release_build_files/readme.md index 6c963edd74..4bdf08fc37 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -617,6 +617,7 @@ code. - Changes - Functions (general): Add in support for Limited Use Tokens. - Storage: Added `List` API for all platforms, which gets the list of items under a `StorageReference` + - Analytics: Add in `LogAppleTransaction` for logging Storekit 2 transactions on iOS. ### 13.5.0 - Changes diff --git a/scripts/gha/build_ios_tvos.py b/scripts/gha/build_ios_tvos.py index 7fe86343e6..760d7e5f42 100644 --- a/scripts/gha/build_ios_tvos.py +++ b/scripts/gha/build_ios_tvos.py @@ -85,6 +85,26 @@ def arrange_frameworks(archive_output_path): archive_output_path (str): Output path containing frameworks. Subdirectories should be the various target frameworks. """ + if not os.path.exists(archive_output_path): + logging.warning('Skipping arrange_frameworks for missing path: ' + archive_output_path) + return + + # Pull output out of Debug subdirectory if using multi-configuration generator (Xcode) + for entry in os.listdir(archive_output_path): + if entry.startswith('Debug') and os.path.isdir(os.path.join(archive_output_path, entry)): + debug_path = os.path.join(archive_output_path, entry) + logging.info('Pulling output out of subdirectory ' + debug_path) + for sub_entry in os.listdir(debug_path): + src = os.path.join(debug_path, sub_entry) + dest = os.path.join(archive_output_path, sub_entry) + if os.path.exists(dest): + if os.path.isdir(dest): + shutil.rmtree(dest) + else: + os.remove(dest) + shutil.move(src, archive_output_path) + os.rmdir(debug_path) + archive_output_dir_entries = os.listdir(archive_output_path) if not 'firebase.framework' in archive_output_dir_entries: # Rename firebase_app path to firebase path @@ -176,6 +196,8 @@ def build_universal_framework(frameworks_path, targets): platform_variant_architecture_dirs = os.listdir(framework_os_path) platform_variant_arch_map = defaultdict(list) for variant_architecture in platform_variant_architecture_dirs: + if '-' not in variant_architecture: + continue logging.debug('Inspecting ' + variant_architecture) platform_variant, architecture = variant_architecture.split('-') platform_variant_arch_map[platform_variant].append(architecture) @@ -199,9 +221,9 @@ def build_universal_framework(frameworks_path, targets): return # Pick any of the platform-arch directories as a reference candidate mainly - # for obtaining a list of contained targets. - reference_dir_path = os.path.join(framework_os_path, - platform_variant_architecture_dirs[0]) + # for obtaining a list of contained targets. Skip 'universal' if it's there. + valid_dirs = [d for d in platform_variant_architecture_dirs if d != 'universal'] + reference_dir_path = os.path.join(framework_os_path, valid_dirs[0]) logging.debug('Using {0} as reference path for scanning ' 'targets'.format(reference_dir_path)) # Filter only .framework directories and make sure the framework is @@ -218,9 +240,7 @@ def build_universal_framework(frameworks_path, targets): # Eg: split firebase_auth.framework -> firebase_auth, .framework target, _ = os.path.splitext(target_framework) for variant_architecture_dir in platform_variant_architecture_dirs: - # Since we have arm64 for both device and simulator, lipo cannot combine - # them in the same fat file. We ignore simulator-arm64. - if variant_architecture_dir == 'simulator-arm64': + if variant_architecture_dir == 'simulator-arm64' or variant_architecture_dir == 'universal': continue # //frameworks// # .framework/target @@ -233,7 +253,7 @@ def build_universal_framework(frameworks_path, targets): universal_target_path = os.path.join(framework_os_path, 'universal', target_framework) logging.debug('Ensuring all directories exist: ' + universal_target_path) - os.makedirs(universal_target_path) + os.makedirs(universal_target_path, exist_ok=True) # //frameworks/universal/.framework/ universal_target_library_path = os.path.join(universal_target_path, target) @@ -259,7 +279,8 @@ def build_universal_framework(frameworks_path, targets): 'Headers') shutil.copytree(firebase_framework_headers_path, - universal_firebase_framework_headers_path) + universal_firebase_framework_headers_path, + dirs_exist_ok=True) def build_xcframeworks(frameworks_path, xcframeworks_path, template_info_plist, @@ -389,7 +410,7 @@ def build_xcframeworks(frameworks_path, xcframeworks_path, template_info_plist, xcframework_key, '{0}.framework'.format(target)) logging.debug('Ensuring all directories exist: ' + library_output_dir) - os.makedirs(library_output_dir) + os.makedirs(library_output_dir, exist_ok=True) cmd = ['lipo', '-create'] cmd.extend(xcframework_libraries) cmd.append('-output') @@ -456,7 +477,7 @@ def cmake_configure(source_path, build_path, toolchain, archive_output_path, system. Used when building for ios/tvos. (eg:'arm64', 'x86_64') apple_os (str, optional): The Apple OS to build for. """ - cmd = ['cmake', '-S', source_path, '-B', build_path] + cmd = ['cmake', '-S', source_path, '-B', build_path, '-G', 'Xcode'] if toolchain: cmd.append('-DCMAKE_TOOLCHAIN_FILE={0}'.format(toolchain)) elif apple_os == 'ios': @@ -468,6 +489,8 @@ def cmake_configure(source_path, build_path, toolchain, archive_output_path, if platform_variant == 'simulator': cmd.append('-DCMAKE_OSX_SYSROOT=appletvsimulator') cmd.append('-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY={0}'.format(archive_output_path)) + cmd.append('-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={0}'.format(archive_output_path)) + cmd.append('-DCMAKE_RUNTIME_OUTPUT_DIRECTORY={0}'.format(archive_output_path)) if architecture: cmd.append('-DCMAKE_OSX_ARCHITECTURES={0}'.format(architecture)) utils.run_command(cmd) diff --git a/test_mac_ios_simulator.sh b/test_mac_ios_simulator.sh old mode 100644 new mode 100755 index 7fc9fa5e3f..ec98fb58fc --- a/test_mac_ios_simulator.sh +++ b/test_mac_ios_simulator.sh @@ -25,11 +25,8 @@ set -x mkdir -p mac_ios_simulator_build cd mac_ios_simulator_build -# Configure cmake with tests enabled -# and disable use of libsecret due to not working on kokoro builders -cmake -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator .. -DCLANG_ENABLE_MODULES=YES -DFIREBASE_CPP_BUILD_TESTS=ON -DFIREBASE_FORCE_FAKE_SECURE_STORAGE=ON "$@" +cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator .. -DCLANG_ENABLE_MODULES=YES -DFIREBASE_CPP_BUILD_TESTS=ON -DFIREBASE_FORCE_FAKE_SECURE_STORAGE=ON "$@" # Build the SDK and the tests -cpus=$(sysctl -n hw.ncpu) -cmake --build . -- -j $(cpus) +cmake --build . From 5f9cffddd8fc39a0d88db644d2760bf4c65bb237 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 9 Apr 2026 09:45:27 -0400 Subject: [PATCH 2/9] Add conditional building for win / android and make the build.sh changed as I have make the complier xcode --- analytics/CMakeLists.txt | 27 +++++++++++++++++++-------- app/CMakeLists.txt | 6 ++++++ build_scripts/ios/build.sh | 8 ++++++-- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/analytics/CMakeLists.txt b/analytics/CMakeLists.txt index b40b6c78d0..e45f1f12c1 100644 --- a/analytics/CMakeLists.txt +++ b/analytics/CMakeLists.txt @@ -130,15 +130,26 @@ target_compile_definitions(firebase_analytics -DINTERNAL_EXPERIMENTAL=1 ) # Automatically include headers that might not be declared. -if(MSVC) - target_compile_options(firebase_analytics PRIVATE - $<$>:/FI"assert.h"> - $<$>:/FI"string.h"> - $<$>:/FI"stdint.h">) +if(IOS) + if(MSVC) + target_compile_options(firebase_analytics PRIVATE + $<$>:/FI"assert.h"> + $<$>:/FI"string.h"> + $<$>:/FI"stdint.h">) + else() + target_compile_options(firebase_analytics PRIVATE + $<$>:SHELL:-include assert.h -include string.h> + ) + endif() else() - target_compile_options(firebase_analytics PRIVATE - $<$>:SHELL:-include assert.h -include string.h> - ) + if(MSVC) + target_compile_options(firebase_analytics PRIVATE + /FI"assert.h" /FI"string.h" /FI"stdint.h") + else() + target_compile_options(firebase_analytics PRIVATE + SHELL:-include assert.h -include string.h + ) + endif() endif() if(ANDROID) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 2bd4e3f07e..4284641de0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -367,11 +367,17 @@ target_link_libraries(firebase_app ${app_flatbuffers_lib} ${LIBSECRET_LIBRARIES} ) +if(APPLE) target_compile_options(firebase_app PRIVATE "$<$:SHELL:-include assert.h>" "$<$:SHELL:-include string.h>" "$<$:SHELL:-include assert.h>" "$<$:SHELL:-include string.h>") +else() + target_compile_options(firebase_app PRIVATE + "$<$:SHELL:-include assert.h>" + "$<$:SHELL:-include string.h>") +endif() if(ANDROID) firebase_cpp_proguard_file(app) diff --git a/build_scripts/ios/build.sh b/build_scripts/ios/build.sh index 73af95608f..b4c3521aa3 100755 --- a/build_scripts/ios/build.sh +++ b/build_scripts/ios/build.sh @@ -1,5 +1,7 @@ #!/bin/bash -e +export LANG=en_US.UTF-8 + # Copyright 2020 Google LLC # # Script to build iOS XCFrameworks @@ -123,7 +125,7 @@ if ${generateMakefiles}; then for arch in ${architectures[@]}; do sysroot_arg="" if [[ "${platform}" == "device" && " ${DEVICE_ARCHITECTURES[@]} " =~ " ${arch} " ]]; then - sysroot_arg="" # Default iphoneos sysroot is correct for iOS devices + sysroot_arg="-DCMAKE_OSX_SYSROOT=iphoneos" elif [[ "${platform}" == "simulator" && " ${SIMULATOR_ARCHITECTURES[@]} " =~ " ${arch} " ]]; then sysroot_arg="-DCMAKE_OSX_SYSROOT=iphonesimulator" # Must specify sysroot for simulator, especially for x86_64 else @@ -132,10 +134,12 @@ if ${generateMakefiles}; then echo "generate Makefiles start" mkdir -p ${buildpath}/ios_build_file/${platform}-${arch} && cd ${buildpath}/ios_build_file/${platform}-${arch} - cmake -DCMAKE_SYSTEM_NAME=iOS \ + cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS \ ${sysroot_arg} \ -DCMAKE_OSX_ARCHITECTURES=${arch} \ -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${buildpath}/${frameworkspath}/${platform}-${arch} \ + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG=${buildpath}/${frameworkspath}/${platform}-${arch} \ + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE=${buildpath}/${frameworkspath}/${platform}-${arch} \ ${sourcepath} echo "generate Makefiles end" done From 395fdc342377320ff9ff8860b3f085e724cce233 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 9 Apr 2026 10:07:04 -0400 Subject: [PATCH 3/9] Linux fix --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f956830507..6c90218bf4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,9 @@ cmake_minimum_required(VERSION 3.22) set (CMAKE_CXX_STANDARD 14) set (CMAKE_CXX_STANDARD_REQUIRED YES) # Don't fall back to an earlier version. +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + add_compile_definitions(_GNU_SOURCE) +endif() # Turn on virtual folders for visual studio set_property(GLOBAL PROPERTY USE_FOLDERS ON) From 8db868288e6f3276ffb07a4ebde246a7ae2e71ad Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 9 Apr 2026 10:23:25 -0400 Subject: [PATCH 4/9] Clean up --- analytics/CMakeLists.txt | 17 +++++++---------- app/src/secure/user_secure_fake_internal.cc | 1 + 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/analytics/CMakeLists.txt b/analytics/CMakeLists.txt index e45f1f12c1..7ceb30e6ee 100644 --- a/analytics/CMakeLists.txt +++ b/analytics/CMakeLists.txt @@ -165,7 +165,6 @@ elseif(IOS) "$(DERIVED_FILE_DIR)" ) -if(IOS OR TVOS) # Swift needs to find the FirebaseAnalytics module from CocoaPods set(pods_dir "${FIREBASE_POD_DIR}/Pods") @@ -173,19 +172,18 @@ if(IOS OR TVOS) # Xcode natively handles XCFrameworks and will pick the right slice automatically. # Determine the xcframework architecture slice based on the target platform # and if it is running on simulator or device. - if(IOS) - string(TOLOWER "${CMAKE_OSX_SYSROOT}" sysroot_lower) + string(TOLOWER "${CMAKE_OSX_SYSROOT}" sysroot_lower) + if(CMAKE_SYSTEM_NAME STREQUAL "tvOS") if(sysroot_lower MATCHES "simulator") - set(analytics_slice "ios-arm64_x86_64-simulator") + set(analytics_slice "tvos-arm64_x86_64-simulator") else() - set(analytics_slice "ios-arm64") + set(analytics_slice "tvos-arm64") endif() - elseif(TVOS) - string(TOLOWER "${CMAKE_OSX_SYSROOT}" sysroot_lower) + else() if(sysroot_lower MATCHES "simulator") - set(analytics_slice "tvos-arm64_x86_64-simulator") + set(analytics_slice "ios-arm64_x86_64-simulator") else() - set(analytics_slice "tvos-arm64") + set(analytics_slice "ios-arm64") endif() endif() @@ -208,7 +206,6 @@ if(IOS OR TVOS) set_target_properties(firebase_analytics PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "YES" ) -endif() setup_pod_headers( firebase_analytics diff --git a/app/src/secure/user_secure_fake_internal.cc b/app/src/secure/user_secure_fake_internal.cc index 5271d16aff..1b524e2a60 100644 --- a/app/src/secure/user_secure_fake_internal.cc +++ b/app/src/secure/user_secure_fake_internal.cc @@ -29,6 +29,7 @@ #include #include +#include #include #include From 5b2c2622438a8cd8a3fecf52c08ae8b64e1537a6 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 9 Apr 2026 10:36:22 -0400 Subject: [PATCH 5/9] revert the to include the old way of header generator --- app/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 4284641de0..852f30d9a9 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -367,7 +367,10 @@ target_link_libraries(firebase_app ${app_flatbuffers_lib} ${LIBSECRET_LIBRARIES} ) -if(APPLE) +if(MSVC) + target_compile_options(firebase_app PRIVATE + $<$:/FI"assert.h" /FI"string.h" /FI"stdint.h">) +elseif(APPLE) target_compile_options(firebase_app PRIVATE "$<$:SHELL:-include assert.h>" "$<$:SHELL:-include string.h>" From 44a69c3a961608627dc38a8a0bf4d60296574511 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 9 Apr 2026 11:39:49 -0400 Subject: [PATCH 6/9] clean up build and path finding --- analytics/CMakeLists.txt | 21 ++++++++++++++------- analytics/src/analytics_ios.mm | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/analytics/CMakeLists.txt b/analytics/CMakeLists.txt index 7ceb30e6ee..f9f1758a4c 100644 --- a/analytics/CMakeLists.txt +++ b/analytics/CMakeLists.txt @@ -72,8 +72,7 @@ set(android_SRCS # Source files used by the iOS implementation. set(ios_SRCS - src/analytics_ios.mm - src/ios/swift/StoreKit2Bridge.swift) + src/analytics_ios.mm) # Source files used by the desktop / stub implementation. set(desktop_SRCS @@ -160,10 +159,18 @@ elseif(IOS) # to the Swift compiler, which does not support the flag. set_source_files_properties(src/analytics_ios.mm PROPERTIES COMPILE_OPTIONS "-fobjc-arc;-fembed-bitcode") - target_include_directories(firebase_analytics - PRIVATE - "$(DERIVED_FILE_DIR)" - ) + add_library(firebase_analytics_swift OBJECT src/ios/swift/StoreKit2Bridge.swift) + target_link_libraries(firebase_analytics PUBLIC firebase_analytics_swift) + + if(CMAKE_GENERATOR STREQUAL "Xcode") + target_include_directories(firebase_analytics PRIVATE "$(DERIVED_FILE_DIR)") + target_compile_options(firebase_analytics PRIVATE + "-I$(OBJECT_FILE_DIR_normal)/$(CURRENT_ARCH)" + "-I$(BUILD_DIR)/firebase_analytics_swift.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/DerivedSources" + ) + else() + target_include_directories(firebase_analytics PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + endif() # Swift needs to find the FirebaseAnalytics module from CocoaPods set(pods_dir "${FIREBASE_POD_DIR}/Pods") @@ -190,7 +197,7 @@ elseif(IOS) set(analytics_framework_dir "${pods_dir}/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/${analytics_slice}") set(measurement_framework_dir "${pods_dir}/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/${analytics_slice}") - target_compile_options(firebase_analytics + target_compile_options(firebase_analytics_swift PRIVATE $<$:-F${analytics_framework_dir}> $<$:-F${measurement_framework_dir}> diff --git a/analytics/src/analytics_ios.mm b/analytics/src/analytics_ios.mm index 92c852ba88..b5f2102ba7 100644 --- a/analytics/src/analytics_ios.mm +++ b/analytics/src/analytics_ios.mm @@ -24,7 +24,7 @@ #include "analytics/src/include/firebase/analytics.h" // Include the generated Swift header for the C++ bridge. -#include +#include "firebase_analytics_swift-Swift.h" #include "app/src/assert.h" #include "app/src/include/firebase/internal/mutex.h" From 4764cbfff9c6da8e30af40c09fc7d7d711cba316 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 9 Apr 2026 23:25:17 -0400 Subject: [PATCH 7/9] Fix tvOS build for Swift by directly compiling in target --- CMakeLists.txt | 2 +- analytics/CMakeLists.txt | 11 ++++------- analytics/src/analytics_ios.mm | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c90218bf4..826a062b26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,7 @@ set(CMAKE_Swift_LANGUAGE_VERSION 5.9) enable_language(C) enable_language(CXX) -if (IOS) +if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS") enable_language(Swift) endif() diff --git a/analytics/CMakeLists.txt b/analytics/CMakeLists.txt index f9f1758a4c..8c0e0c2e96 100644 --- a/analytics/CMakeLists.txt +++ b/analytics/CMakeLists.txt @@ -72,7 +72,8 @@ set(android_SRCS # Source files used by the iOS implementation. set(ios_SRCS - src/analytics_ios.mm) + src/analytics_ios.mm + src/ios/swift/StoreKit2Bridge.swift) # Source files used by the desktop / stub implementation. set(desktop_SRCS @@ -159,14 +160,10 @@ elseif(IOS) # to the Swift compiler, which does not support the flag. set_source_files_properties(src/analytics_ios.mm PROPERTIES COMPILE_OPTIONS "-fobjc-arc;-fembed-bitcode") - add_library(firebase_analytics_swift OBJECT src/ios/swift/StoreKit2Bridge.swift) - target_link_libraries(firebase_analytics PUBLIC firebase_analytics_swift) - if(CMAKE_GENERATOR STREQUAL "Xcode") target_include_directories(firebase_analytics PRIVATE "$(DERIVED_FILE_DIR)") target_compile_options(firebase_analytics PRIVATE "-I$(OBJECT_FILE_DIR_normal)/$(CURRENT_ARCH)" - "-I$(BUILD_DIR)/firebase_analytics_swift.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/DerivedSources" ) else() target_include_directories(firebase_analytics PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") @@ -197,7 +194,7 @@ elseif(IOS) set(analytics_framework_dir "${pods_dir}/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/${analytics_slice}") set(measurement_framework_dir "${pods_dir}/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/${analytics_slice}") - target_compile_options(firebase_analytics_swift + target_compile_options(firebase_analytics PRIVATE $<$:-F${analytics_framework_dir}> $<$:-F${measurement_framework_dir}> @@ -208,7 +205,7 @@ elseif(IOS) "-F${analytics_framework_dir}" "-F${measurement_framework_dir}" ) - + # Prevent Xcode from trying to build or evaluate headers for unused architectures set_target_properties(firebase_analytics PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "YES" diff --git a/analytics/src/analytics_ios.mm b/analytics/src/analytics_ios.mm index b5f2102ba7..01e1c3f0a3 100644 --- a/analytics/src/analytics_ios.mm +++ b/analytics/src/analytics_ios.mm @@ -24,7 +24,7 @@ #include "analytics/src/include/firebase/analytics.h" // Include the generated Swift header for the C++ bridge. -#include "firebase_analytics_swift-Swift.h" +#include "firebase_analytics-Swift.h" #include "app/src/assert.h" #include "app/src/include/firebase/internal/mutex.h" From 42aa8db81818b30d0c2060834df0b9adda1f9535 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Fri, 10 Apr 2026 13:08:55 -0400 Subject: [PATCH 8/9] Add in dummy async func to force backward compatability --- release_build_files/readme.md | 12 ++++++++---- testing/sample_framework/src/empty.swift | 10 ++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/release_build_files/readme.md b/release_build_files/readme.md index 4bdf08fc37..ea9e5dedd4 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -265,8 +265,10 @@ the Firebase iOS SDK. Please ensure that you reference the Cocoapod versions listed above. Note: Parts of the Firebase iOS SDK are written in Swift. If your application -does not use any Swift code, you may need to add an empty .swift file to your -Xcode project to ensure that the Swift runtime is included in your app. +does not use any Swift code, you may need to add a .swift file to your +Xcode project to ensure that the Swift runtime is included in your app. To +ensure compatibility with Swift Concurrency on iOS 15 and 16, this file should +contain a dummy async function: `func _firebase_sdk_dummy_async() async {}`. #### Libraries @@ -324,8 +326,10 @@ the Firebase iOS SDK. Please ensure that you reference the Cocoapod versions listed above. Note: Parts of the Firebase iOS SDK are written in Swift. If your application -does not use any Swift code, you may need to add an empty .swift file to your -Xcode project to ensure that the Swift runtime is included in your app. +does not use any Swift code, you may need to add a .swift file to your +Xcode project to ensure that the Swift runtime is included in your app. To +ensure compatibility with Swift Concurrency on iOS 15 and 16, this file should +contain a dummy async function: `func _firebase_sdk_dummy_async() async {}`. ### Desktop Implementation Dependencies diff --git a/testing/sample_framework/src/empty.swift b/testing/sample_framework/src/empty.swift index e1cb622251..97e8fbb973 100644 --- a/testing/sample_framework/src/empty.swift +++ b/testing/sample_framework/src/empty.swift @@ -13,3 +13,13 @@ // limitations under the License. // This empty Swift file is needed to ensure the Swift runtime is included. +// along with forcing the swift async libraries to be linked on older versions of iOS/tvOS + +import Foundation + +// This dummy async function forces Xcode to automatically link the +// Swift Concurrency backwards-compatibility libraries (libswift_Concurrency) +// on older iOS versions (iOS 15/16). +@available(iOS 13.0, tvOS 13.0, macOS 10.15, watchOS 6.0, *) +func _firebase_sdk_dummy_async_func() async { +} From 02d24483d675f7ad2b42e7a36f6aa392e5c8292b Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Fri, 10 Apr 2026 19:49:53 -0400 Subject: [PATCH 9/9] [StoreKit2] Fix Xcode 15 dyld launch crashes on iOS <=16 and update documentation This commit resolves several known compiler and runtime issues when compiling C++ alongside modern Swift (Concurrency) using Xcode 15+ for deployment on iOS 15/16: 1. `swift_task_alloc` (EXC_BAD_ACCESS): Mixing Swift Concurrency with `@objc` interfaces and C++ pointers on older runtimes causes memory segmentation faults. We introduced an Objective-C++ Block Barrier to keep C pointers on the C++ side (`analytics_ios.mm`) and used a detached `Task` with a pure Swift struct (`AppleTransactionVerifier.swift`) to safely isolate the async `Transaction.all` loop from the bridging boundary. 2. `AsyncIteratorProtocol` (Witness Table Corruption): Using a `for await` loop within an `@objc` class on iOS 15/16 triggers a known Xcode 15+ compiler bug leading to a runtime crash. We bypassed this by extracting the logic into a pure Swift struct and replacing the `for await` loop with manual `while let ... = await iterator.next()` iteration. 3. `__libcpp_verbose_abort`: Xcode 15 requires this symbol for C++ exception handling, but it is missing from the iOS 15/16 system `libc++`. We disabled verbose abort globally via `CMakeLists.txt` and provided a weak fallback implementation in `app_framework.cc` for integration tests to prevent a `dyld` launch crash. 4. `libswift_Concurrency.dylib`: The Swift compiler sometimes fails to weak-link the Concurrency backward compatibility library in Objective-C++ projects. We now natively inject `-Wl,-weak-lswift_Concurrency` into all integration test Xcode projects during `setup_integration_tests.py`. Internal dialog comments have been cleaned up and replaced with professional explanations suitable for open-source maintainers. Documentation in `release_build_files/readme.md` has been updated to provide clear instructions for manual C++ integrators to apply these linker/compiler flags if they experience similar crashes. --- CMakeLists.txt | 3 + analytics/CMakeLists.txt | 2 +- .../project.pbxproj | 12 ++++ analytics/src/analytics_ios.mm | 11 ++- .../ios/swift/AppleTransactionVerifier.swift | 72 +++++++++++++++++++ analytics/src/ios/swift/StoreKit2Bridge.swift | 37 ---------- .../project.pbxproj | 8 +++ .../project.pbxproj | 12 ++++ .../project.pbxproj | 12 ++++ .../project.pbxproj | 12 ++++ .../project.pbxproj | 12 ++++ .../project.pbxproj | 12 ++++ .../project.pbxproj | 12 ++++ .../project.pbxproj | 8 +++ .../project.pbxproj | 12 ++++ release_build_files/readme.md | 29 +++++--- .../project.pbxproj | 12 ++++ setup_integration_tests.py | 15 ++++ .../project.pbxproj | 12 ++++ testing/sample_framework/src/app_framework.cc | 21 ++++++ testing/sample_framework/src/empty.swift | 10 --- .../project.pbxproj | 8 +++ 22 files changed, 285 insertions(+), 59 deletions(-) create mode 100644 analytics/src/ios/swift/AppleTransactionVerifier.swift delete mode 100644 analytics/src/ios/swift/StoreKit2Bridge.swift diff --git a/CMakeLists.txt b/CMakeLists.txt index 826a062b26..4d3bb9810b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,6 +161,7 @@ if(DESKTOP AND APPLE) endif() if(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_DISABLE_AVAILABILITY -D_LIBCPP_HAS_NO_VERBOSE_ABORT") # For iOS and macOS, disable nullability completeness warning, as it makes the # build output for our Objective-C++ files much too verbose. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-nullability-completeness") @@ -365,6 +366,7 @@ endif() # Include Firestore's external build early to resolve conflicts on packages. if(FIRESTORE_USE_EXTERNAL_CMAKE_BUILD) if(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_DISABLE_AVAILABILITY -D_LIBCPP_HAS_NO_VERBOSE_ABORT") # On Apple, set GRPC_BAZEL_BUILD to fix an issue with __thread. # Setting this define makes gRPC use pthread's thread-local storage # instead of GCC's. @@ -486,6 +488,7 @@ if(DESKTOP) -DUSE_LIBUV=1 ) elseif(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_DISABLE_AVAILABILITY -D_LIBCPP_HAS_NO_VERBOSE_ABORT") set(websockets_additional_defines ${websockets_additional_defines} -DUSE_LIBUV=1 diff --git a/analytics/CMakeLists.txt b/analytics/CMakeLists.txt index 8c0e0c2e96..0065008dd7 100644 --- a/analytics/CMakeLists.txt +++ b/analytics/CMakeLists.txt @@ -73,7 +73,7 @@ set(android_SRCS # Source files used by the iOS implementation. set(ios_SRCS src/analytics_ios.mm - src/ios/swift/StoreKit2Bridge.swift) + src/ios/swift/AppleTransactionVerifier.swift) # Source files used by the desktop / stub implementation. set(desktop_SRCS diff --git a/analytics/integration_test/integration_test.xcodeproj/project.pbxproj b/analytics/integration_test/integration_test.xcodeproj/project.pbxproj index b7b48a1f42..d43e30ff77 100644 --- a/analytics/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/analytics/integration_test/integration_test.xcodeproj/project.pbxproj @@ -375,6 +375,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -418,6 +420,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -455,6 +459,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -487,6 +493,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -518,6 +526,8 @@ BC1D665F2668D10A005DC2DA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -572,6 +582,8 @@ BC1D66602668D10A005DC2DA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/analytics/src/analytics_ios.mm b/analytics/src/analytics_ios.mm index 01e1c3f0a3..f33297eeab 100644 --- a/analytics/src/analytics_ios.mm +++ b/analytics/src/analytics_ios.mm @@ -269,9 +269,14 @@ void CompleteLogAppleTransaction(const void* context, bool success) { SafeFutureHandle* handle_ptr = new SafeFutureHandle(future_handle); - [StoreKit2Bridge logTransaction:SafeString(transaction_id) - context:handle_ptr - completion:CompleteLogAppleTransaction]; + // 2. Call Swift using a standard Objective-C block. + // We capture the C++ handle_ptr inside the Objective-C block. Swift never sees it. + [AppleTransactionVerifier verifyWithTransactionId:SafeString(transaction_id) + completion:^(BOOL isFound) { + // 3. We are back in C++ land on the Main Thread. + // Call your completion logic directly. + CompleteLogAppleTransaction(handle_ptr, isFound == YES); + }]; return Future(api, future_handle.get()); } diff --git a/analytics/src/ios/swift/AppleTransactionVerifier.swift b/analytics/src/ios/swift/AppleTransactionVerifier.swift new file mode 100644 index 0000000000..29bbe40e03 --- /dev/null +++ b/analytics/src/ios/swift/AppleTransactionVerifier.swift @@ -0,0 +1,72 @@ +// Copyright 2026 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. + +import Foundation +import StoreKit +import FirebaseAnalytics + +// Pure Swift worker to prevent compiler generation bugs with witness tables +// when mixing @objc and Swift Concurrency on older iOS deployment targets. +@available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) +internal struct AppleTransactionWorker { + static func findAndLogTransaction(id: String) async -> Bool { + // Using a standard while loop instead of `for await` avoids a known + // Xcode 15+ compiler bug where corrupted witness tables are generated + // for AsyncSequences when targeting iOS 15/16. + var iterator = Transaction.all.makeAsyncIterator() + while let verificationResult = await iterator.next() { + if case .verified(let transaction) = verificationResult { + if String(transaction.id) == id { + Analytics.logTransaction(transaction) + return true + } + } + } + return false + } +} + +@objc public class AppleTransactionVerifier: NSObject { + + // Notice: To avoid C-pointer ABI layout issues across Swift boundaries, + // this interface relies purely on a standard Swift closure. The calling + // C++ layer captures any necessary pointers within an Objective-C block. + @objc public static func verify(transactionId: String, completion: @escaping (Bool) -> Void) { + if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) { + // Create a pure Swift String copy of the transaction ID. + // This ensures we do not rely on the memory of the bridged Objective-C + // NSString, which might be destroyed by the calling C++ thread before + // the asynchronous Task completes. + let safeId = String(transactionId) + + // Use a detached task to avoid inheriting any C++/ObjC thread context. + // This prevents EXC_BAD_ACCESS during `swift_task_alloc` on iOS 15/16. + Task.detached(priority: .userInitiated) { [safeId, completion] in + let isFound = await AppleTransactionWorker.findAndLogTransaction(id: safeId) + + // Return to the main thread to ensure thread safety when the C++ + // layer receives the callback and manages internal state. + DispatchQueue.main.async { + completion(isFound) + } + } + } else { + // Not on a supported OS, resolve immediately on the main thread + // to avoid potential deadlocks if called while holding a C++ mutex. + DispatchQueue.main.async { + completion(false) + } + } + } +} diff --git a/analytics/src/ios/swift/StoreKit2Bridge.swift b/analytics/src/ios/swift/StoreKit2Bridge.swift deleted file mode 100644 index 1b7c1edeba..0000000000 --- a/analytics/src/ios/swift/StoreKit2Bridge.swift +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2026 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. - -import Foundation -import StoreKit -import FirebaseAnalytics - -@objc public class StoreKit2Bridge: NSObject { - - @objc public static func logTransaction(_ transactionId: String, context: UnsafeRawPointer, completion: @escaping @convention(c) (UnsafeRawPointer, Bool) -> Void) { - if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) { - Task { - for await case .verified(let transaction) in Transaction.all { - if String(transaction.id) == transactionId { - Analytics.logTransaction(transaction) - completion(context, true) - return - } - } - completion(context, false) - } - } else { - completion(context, false) - } - } -} \ No newline at end of file diff --git a/app/integration_test/integration_test.xcodeproj/project.pbxproj b/app/integration_test/integration_test.xcodeproj/project.pbxproj index ecd3d7ba3a..29c291307a 100644 --- a/app/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/app/integration_test/integration_test.xcodeproj/project.pbxproj @@ -210,6 +210,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -253,6 +255,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -290,6 +294,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -322,6 +328,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; diff --git a/app_check/integration_test/integration_test.xcodeproj/project.pbxproj b/app_check/integration_test/integration_test.xcodeproj/project.pbxproj index d461e3db5c..d15f733d5d 100644 --- a/app_check/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/app_check/integration_test/integration_test.xcodeproj/project.pbxproj @@ -322,6 +322,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -365,6 +367,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -402,6 +406,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -435,6 +441,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -467,6 +475,8 @@ 9F2ABA39267A4721001A35CE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -521,6 +531,8 @@ 9F2ABA3A267A4721001A35CE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/auth/integration_test/integration_test.xcodeproj/project.pbxproj b/auth/integration_test/integration_test.xcodeproj/project.pbxproj index fee3b799bd..0f0f63d080 100644 --- a/auth/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/auth/integration_test/integration_test.xcodeproj/project.pbxproj @@ -400,6 +400,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -443,6 +445,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -480,6 +484,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -513,6 +519,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -545,6 +553,8 @@ 9F3A08FE266978C400E1D69F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -599,6 +609,8 @@ 9F3A08FF266978C400E1D69F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/database/integration_test/integration_test.xcodeproj/project.pbxproj b/database/integration_test/integration_test.xcodeproj/project.pbxproj index cd97e10c8d..f989cfeb2d 100644 --- a/database/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/database/integration_test/integration_test.xcodeproj/project.pbxproj @@ -322,6 +322,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -365,6 +367,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -402,6 +406,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -435,6 +441,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -467,6 +475,8 @@ 9F2ABA39267A4721001A35CE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -521,6 +531,8 @@ 9F2ABA3A267A4721001A35CE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/firestore/integration_test/integration_test.xcodeproj/project.pbxproj b/firestore/integration_test/integration_test.xcodeproj/project.pbxproj index d012e8557a..2c8adc2e56 100644 --- a/firestore/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/firestore/integration_test/integration_test.xcodeproj/project.pbxproj @@ -418,6 +418,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -461,6 +463,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -498,6 +502,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -531,6 +537,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -563,6 +571,8 @@ BC1D678C26799F8D005DC2DA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -620,6 +630,8 @@ BC1D678D26799F8D005DC2DA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/firestore/integration_test_internal/integration_test.xcodeproj/project.pbxproj b/firestore/integration_test_internal/integration_test.xcodeproj/project.pbxproj index 67c4326e90..e8b0aa9951 100644 --- a/firestore/integration_test_internal/integration_test.xcodeproj/project.pbxproj +++ b/firestore/integration_test_internal/integration_test.xcodeproj/project.pbxproj @@ -703,6 +703,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; @@ -746,6 +748,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; @@ -784,6 +788,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = AA66DDF2F9BB2D8480FAB9BD /* Pods-integration_test.debug.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -834,6 +840,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5FB592CD6A6DDFBF795F22C1 /* Pods-integration_test.release.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -883,6 +891,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = F64F2CE3EB5EF07EA247CB71 /* Pods-integration_test_tvos.debug.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -956,6 +966,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 3DE393E827F88B06CD3C39CD /* Pods-integration_test_tvos.release.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/functions/integration_test/integration_test.xcodeproj/project.pbxproj b/functions/integration_test/integration_test.xcodeproj/project.pbxproj index aea4f280ed..0341f57a98 100644 --- a/functions/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/functions/integration_test/integration_test.xcodeproj/project.pbxproj @@ -401,6 +401,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -444,6 +446,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -482,6 +486,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 8675F0B26689AA876629E125 /* Pods-integration_test.debug.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -516,6 +522,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = E30FEEB78B34075EC944F51F /* Pods-integration_test.release.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -549,6 +557,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = DC1961DDB894F0DB5BE0D891 /* Pods-integration_test_tvos.debug.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -607,6 +617,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 22934B574D2479C75CC4D751 /* Pods-integration_test_tvos.release.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/installations/integration_test/integration_test.xcodeproj/project.pbxproj b/installations/integration_test/integration_test.xcodeproj/project.pbxproj index 5eda7ec6c9..ab2ffbefcf 100644 --- a/installations/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/installations/integration_test/integration_test.xcodeproj/project.pbxproj @@ -210,6 +210,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -253,6 +255,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -290,6 +294,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -322,6 +328,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; diff --git a/messaging/integration_test/integration_test.xcodeproj/project.pbxproj b/messaging/integration_test/integration_test.xcodeproj/project.pbxproj index 801d0a002c..0feae07166 100644 --- a/messaging/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/messaging/integration_test/integration_test.xcodeproj/project.pbxproj @@ -399,6 +399,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -442,6 +444,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -480,6 +484,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 187DA1CE07295DEC4378B7E2 /* Pods-integration_test.debug.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -513,6 +519,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 577B09235E486561D55F37DF /* Pods-integration_test.release.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -545,6 +553,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = CCCD7F9F30C5B4CDF23E3893 /* Pods-integration_test_tvos.debug.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -600,6 +610,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 81EF7FBB876B573921A52197 /* Pods-integration_test_tvos.release.xcconfig */; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/release_build_files/readme.md b/release_build_files/readme.md index ea9e5dedd4..abdf6b8bfc 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -265,10 +265,16 @@ the Firebase iOS SDK. Please ensure that you reference the Cocoapod versions listed above. Note: Parts of the Firebase iOS SDK are written in Swift. If your application -does not use any Swift code, you may need to add a .swift file to your -Xcode project to ensure that the Swift runtime is included in your app. To -ensure compatibility with Swift Concurrency on iOS 15 and 16, this file should -contain a dummy async function: `func _firebase_sdk_dummy_async() async {}`. +does not use any Swift code, you may need to add an empty .swift file to your +Xcode project to ensure that the Swift runtime is included in your app. + +Additionally, to resolve known Xcode 15+ crashes when deploying to iOS 15 or 16, +you must add `-Wl,-weak-lswift_Concurrency` to your `OTHER_LDFLAGS` (Other +Linker Flags). If your application crashes with a 'Symbol not found' error for +`__libcpp_verbose_abort`, you should also add +`-D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY` to your +`OTHER_CPLUSPLUSFLAGS` (Other C++ Flags), or provide a fallback implementation +in your code (e.g., `extern "C" void __libcpp_verbose_abort(const char* f, ...) { abort(); }`). #### Libraries @@ -326,10 +332,16 @@ the Firebase iOS SDK. Please ensure that you reference the Cocoapod versions listed above. Note: Parts of the Firebase iOS SDK are written in Swift. If your application -does not use any Swift code, you may need to add a .swift file to your -Xcode project to ensure that the Swift runtime is included in your app. To -ensure compatibility with Swift Concurrency on iOS 15 and 16, this file should -contain a dummy async function: `func _firebase_sdk_dummy_async() async {}`. +does not use any Swift code, you may need to add an empty .swift file to your +Xcode project to ensure that the Swift runtime is included in your app. + +Additionally, to resolve known Xcode 15+ crashes when deploying to iOS 15 or 16, +you must add `-Wl,-weak-lswift_Concurrency` to your `OTHER_LDFLAGS` (Other +Linker Flags). If your application crashes with a 'Symbol not found' error for +`__libcpp_verbose_abort`, you should also add +`-D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY` to your +`OTHER_CPLUSPLUSFLAGS` (Other C++ Flags), or provide a fallback implementation +in your code (e.g., `extern "C" void __libcpp_verbose_abort(const char* f, ...) { abort(); }`). ### Desktop Implementation Dependencies @@ -622,6 +634,7 @@ code. - Functions (general): Add in support for Limited Use Tokens. - Storage: Added `List` API for all platforms, which gets the list of items under a `StorageReference` - Analytics: Add in `LogAppleTransaction` for logging Storekit 2 transactions on iOS. + - General (iOS): Added `-Wl,-weak-lswift_Concurrency` and `-D_LIBCPP_HAS_NO_VERBOSE_ABORT` flags to resolve Xcode 15+ launch crashes on iOS 15 and 16. ### 13.5.0 - Changes diff --git a/remote_config/integration_test/integration_test.xcodeproj/project.pbxproj b/remote_config/integration_test/integration_test.xcodeproj/project.pbxproj index 632c12c670..73c61f851b 100644 --- a/remote_config/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/remote_config/integration_test/integration_test.xcodeproj/project.pbxproj @@ -375,6 +375,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -418,6 +420,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -455,6 +459,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -487,6 +493,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -518,6 +526,8 @@ BC1D665F2668D10A005DC2DA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -572,6 +582,8 @@ BC1D66602668D10A005DC2DA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/setup_integration_tests.py b/setup_integration_tests.py index f4f7cd5869..e9bba2229e 100755 --- a/setup_integration_tests.py +++ b/setup_integration_tests.py @@ -57,3 +57,18 @@ for src in FRAMEWORK_DIRECTORIES: print('Copying %s to %s' % (src, dest)) copy_tree(src, dest, update=1) + + # Workaround for Xcode 15 / Swift 5.10 Concurrency crash on iOS 15 and 16 + pbxproj_path = os.path.join(dest, "integration_test.xcodeproj", "project.pbxproj") + if os.path.exists(pbxproj_path): + with open(pbxproj_path, "r") as f: + pbx_content = f.read() + if "-Wl,-weak-lswift_Concurrency" not in pbx_content: + pbx_content = pbx_content.replace( + "buildSettings = {", + "buildSettings = {\n\t\t\t\tOTHER_CPLUSPLUSFLAGS = \"$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY\";\n\t\t\t\tOTHER_LDFLAGS = \"-Wl,-weak-lswift_Concurrency\";" + ) + with open(pbxproj_path, "w") as f: + f.write(pbx_content) + print("Patched " + pbxproj_path + " for Swift Concurrency backwards compatibility.") + diff --git a/storage/integration_test/integration_test.xcodeproj/project.pbxproj b/storage/integration_test/integration_test.xcodeproj/project.pbxproj index 4d0bde1f79..eaf61e41d1 100644 --- a/storage/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/storage/integration_test/integration_test.xcodeproj/project.pbxproj @@ -386,6 +386,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -429,6 +431,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -466,6 +470,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -499,6 +505,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -531,6 +539,8 @@ BC1D669F2679868B005DC2DA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; @@ -588,6 +598,8 @@ BC1D66A02679868B005DC2DA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CLANG_ANALYZER_NONNULL = YES; diff --git a/testing/sample_framework/src/app_framework.cc b/testing/sample_framework/src/app_framework.cc index bed0d01526..c432cf3c84 100644 --- a/testing/sample_framework/src/app_framework.cc +++ b/testing/sample_framework/src/app_framework.cc @@ -15,6 +15,9 @@ #include "app_framework.h" // NOLINT #include +#include +#include +#include #include #include @@ -23,6 +26,24 @@ #include #include +#if defined(__APPLE__) +// Workaround for Xcode 15 / Swift 5.10 Concurrency and C++ verbose abort +// crash on older iOS versions (iOS 15/16). +// By providing these symbols in our own binary, we prevent dyld from +// crashing when they are missing from the system libraries on older OSs. +namespace std { +inline namespace __1 { +__attribute__((weak)) void __libcpp_verbose_abort(const char* format, ...) { + va_list list; + va_start(list, format); + vfprintf(stderr, format, list); + va_end(list); + abort(); +} +} // namespace __1 +} // namespace std +#endif + namespace app_framework { // Base logging methods, implemented by platform-specific files. diff --git a/testing/sample_framework/src/empty.swift b/testing/sample_framework/src/empty.swift index 97e8fbb973..e1cb622251 100644 --- a/testing/sample_framework/src/empty.swift +++ b/testing/sample_framework/src/empty.swift @@ -13,13 +13,3 @@ // limitations under the License. // This empty Swift file is needed to ensure the Swift runtime is included. -// along with forcing the swift async libraries to be linked on older versions of iOS/tvOS - -import Foundation - -// This dummy async function forces Xcode to automatically link the -// Swift Concurrency backwards-compatibility libraries (libswift_Concurrency) -// on older iOS versions (iOS 15/16). -@available(iOS 13.0, tvOS 13.0, macOS 10.15, watchOS 6.0, *) -func _firebase_sdk_dummy_async_func() async { -} diff --git a/ump/integration_test/integration_test.xcodeproj/project.pbxproj b/ump/integration_test/integration_test.xcodeproj/project.pbxproj index 6b7651922e..8a4c20e749 100644 --- a/ump/integration_test/integration_test.xcodeproj/project.pbxproj +++ b/ump/integration_test/integration_test.xcodeproj/project.pbxproj @@ -214,6 +214,8 @@ 529226F71C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -257,6 +259,8 @@ 529226F81C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -294,6 +298,8 @@ 529226FA1C85F68000C89379 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; @@ -327,6 +333,8 @@ 529226FB1C85F68000C89379 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + OTHER_CPLUSPLUSFLAGS = "$(inherited) -D_LIBCPP_HAS_NO_VERBOSE_ABORT -D_LIBCPP_DISABLE_AVAILABILITY"; + OTHER_LDFLAGS = "$(inherited) -Wl,-weak-lswift_Concurrency"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES;