diff --git a/CMakeLists.txt b/CMakeLists.txt index 70a503371e..d6a71dffb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,6 +107,12 @@ if(FIREBASE_CPP_BUILD_TESTS) ${CMAKE_BINARY_DIR}) endif() +if (PLATFORM STREQUAL TVOS OR PLATFORM STREQUAL SIMULATOR_TVOS) + # AdMob, FDL are not supported on tvOS. + set(FIREBASE_INCLUDE_ADMOB OFF) + set(FIREBASE_INCLUDE_DYNAMIC_LINKS OFF) +endif() + # Occasionally ANDROID is not being set correctly when invoked by gradle, so # set it manually if ANDROID_NDK has been defined. if(DEFINED ANDROID_NDK) diff --git a/admob/src/common/banner_view_internal.cc b/admob/src/common/banner_view_internal.cc index 85e6b2bdf2..e767abf8cc 100644 --- a/admob/src/common/banner_view_internal.cc +++ b/admob/src/common/banner_view_internal.cc @@ -24,11 +24,12 @@ #if FIREBASE_PLATFORM_ANDROID #include "admob/src/android/banner_view_internal_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "admob/src/ios/banner_view_internal_ios.h" #else #include "admob/src/stub/banner_view_internal_stub.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace admob { @@ -40,11 +41,12 @@ BannerViewInternal::BannerViewInternal(BannerView* base) BannerViewInternal* BannerViewInternal::CreateInstance(BannerView* base) { #if FIREBASE_PLATFORM_ANDROID return new BannerViewInternalAndroid(base); -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS return new BannerViewInternalIOS(base); #else return new BannerViewInternalStub(base); -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS } void BannerViewInternal::SetListener(BannerView::Listener* listener) { diff --git a/admob/src/common/interstitial_ad_internal.cc b/admob/src/common/interstitial_ad_internal.cc index b94b90c4d2..8626c5395f 100644 --- a/admob/src/common/interstitial_ad_internal.cc +++ b/admob/src/common/interstitial_ad_internal.cc @@ -24,11 +24,12 @@ #if FIREBASE_PLATFORM_ANDROID #include "admob/src/android/interstitial_ad_internal_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "admob/src/ios/interstitial_ad_internal_ios.h" #else #include "admob/src/stub/interstitial_ad_internal_stub.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace admob { @@ -41,11 +42,12 @@ InterstitialAdInternal* InterstitialAdInternal::CreateInstance( InterstitialAd* base) { #if FIREBASE_PLATFORM_ANDROID return new InterstitialAdInternalAndroid(base); -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS return new InterstitialAdInternalIOS(base); #else return new InterstitialAdInternalStub(base); -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS } void InterstitialAdInternal::SetListener(InterstitialAd::Listener* listener) { diff --git a/admob/src/common/native_express_ad_view_internal.cc b/admob/src/common/native_express_ad_view_internal.cc index b1fedcc6f6..f4464701b2 100644 --- a/admob/src/common/native_express_ad_view_internal.cc +++ b/admob/src/common/native_express_ad_view_internal.cc @@ -24,11 +24,12 @@ #if FIREBASE_PLATFORM_ANDROID #include "admob/src/android/native_express_ad_view_internal_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "admob/src/ios/native_express_ad_view_internal_ios.h" #else #include "admob/src/stub/native_express_ad_view_internal_stub.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace admob { @@ -44,11 +45,12 @@ NativeExpressAdViewInternal* NativeExpressAdViewInternal::CreateInstance( NativeExpressAdView* base) { #if FIREBASE_PLATFORM_ANDROID return new NativeExpressAdViewInternalAndroid(base); -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS return new NativeExpressAdViewInternalIOS(base); #else return new NativeExpressAdViewInternalStub(base); -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS } void NativeExpressAdViewInternal::SetListener( diff --git a/admob/src/common/rewarded_video_internal.cc b/admob/src/common/rewarded_video_internal.cc index 064fdfc12d..4c0ee2fb37 100644 --- a/admob/src/common/rewarded_video_internal.cc +++ b/admob/src/common/rewarded_video_internal.cc @@ -24,11 +24,12 @@ #if FIREBASE_PLATFORM_ANDROID #include "admob/src/android/rewarded_video_internal_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "admob/src/ios/rewarded_video_internal_ios.h" #else #include "admob/src/stub/rewarded_video_internal_stub.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace admob { @@ -41,11 +42,12 @@ RewardedVideoInternal::RewardedVideoInternal() RewardedVideoInternal* RewardedVideoInternal::CreateInstance() { #if FIREBASE_PLATFORM_ANDROID return new RewardedVideoInternalAndroid(); -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS return new RewardedVideoInternalIOS(); #else return new RewardedVideoInternalStub(); -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS } void RewardedVideoInternal::SetListener(Listener* listener) { diff --git a/admob/src/include/firebase/admob/types.h b/admob/src/include/firebase/admob/types.h index d1e3d28e75..e8f6af73ce 100644 --- a/admob/src/include/firebase/admob/types.h +++ b/admob/src/include/firebase/admob/types.h @@ -21,11 +21,12 @@ #if FIREBASE_PLATFORM_ANDROID #include -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS extern "C" { #include } // extern "C" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace admob { @@ -40,13 +41,14 @@ namespace admob { #if FIREBASE_PLATFORM_ANDROID /// An Android Activity from Java. typedef jobject AdParent; -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS /// A pointer to an iOS UIView. typedef id AdParent; #else /// A void pointer for stub classes. typedef void *AdParent; -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS #ifdef INTERNAL_EXPERIMENTAL // LINT.IfChange diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 40b3edb68d..6624a5db78 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -156,6 +156,14 @@ set(app_ios_SRCS src/invites/ios/invites_receiver_internal_ios.mm src/invites/ios/invites_ios_startup.mm src/uuid_ios_darwin.mm) +if (PLATFORM STREQUAL TVOS OR PLATFORM STREQUAL SIMULATOR_TVOS) + # TVOS does not have a web browser and does not support dynamic links. + # Remove these files if we are building for TVOS. + list(REMOVE_ITEM app_ios_SRCS + src/invites/ios/invites_receiver_internal_ios.mm + src/invites/ios/invites_ios_startup.mm) +endif() + set(app_desktop_SRCS src/app_desktop.cc src/heartbeat_date_storage_desktop.cc diff --git a/app/src/app_common.cc b/app/src/app_common.cc index 733d3127c5..f670536180 100644 --- a/app/src/app_common.cc +++ b/app/src/app_common.cc @@ -90,6 +90,8 @@ const char* kCpuArchitecture = "arm32"; const char* kCppRuntimeOrStl = "libcpp"; #if FIREBASE_PLATFORM_IOS const char* kOperatingSystem = "ios"; +#elif FIREBASE_PLATFORM_TVOS +const char* kOperatingSystem = "tvos"; #elif FIREBASE_PLATFORM_OSX const char* kOperatingSystem = "darwin"; #else diff --git a/app/src/include/firebase/app.h b/app/src/include/firebase/app.h index db4d8b91a3..ccdca72d64 100644 --- a/app/src/include/firebase/app.h +++ b/app/src/include/firebase/app.h @@ -26,7 +26,7 @@ #include #include -#if FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #ifdef __OBJC__ @class FIRApp; #endif // __OBJC__ @@ -718,14 +718,14 @@ class App { /// @return Global reference to the FirebaseApp. The returned reference /// most be deleted after use. jobject GetPlatformApp() const; -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #ifdef __OBJC__ /// Get the platform specific app implementation referenced by this object. /// /// @return Reference to the FIRApp object owned by this app. FIRApp* GetPlatformApp() const; #endif // __OBJC__ -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, FIREBASE_PLATFORM_TVOS #endif // INTERNAL_EXPERIMENTAL private: diff --git a/app/src/include/firebase/internal/platform.h b/app/src/include/firebase/internal/platform.h index e2518195ae..687a7e66f7 100644 --- a/app/src/include/firebase/internal/platform.h +++ b/app/src/include/firebase/internal/platform.h @@ -36,6 +36,7 @@ #define FIREBASE_PLATFORM_ANDROID 0 #define FIREBASE_PLATFORM_IOS 0 +#define FIREBASE_PLATFORM_TVOS 0 #define FIREBASE_PLATFORM_OSX 0 #define FIREBASE_PLATFORM_WINDOWS 0 #define FIREBASE_PLATFORM_LINUX 0 @@ -51,6 +52,9 @@ #elif defined(TARGET_OS_IOS) && TARGET_OS_IOS #undef FIREBASE_PLATFORM_IOS #define FIREBASE_PLATFORM_IOS 1 +#elif defined(TARGET_OS_TV) && TARGET_OS_TV +#undef FIREBASE_PLATFORM_TVOS +#define FIREBASE_PLATFORM_TVOS 1 #elif defined(TARGET_OS_OSX) && TARGET_OS_OSX #undef FIREBASE_PLATFORM_OSX #define FIREBASE_PLATFORM_OSX 1 diff --git a/app/src/locale.cc b/app/src/locale.cc index cbdc4ddfdd..c007208cef 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -19,7 +19,7 @@ #include "app/src/include/firebase/internal/platform.h" #include "app/src/log.h" -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #error "This file does not support iOS and OS X, use locale_apple.mm instead." #elif FIREBASE_PLATFORM_ANDROID #error "This file is not support on Android." diff --git a/app/src/semaphore.h b/app/src/semaphore.h index 1858046204..b3d4ecdc64 100644 --- a/app/src/semaphore.h +++ b/app/src/semaphore.h @@ -36,10 +36,11 @@ #include -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "app/src/mutex.h" #include "app/src/pthread_condvar.h" -#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS #if !defined(FIREBASE_NAMESPACE) #define FIREBASE_NAMESPACE firebase @@ -50,7 +51,7 @@ namespace FIREBASE_NAMESPACE { class Semaphore { public: explicit Semaphore(int initial_count) { -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // MacOS requires named semaphores, and does not support unnamed. // Generate a unique string for the semaphore name: static const char kPrefix[] = "/firebase-"; @@ -94,7 +95,7 @@ class Semaphore { } ~Semaphore() { -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // Because we use named semaphores on MacOS, we need to close them. bool success = (sem_close(semaphore_) == 0); assert(success); @@ -110,9 +111,10 @@ class Semaphore { } void Post() { -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS MutexLock lock(cond_mutex_); -#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS #if !FIREBASE_PLATFORM_WINDOWS bool success = (sem_post(semaphore_) == 0); @@ -124,10 +126,11 @@ class Semaphore { (void)success; #endif -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // Notify any potential timedWait calls that are waiting for this. cond_.NotifyAll(); -#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS } void Wait() { @@ -164,7 +167,7 @@ class Semaphore { // before returning. // Returns false if it was unable to acquire a lock, true otherwise. bool TimedWait(int milliseconds) { -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS MutexLock lock(cond_mutex_); return cond_.TimedWait( cond_mutex_.native_handle(), [this] { return this->TryWait(); }, @@ -184,14 +187,15 @@ class Semaphore { HANDLE semaphore_; #endif -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // Apple implementations need a condition variable to make TimedWait() work. Mutex cond_mutex_; internal::ConditionVariable cond_; #elif !FIREBASE_PLATFORM_WINDOWS // On non-Mac POSIX systems, we keep our own sem_t object. sem_t semaphore_value_; -#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS }; // NOLINTNEXTLINE - allow namespace overridden diff --git a/app/src/time.h b/app/src/time.h index 19a51d4d95..6acc7ffce3 100644 --- a/app/src/time.h +++ b/app/src/time.h @@ -29,10 +29,11 @@ #include #endif // FIREBASE_PLATFORM_WINDOWS -#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include #include -#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS #if !defined(FIREBASE_NAMESPACE) #define FIREBASE_NAMESPACE firebase @@ -124,10 +125,10 @@ inline uint64_t GetTimestamp() { #if FIREBASE_PLATFORM_WINDOWS // return the elapse time since the system is started in milliseconds return GetTickCount64(); -#elif FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // clock_gettime is only supported on macOS after 10.10 Sierra. // mach_absolute_time() returns absolute time in nano seconds. -#if FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // Note that the same function does NOT return nano seconds in iOS. Requires // mach_timebase_info_data_t to convert returned value into nano seconds. // However, the conversion may have potential risk to introduce overflow or diff --git a/app/tests/app_test.cc b/app/tests/app_test.cc index c1c3c0bceb..ad60202f22 100644 --- a/app/tests/app_test.cc +++ b/app/tests/app_test.cc @@ -59,7 +59,7 @@ #include "TargetConditionals.h" #endif // __APPLE__ -#if FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // Declared in the Obj-C header fake/FIRApp.h. extern "C" { void FIRAppCreateUsingDefaultOptions(const char* name); @@ -106,7 +106,7 @@ class AppTest : public ::testing::Test { // Create a mobile app instance using the fake options from resources. void CreateMobileApp(const char* name) { -#if FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS FIRAppCreateUsingDefaultOptions(name ? name : "__FIRAPP_DEFAULT"); #endif // FIREBASE_PLATFORM_IOS #if FIREBASE_ANDROID_FOR_DESKTOP @@ -146,7 +146,7 @@ class AppTest : public ::testing::Test { // Clear all C++ firebase::App objects and any mobile SDK instances. void ClearAppInstances() { app_common::DestroyAllApps(); -#if FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS FIRAppResetApps(); #endif // FIREBASE_PLATFORM_IOS #if FIREBASE_ANDROID_FOR_DESKTOP @@ -241,7 +241,7 @@ TEST_F(AppTest, LoadDefault) { EXPECT_STREQ("fake messaging sender id from resource", options.messaging_sender_id()); EXPECT_STREQ("fake database url from resource", options.database_url()); -#if FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS // GA tracking ID can currently only be configured on iOS. EXPECT_STREQ("fake ga tracking id from resource", options.ga_tracking_id()); #endif // FIREBASE_PLATFORM_IOS diff --git a/auth/src/ios/credential_ios.mm b/auth/src/ios/credential_ios.mm index e518f59310..aeb899a0e4 100644 --- a/auth/src/ios/credential_ios.mm +++ b/auth/src/ios/credential_ios.mm @@ -27,9 +27,16 @@ #import "FIRGitHubAuthProvider.h" #import "FIRGoogleAuthProvider.h" #import "FIROAuthProvider.h" + +#if FIREBASE_PLATFORM_IOS +// PhoneAuth is not supported on non-iOS Apple platforms (eg: tvOS). +// We are using stub implementation for these platforms (just like on desktop). #import "FIRPhoneAuthProvider.h" +#endif //FIREBASE_PLATFORM_IOS + #import "FIRTwitterAuthProvider.h" +#if FIREBASE_PLATFORM_IOS // This object is shared between the PhoneAuthProvider::Listener and the blocks in // @ref VerifyPhoneNumber. It exists for as long as one of those two lives. We use Objective-C // for reference counting. @@ -46,10 +53,13 @@ @interface PhoneListenerDataObjC : NSObject { @end @implementation PhoneListenerDataObjC @end +#endif //FIREBASE_PLATFORM_IOS namespace firebase { namespace auth { +static const char* kMockVerificationId = "PhoneAuth not supported on this platform"; + using util::StringFromNSString; Credential::~Credential() { @@ -207,7 +217,7 @@ @implementation PhoneListenerDataObjC /** Linking GameKit.framework without using it on macOS results in App Store rejection. Thus we don't link GameKit.framework to our SDK directly. `optionalLocalPlayer` is used for - checking whether the APP that consuming our SDK has linked GameKit.framework. If not, + checking whether the APP that consuming our SDK has linked GameKit.framework. If not, early out. **/ GKLocalPlayer *_Nullable optionalLocalPlayer = [[NSClassFromString(@"GKLocalPlayer") alloc] init]; @@ -233,6 +243,7 @@ @implementation PhoneListenerDataObjC bool PhoneAuthProvider::ForceResendingToken::operator!=( const ForceResendingToken&) const { return false; } +#if FIREBASE_PLATFORM_IOS // This implementation of PhoneListenerData is specific to iOS. struct PhoneListenerData { // Hold the reference-counted ObjC structure. This structure is shared by the blocks in @@ -244,7 +255,12 @@ @implementation PhoneListenerDataObjC data_->objc = [[PhoneListenerDataObjC alloc] init]; data_->objc->active_listener = this; } +#else // non-iOS Apple platforms (eg: tvOS) +// Stub for tvOS and other non-iOS apple platforms. +PhoneAuthProvider::Listener::Listener() : data_(nullptr) {} +#endif // FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS PhoneAuthProvider::Listener::~Listener() { // Wait while the Listener is being used (in the callbacks in VerifyPhoneNumber). // Then reset the active_listener so that callbacks become no-ops. @@ -255,7 +271,11 @@ @implementation PhoneListenerDataObjC data_->objc = nil; delete data_; } +#else // non-iOS Apple platforms (eg: tvOS) +PhoneAuthProvider::Listener::~Listener() {} +#endif // FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS // This implementation of PhoneAuthProviderData is specific to iOS. struct PhoneAuthProviderData { public: @@ -265,10 +285,17 @@ explicit PhoneAuthProviderData(FIRPhoneAuthProvider* objc_provider) // The wrapped provider in Objective-C. FIRPhoneAuthProvider* objc_provider; }; +#endif // FIREBASE_PLATFORM_IOS PhoneAuthProvider::PhoneAuthProvider() : data_(nullptr) {} + +#if FIREBASE_PLATFORM_IOS PhoneAuthProvider::~PhoneAuthProvider() { delete data_; } +#else // non-iOS Apple platforms (eg: tvOS) +PhoneAuthProvider::~PhoneAuthProvider() {} +#endif // FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS void PhoneAuthProvider::VerifyPhoneNumber( const char* phone_number, uint32_t /*auto_verify_time_out_ms*/, const ForceResendingToken* /*force_resending_token*/, Listener* listener) { @@ -303,7 +330,24 @@ explicit PhoneAuthProviderData(FIRPhoneAuthProvider* objc_provider) } } } +#else // non-iOS Apple platforms (eg: tvOS) +void PhoneAuthProvider::VerifyPhoneNumber( + const char* /*phone_number*/, uint32_t /*auto_verify_time_out_ms*/, + const ForceResendingToken* force_resending_token, Listener* listener) { + FIREBASE_ASSERT_RETURN_VOID(listener != nullptr); + + // Mock the tokens by sending a new one whenever it's unspecified. + ForceResendingToken token; + if (force_resending_token != nullptr) { + token = *force_resending_token; + } + + listener->OnCodeAutoRetrievalTimeOut(kMockVerificationId); + listener->OnCodeSent(kMockVerificationId, token); +} +#endif // FIREBASE_PLATFORM_IOS +#if FIREBASE_PLATFORM_IOS Credential PhoneAuthProvider::GetCredential(const char* verification_id, const char* verification_code) { FIREBASE_ASSERT_RETURN(Credential(), verification_id && verification_code); @@ -312,7 +356,17 @@ explicit PhoneAuthProviderData(FIRPhoneAuthProvider* objc_provider) verificationCode:@(verification_code)]; return Credential(new FIRAuthCredentialPointer((FIRAuthCredential*)credential)); } +#else // non-iOS Apple platforms (eg: tvOS) +Credential PhoneAuthProvider::GetCredential(const char* verification_id, + const char* verification_code) { + FIREBASE_ASSERT_MESSAGE_RETURN(Credential(nullptr), false, + "Phone Auth is not supported on non iOS Apple platforms (eg:tvOS)."); + return Credential(nullptr); +} +#endif // FIREBASE_PLATFORM_IOS + +#if FIREBASE_PLATFORM_IOS // static PhoneAuthProvider& PhoneAuthProvider::GetInstance(Auth* auth) { PhoneAuthProvider& provider = auth->auth_data_->phone_auth_provider; @@ -325,6 +379,12 @@ explicit PhoneAuthProviderData(FIRPhoneAuthProvider* objc_provider) } return provider; } +#else // non-iOS Apple platforms (eg: tvOS) +// static +PhoneAuthProvider& PhoneAuthProvider::GetInstance(Auth* auth) { + return auth->auth_data_->phone_auth_provider; +} +#endif // FIREBASE_PLATFORM_IOS // FederatedAuthHandlers FederatedOAuthProvider::FederatedOAuthProvider() { } @@ -420,6 +480,7 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl ReferenceCountedFutureImpl &futures = auth_data->future_impl; auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider, SignInResult()); + #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) auth:AuthImpl(auth_data)]; @@ -442,6 +503,13 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl SignInResult()); return future; } + + #else // non-iOS Apple platforms (eg: tvOS) + Future future = MakeFuture(&futures, handle); + futures.Complete(handle, kAuthErrorApiNotAvailable, + "OAuth provider linking is not supported on non-iOS Apple platforms."); + #endif // FIREBASE_PLATFORM_IOS + } Future FederatedOAuthProvider::Reauthenticate(AuthData* auth_data) { @@ -449,6 +517,7 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl ReferenceCountedFutureImpl &futures = auth_data->future_impl; auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider, SignInResult()); + #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) auth:AuthImpl(auth_data)]; @@ -471,6 +540,12 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl SignInResult()); return future; } + + #else // non-iOS Apple platforms (eg: tvOS) + Future future = MakeFuture(&futures, handle); + futures.Complete(handle, kAuthErrorApiNotAvailable, + "OAuth reauthentication is not supported on non-iOS Apple platforms."); + #endif // FIREBASE_PLATFORM_IOS } } // namespace auth diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index 090ff2d1e1..ccbe470199 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -14,11 +14,13 @@ * limitations under the License. */ -#import "FIRPhoneAuthCredential.h" - #include "app/src/time.h" #include "auth/src/ios/common_ios.h" +#if FIREBASE_PLATFORM_IOS +#import "FIRPhoneAuthCredential.h" +#endif + namespace firebase { namespace auth { @@ -229,6 +231,8 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { } ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential); + + #if FIREBASE_PLATFORM_IOS FIRAuthCredential *objc_credential = CredentialFromImpl(credential.impl_); if ([objc_credential isKindOfClass:[FIRPhoneAuthCredential class]]) { [UserImpl(auth_data_) @@ -240,6 +244,12 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { } else { futures.Complete(handle, kAuthErrorInvalidCredential, kInvalidCredentialMessage); } + + #else // non iOS Apple platforms (eg: tvOS). + futures.Complete(handle, kAuthErrorApiNotAvailable, + "Phone Auth is not supported on non-iOS apple platforms."); + #endif // FIREBASE_PLATFORM_IOS + return MakeFuture(&futures, handle); } diff --git a/auth/tests/auth_test.cc b/auth/tests/auth_test.cc index 6d77133cd3..e14778a32b 100644 --- a/auth/tests/auth_test.cc +++ b/auth/tests/auth_test.cc @@ -69,10 +69,12 @@ template void Verify(const AuthError error, const Future& result, bool check_result_not_null) { // Desktop stub returns result immediately and thus we skip the ticker elapse. -#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || \ + FIREBASE_PLATFORM_TVOS EXPECT_EQ(firebase::kFutureStatusPending, result.status()); firebase::testing::cppsdk::TickerElapse(); -#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS MaybeWaitForFuture(result); EXPECT_EQ(firebase::kFutureStatusComplete, result.status()); EXPECT_EQ(error, result.error()); @@ -351,7 +353,8 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordSucceeded) { // Right now the desktop stub always succeeded. We could potentially test it by // adding a desktop fake, which does not provide much value for the specific // case of Auth since the C++ code is only a thin wraper. -#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || \ + FIREBASE_PLATFORM_TVOS TEST_F(AuthTest, TestSignInWithCustomTokenFailed) { firebase::testing::cppsdk::ConfigSet( @@ -471,7 +474,8 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordFailed) { Verify(kAuthErrorEmailAlreadyInUse, result); } -#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS TEST_F(AuthTest, TestCurrentUserAndSignOut) { // Here we let mock sign-in-anonymously succeed immediately (ticker = 0). @@ -534,7 +538,8 @@ TEST_F(AuthTest, TestSendPasswordResetEmailSucceeded) { Verify(kAuthErrorNone, result); } -#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || \ + FIREBASE_PLATFORM_TVOS TEST_F(AuthTest, TestSendPasswordResetEmailFailed) { firebase::testing::cppsdk::ConfigSet( "{" @@ -557,7 +562,8 @@ TEST_F(AuthTest, TestSendPasswordResetEmailFailed) { Future result = firebase_auth_->SendPasswordResetEmail("my@email.com"); Verify(kAuthErrorInvalidMessagePayload, result); } -#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS } // namespace auth } // namespace firebase diff --git a/auth/tests/user_test.cc b/auth/tests/user_test.cc index 188e1a80b4..c2e9176837 100644 --- a/auth/tests/user_test.cc +++ b/auth/tests/user_test.cc @@ -202,10 +202,12 @@ class UserTest : public ::testing::Test { template static void Verify(const Future result) { // Fake Android & iOS implemented the delay. Desktop stub completed immediately. -#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || \ + FIREBASE_PLATFORM_TVOS EXPECT_EQ(firebase::kFutureStatusPending, result.status()); firebase::testing::cppsdk::TickerElapse(); -#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS MaybeWaitForFuture(result); EXPECT_EQ(firebase::kFutureStatusComplete, result.status()); EXPECT_EQ(0, result.error()); @@ -274,11 +276,13 @@ TEST_F(UserTest, TestUpdateEmail) { Future result = firebase_user_->UpdateEmail("new@email.com"); // Fake Android & iOS implemented the delay. Desktop stub completed immediately. -#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || \ + FIREBASE_PLATFORM_TVOS EXPECT_EQ(firebase::kFutureStatusPending, result.status()); EXPECT_NE("new@email.com", firebase_user_->email()); firebase::testing::cppsdk::TickerElapse(); -#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS MaybeWaitForFuture(result); EXPECT_EQ(firebase::kFutureStatusComplete, result.status()); EXPECT_EQ(0, result.error()); @@ -519,15 +523,18 @@ TEST_F(UserTest, TestIsAnonymous) { TEST_F(UserTest, TestGetter) { // Test getter functions. The fake value are different between stub and fake. -#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#if defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || \ + FIREBASE_PLATFORM_TVOS EXPECT_EQ("fake email", firebase_user_->email()); EXPECT_EQ("fake display name", firebase_user_->display_name()); EXPECT_EQ("fake provider id", firebase_user_->provider_id()); -#else // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#else // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS EXPECT_TRUE(firebase_user_->email().empty()); EXPECT_TRUE(firebase_user_->display_name().empty()); EXPECT_EQ("Firebase", firebase_user_->provider_id()); -#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS +#endif // defined(FIREBASE_ANDROID_FOR_DESKTOP) || FIREBASE_PLATFORM_IOS || + // FIREBASE_PLATFORM_TVOS EXPECT_FALSE(firebase_user_->uid().empty()); EXPECT_TRUE(firebase_user_->photo_url().empty()); diff --git a/build_scripts/tvos/Info.plist b/build_scripts/tvos/Info.plist new file mode 100644 index 0000000000..6a3da3b0a1 --- /dev/null +++ b/build_scripts/tvos/Info.plist @@ -0,0 +1,39 @@ + + + + + AvailableLibraries + + + LibraryIdentifier + tvos-x86_64-simulator + LibraryPath + LIBRARY_PATH + SupportedArchitectures + + x86_64 + + SupportedPlatform + tvos + SupportedPlatformVariant + simulator + + + LibraryIdentifier + tvos-arm64 + LibraryPath + LIBRARY_PATH + SupportedArchitectures + + arm64 + + SupportedPlatform + tvos + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/build_scripts/tvos/build.sh b/build_scripts/tvos/build.sh new file mode 100755 index 0000000000..159d2015a2 --- /dev/null +++ b/build_scripts/tvos/build.sh @@ -0,0 +1,257 @@ +#!/bin/bash -e +# +# Script to build iOS XCFrameworks +# If built for all architectures (arm64 x86_64), +# it will build universal framework as well +# + +usage(){ + echo "Usage: $0 [options] + options: + -b, build path default: tvos_build + -s, source path default: . + -p, framework platform default: ${SUPPORTED_PLATFORMS[@]} + -a, framework architecture default: ${SUPPORTED_ARCHITECTURES[@]} + -t, CMake target default: ${SUPPORTED_TARGETS[@]} + -g, generate Makefiles default: true + -c, CMake build default: true + example: + build_scripts/tvos/build.sh -b tvos_build -s . -a arm64,x86_64 -t firebase_admob,firebase_auth -c false" +} + +set -e + +readonly SUPPORTED_PLATFORMS=(device simulator) +readonly SUPPORTED_ARCHITECTURES=(arm64 x86_64) +readonly DEVICE_ARCHITECTURES=(arm64) +readonly SIMULATOR_ARCHITECTURES=(x86_64) +readonly SUPPORTED_TARGETS=(firebase_analytics firebase_auth firebase_database firebase_firestore firebase_functions firebase_installations firebase_messaging firebase_remote_config firebase_storage) + +# build default value +buildpath="tvos_build" +sourcepath="." +platforms=("${SUPPORTED_PLATFORMS[@]}") +architectures=("${SUPPORTED_ARCHITECTURES[@]}") +targets=("${SUPPORTED_TARGETS[@]}") +generateMakefiles=true +cmakeBuild=true + +# check options +IFS=',' # split options on ',' characters +while getopts ":b:s:a:t:g:ch" opt; do + case $opt in + h) + usage + exit 0 + ;; + b) + buildpath=$OPTARG + ;; + s) + sourcepath=$OPTARG + if [[ ! -d "${sourcepath}" ]]; then + echo "Source path ${sourcepath} not found." + exit 2 + fi + ;; + p) + platforms=($OPTARG) + for platform in ${platforms[@]}; do + if [[ ! " ${SUPPORTED_PLATFORMS[@]} " =~ " ${platform} " ]]; then + echo "invalid platform: ${platform}" + echo "Supported platforms are: ${SUPPORTED_PLATFORMS[@]}" + exit 2 + fi + done + ;; + a) + architectures=($OPTARG) + for arch in ${architectures[@]}; do + if [[ ! " ${SUPPORTED_ARCHITECTURES[@]} " =~ " ${arch} " ]]; then + echo "invalid architecture: ${arch}" + echo "Supported architectures are: ${SUPPORTED_ARCHITECTURES[@]}" + exit 2 + fi + done + ;; + t) + targets=($OPTARG) + for t in ${targets[@]}; do + if [[ ! " ${SUPPORTED_TARGETS[@]} " =~ " ${t} " ]]; then + echo "invalid target: ${t}" + echo "Supported targets are: ${SUPPORTED_TARGETS[@]}" + exit 2 + fi + done + ;; + g) + if [[ $OPTARG == true ]]; then + generateMakefiles=true + else + generateMakefiles=false + fi + ;; + c) + if [[ $OPTARG == true ]]; then + cmakeBuild=true + else + cmakeBuild=false + fi + ;; + *) + echo "unknown parameter" + exit 2 + ;; + esac +done +echo "build path: ${buildpath}" +echo "source path: ${sourcepath}" +echo "build platforms: ${platforms[@]}" +echo "build architectures: ${architectures[@]}" +echo "build targets: ${targets[@]}" +echo "generate Makefiles: ${generateMakefiles}" +echo "CMake Build: ${cmakeBuild}" +sourcepath=$(cd ${sourcepath} && pwd) #full path +buildpath=$(mkdir -p ${buildpath} && cd ${buildpath} && pwd) #full path + +# generate Makefiles for each architecture and target +frameworkspath="frameworks/tvos" +tvos_toolchain_platform="TVOS" +if ${generateMakefiles}; then + for platform in ${platforms[@]}; do + for arch in ${architectures[@]}; do + if [[ "${platform}" == "device" && " ${DEVICE_ARCHITECTURES[@]} " =~ " ${arch} " ]]; then + toolchain="cmake/toolchains/apple.toolchain.cmake" + elif [[ "${platform}" == "simulator" && " ${SIMULATOR_ARCHITECTURES[@]} " =~ " ${arch} " ]]; then + toolchain="cmake/toolchains/apple.toolchain.cmake" + tvos_toolchain_platform="SIMULATOR_TVOS" + else + continue + fi + + echo "generate Makefiles start" + mkdir -p ${buildpath}/tvos_build_file/${platform}-${arch} && cd ${buildpath}/tvos_build_file/${platform}-${arch} + cmake -DCMAKE_TOOLCHAIN_FILE=${sourcepath}/${toolchain} \ + -DPLATFORM=${tvos_toolchain_platform} \ + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${buildpath}/${frameworkspath}/${platform}-${arch} \ + ${sourcepath} + echo "generate Makefiles end" + done + done +fi + +# build framework for each architecture and target +IFS=$'\n' # split $(ls) on \n characters +if ${cmakeBuild}; then + for platform in ${platforms[@]}; do + for arch in ${architectures[@]}; do + if [ -d "${buildpath}/tvos_build_file/${platform}-${arch}" ]; then + { + cd ${buildpath}/tvos_build_file/${platform}-${arch} + echo "build ${platform} ${arch} ${targets[@]} framework start" + cmake --build . --target ${targets[@]} + echo "build ${platform} ${arch} ${targets[@]} framework end" + + } & + fi + done + done + subprocess_fail=0 + for job in $(jobs -p); do + wait $job || let "subprocess_fail+=1" + done + if [ "${subprocess_fail}" == "0" ]; then + echo "frameworks build end" + else + echo "frameworks build error, ${subprocess_fail} architecture(s) build failed" + exit 2 + fi + + # arrange the framework + cd ${buildpath}/${frameworkspath} + for platform in ${platforms[@]}; do + for arch in ${architectures[@]}; do + if [[ ! -d "${platform}-${arch}" ]]; then + continue + fi + + # rename firebase_app to firebase + if [[ ! -d "${platform}-${arch}/firebase.framework" ]]; then + mv ${platform}-${arch}/firebase_app.framework ${platform}-${arch}/firebase.framework + mv ${platform}-${arch}/firebase.framework/firebase_app ${platform}-${arch}/firebase.framework/firebase + rm ${platform}-${arch}/firebase.framework/Info.plist + fi + + # delete useless Info.plist + for target in ${targets[@]}; do + if [[ -f "${platform}-${arch}/${target}.framework/Info.plist" ]]; then + rm ${platform}-${arch}/${target}.framework/Info.plist + fi + done + + # delete non-framework dir + for dir in $(ls ${platform}-${arch}); do + if [[ ! ${dir} =~ ".framework" ]]; then + rm -rf ${platform}-${arch}/${dir} + fi + done + done + done + + # if we built for all architectures (arm64 armv7 x86_64 i386) + # build universal framework as well + if [[ ${#architectures[@]} < ${#SUPPORTED_ARCHITECTURES[@]} ]]; then + exit 0 + fi + + targets+=('firebase') + for target in ${targets[@]}; do + mkdir -p universal/${target}.framework + libsubpath="${target}.framework/${target}" + lipo -create "device-arm64/${libsubpath}" \ + "simulator-x86_64/${libsubpath}" \ + -output "universal/${libsubpath}" + done + if [[ ! -d "universal/firebase.framework/Headers" ]]; then + cp -R device-arm64/firebase.framework/Headers universal/firebase.framework + fi + echo "universal frameworks build end & ready to use" + + # covert framework into xcframework + cd ${buildpath} + xcframeworkspath="xcframeworks" + mkdir -p ${xcframeworkspath} + # create library for xcframework + for platform in ${platforms[@]}; do + for target in ${targets[@]}; do + libsubpath="${target}.framework/${target}" + if [[ "${platform}" == "device" ]]; then + outputdir="${xcframeworkspath}/${target}.xcframework/tvos-arm64/${target}.framework" + mkdir -p ${outputdir} + lipo -create "${frameworkspath}/device-arm64/${libsubpath}" \ + -output "${outputdir}/${target}" + + elif [[ "${platform}" == "simulator" ]]; then + outputdir="${xcframeworkspath}/${target}.xcframework/tvos-x86_64-simulator/${target}.framework" + mkdir -p ${outputdir} + lipo -create "${frameworkspath}/simulator-x86_64/${libsubpath}" \ + -output "${outputdir}/${target}" + fi + done + done + + # create Info.plist for xcframework + for target in ${targets[@]}; do + cp ${sourcepath}/build_scripts/tvos/Info.plist ${xcframeworkspath}/${target}.xcframework + sed -i "" "s/LIBRARY_PATH/${target}.framework/" ${xcframeworkspath}/${target}.xcframework/Info.plist + done + + # create Headers for xcframework + if [[ ! -d "${xcframeworkspath}/firebase.xcframework/tvos-arm64/firebase.framework/Headers" ]]; then + cp -R ${frameworkspath}/device-arm64/firebase.framework/Headers \ + ${xcframeworkspath}/firebase.xcframework/tvos-arm64/firebase.framework/Headers + cp -R ${frameworkspath}/device-arm64/firebase.framework/Headers \ + ${xcframeworkspath}/firebase.xcframework/tvos-x86_64-simulator/firebase.framework/Headers + fi + echo "xcframeworks build end & ready to use" +fi diff --git a/build_scripts/tvos/install_prereqs.sh b/build_scripts/tvos/install_prereqs.sh new file mode 100755 index 0000000000..fd4fb41a77 --- /dev/null +++ b/build_scripts/tvos/install_prereqs.sh @@ -0,0 +1,44 @@ +#!/bin/bash -e + +if [[ $(uname) != "Darwin" ]]; then + echo "Unsupported platform, tvOS can only be build on a MacOS machine." + exit 1 +fi + +if [[ -z $(which cmake) ]]; then + echo "Error, cmake is not installed or is not in the PATH." + exit 1 +fi + +if [[ -z $(which python) ]]; then + echo "Error, python is not installed or is not in the PATH." + exit 1 +else + updated_pip=0 + if ! $(echo "import absl"$'\n'"import google.protobuf" | python - 2> /dev/null); then + echo "Installing python packages." + set -x + sudo python -m pip install --upgrade pip + pip install absl-py protobuf + set +x + fi +fi + +if [[ -z $(which xcodebuild) || -z $(which xcode-select) ]]; then + echo "Error, Xcode command line tools not installed." + exit 1 +fi + +if [[ -z $(xcode-select -p) || ! -d $(xcode-select -p) ]]; then + echo "Error, no Xcode version selected. Use 'xcode-select' to select one." + exit 1 +fi + +if [[ -z $(which pod) ]]; then + echo "Cocoapods not detected, installing..." + sudo gem install cocoapods +fi + +echo "Updating Cocoapods repo..." +pod repo update + diff --git a/build_scripts/tvos/package.sh b/build_scripts/tvos/package.sh new file mode 100755 index 0000000000..951ccc78e0 --- /dev/null +++ b/build_scripts/tvos/package.sh @@ -0,0 +1,66 @@ +#!/bin/bash -e +# +# Script to package tvOS SDK. +# + +usage(){ + echo "Usage: $0 +example: + build_scripts/tvos/package.sh tvos_build package_out" +} + +builtpath=$1 +packagepath=$2 + +if [[ -z "${builtpath}" || -z "${packagepath}" ]]; then + usage + exit 1 +fi + +if [[ ! -d "${builtpath}/xcframeworks" ]]; then + echo "Built tvOS SDK not found at path '${builtpath}'." + usage + exit 2 +fi + +root_dir=$(cd $(dirname $0)/../..; pwd -P) +. "${root_dir}/build_scripts/packaging.conf" + +origpath=$( pwd -P ) + +mkdir -p "${packagepath}" +cd "${packagepath}" +destpath=$( pwd -P ) +cd "${origpath}" + +cd "${builtpath}" +sourcepath=$( pwd -P ) +cd "${origpath}" + +# Copy xcframeworks into packaged SDK. +cd "${sourcepath}" +mkdir -p "${destpath}/xcframeworks" +# Make sure we only copy the xcframeworks in product_list (specified in packaging.conf) +for product in ${product_list[*]}; do + if [[ "${product}" == "app" ]]; then + framework_dir="firebase.xcframework" + else + framework_dir="firebase_${product}.xcframework" + fi + cp -R ${sourcepath}/xcframeworks/${framework_dir} ${destpath}/xcframeworks/ +done +cd "${origpath}" + +# Convert frameworks into libraries so we can provide both in the SDK. +cd "${sourcepath}" +for frameworkpath in frameworks/tvos/*/*.framework; do + libpath=$(echo "${frameworkpath}" | sed 's|^frameworks|libs|' | sed 's|\([^/]*\)\.framework$|lib\1.a|') + if [[ $(basename "${libpath}") == 'libfirebase.a' ]]; then + libpath=$(echo "${libpath}" | sed 's|libfirebase\.a|libfirebase_app.a|') + fi + + frameworkpath=$(echo "${frameworkpath}" | sed 's|\([^/]*\)\.framework$|\1.framework/\1|') + mkdir -p $(dirname "${destpath}/${libpath}") + cp -af "${sourcepath}/${frameworkpath}" "${destpath}/${libpath}" +done +cd "${origpath}" diff --git a/cmake/external_rules.cmake b/cmake/external_rules.cmake index a31c406208..8db0fcdac1 100644 --- a/cmake/external_rules.cmake +++ b/cmake/external_rules.cmake @@ -66,6 +66,7 @@ function(download_external_sources) ${ENV_COMMAND} ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} + -DPLATFORM=${PLATFORM} -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -DCMAKE_INSTALL_PREFIX=${FIREBASE_INSTALL_DIR} -DFIREBASE_DOWNLOAD_DIR=${FIREBASE_DOWNLOAD_DIR} diff --git a/cmake/toolchains/apple.toolchain.cmake b/cmake/toolchains/apple.toolchain.cmake new file mode 100644 index 0000000000..68d38a8133 --- /dev/null +++ b/cmake/toolchains/apple.toolchain.cmake @@ -0,0 +1,940 @@ +# Copyright 2021 Google LLC +# +# 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. + +# This file is part of the ios-cmake project. It was retrieved from +# https://github.com/gerstrong/ios-cmake.git which is a fork of +# https://github.com/cristeab/ios-cmake.git, which again is a fork of +# https://code.google.com/p/ios-cmake/. Which in turn is based off of +# the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which +# are included with CMake 2.8.4 +# +# The ios-cmake project is licensed under the new BSD license. +# +# Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software, +# Kitware, Inc., Insight Software Consortium. All rights reserved. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# This file is based off of the Platform/Darwin.cmake and +# Platform/UnixPaths.cmake files which are included with CMake 2.8.4 +# It has been altered for iOS development. +# +# Updated by Alex Stewart (alexs.mac@gmail.com) +# +# ***************************************************************************** +# Now maintained by Alexander Widerberg (widerbergaren [at] gmail.com) +# under the BSD-3-Clause license +# https://github.com/leetal/ios-cmake +# ***************************************************************************** +# +# INFORMATION / HELP +# +# The following options control the behaviour of this toolchain: +# +# PLATFORM: (default "OS64") +# OS = Build for iPhoneOS. +# OS64 = Build for arm64 iphoneOS. +# OS64COMBINED = Build for arm64 x86_64 iphoneOS. Combined into FAT STATIC lib (supported on 3.14+ of CMakewith "-G Xcode" argument ONLY) +# SIMULATOR = Build for x86 i386 iphoneOS Simulator. +# SIMULATOR64 = Build for x86_64 iphoneOS Simulator. +# SIMULATORARM64 = Build for arm64 iphoneOS Simulator. +# TVOS = Build for arm64 tvOS. +# TVOSCOMBINED = Build for arm64 x86_64 tvOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY) +# SIMULATOR_TVOS = Build for x86_64 tvOS Simulator. +# WATCHOS = Build for armv7k arm64_32 for watchOS. +# WATCHOSCOMBINED = Build for armv7k arm64_32 x86_64 watchOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY) +# SIMULATOR_WATCHOS = Build for x86_64 for watchOS Simulator. +# MAC = Build for x86_64 macOS. +# MAC_ARM64 = Build for Apple Silicon macOS. +# MAC_CATALYST = Build for x86_64 macOS with Catalyst support (iOS toolchain on macOS). +# Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS +# MAC_CATALYST_ARM64 = Build for Apple Silicon macOS with Catalyst support (iOS toolchain on macOS). +# Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS +# +# CMAKE_OSX_SYSROOT: Path to the SDK to use. By default this is +# automatically determined from PLATFORM and xcodebuild, but +# can also be manually specified (although this should not be required). +# +# CMAKE_DEVELOPER_ROOT: Path to the Developer directory for the platform +# being compiled for. By default this is automatically determined from +# CMAKE_OSX_SYSROOT, but can also be manually specified (although this should +# not be required). +# +# DEPLOYMENT_TARGET: Minimum SDK version to target. Default 2.0 on watchOS and 9.0 on tvOS+iOS +# +# ENABLE_BITCODE: (1|0) Enables or disables bitcode support. Default 1 (true) +# +# ENABLE_ARC: (1|0) Enables or disables ARC support. Default 1 (true, ARC enabled by default) +# +# ENABLE_VISIBILITY: (1|0) Enables or disables symbol visibility support. Default 0 (false, visibility hidden by default) +# +# ENABLE_STRICT_TRY_COMPILE: (1|0) Enables or disables strict try_compile() on all Check* directives (will run linker +# to actually check if linking is possible). Default 0 (false, will set CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY) +# +# ARCHS: (armv7 armv7s armv7k arm64 arm64_32 i386 x86_64) If specified, will override the default architectures for the given PLATFORM +# OS = armv7 armv7s arm64 (if applicable) +# OS64 = arm64 (if applicable) +# SIMULATOR = i386 +# SIMULATOR64 = x86_64 +# SIMULATORARM64 = arm64 +# TVOS = arm64 +# SIMULATOR_TVOS = x86_64 (i386 has since long been deprecated) +# WATCHOS = armv7k arm64_32 (if applicable) +# SIMULATOR_WATCHOS = x86_64 (i386 has since long been deprecated) +# MAC = x86_64 +# MAC_ARM64 = arm64 +# MAC_CATALYST = x86_64 +# MAC_CATALYST_ARM64 = arm64 +# +# This toolchain defines the following properties (available via get_property()) for use externally: +# +# PLATFORM: The currently targeted platform. +# XCODE_VERSION: Version number (not including Build version) of Xcode detected. +# SDK_VERSION: Version of SDK being used. +# OSX_ARCHITECTURES: Architectures being compiled for (generated from PLATFORM). +# APPLE_TARGET_TRIPLE: Used by autoconf build systems. NOTE: If "ARCHS" are overridden, this will *NOT* be set! +# +# This toolchain defines the following macros for use externally: +# +# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE XCODE_VARIANT) +# A convenience macro for setting xcode specific properties on targets. +# Available variants are: All, Release, RelWithDebInfo, Debug, MinSizeRel +# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1" "all"). +# +# find_host_package (PROGRAM ARGS) +# A macro used to find executable programs on the host system, not within the +# environment. Thanks to the android-cmake project for providing the +# command. +# + +cmake_minimum_required(VERSION 3.8.0) + +# CMake invokes the toolchain file twice during the first build, but only once during subsequent rebuilds. +if(IOS_TOOLCHAIN_HAS_RUN) + return() +endif(IOS_TOOLCHAIN_HAS_RUN) +set(IOS_TOOLCHAIN_HAS_RUN true) + +############################################################################### +# OPTIONS # +############################################################################### + +option(DROP_32_BIT "Drops the 32-bit targets universally." YES) + +############################################################################### +# END OPTIONS # +############################################################################### + +# List of supported platform values +list(APPEND _supported_platforms + "OS" "OS64" "OS64COMBINED" "SIMULATOR" "SIMULATOR64" "SIMULATORARM64" + "TVOS" "TVOSCOMBINED" "SIMULATOR_TVOS" + "WATCHOS" "WATCHOSCOMBINED" "SIMULATOR_WATCHOS" + "MAC" "MAC_ARM64" + "MAC_CATALYST" "MAC_CATALYST_ARM64") + +# Cache what generator is used +set(USED_CMAKE_GENERATOR "${CMAKE_GENERATOR}") + +# Check if using a CMake version capable of building combined FAT builds (simulator and target slices combined in one static lib) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14") + set(MODERN_CMAKE YES) +endif() + +# Get the Xcode version being used. +# Problem: CMake runs toolchain files multiple times, but can't read cache variables on some runs. +# Workaround: On first run (in which cache variables are always accessible), set an intermediary environment variable. +# +# NOTE: This pattern is used i many places in this toolchain to speed up checks of all sorts +if(DEFINED XCODE_VERSION_INT) + # Environment variables are always preserved. + set(ENV{_XCODE_VERSION_INT} "${XCODE_VERSION_INT}") +elseif(DEFINED ENV{_XCODE_VERSION_INT}) + set(XCODE_VERSION_INT "$ENV{_XCODE_VERSION_INT}") +elseif(NOT DEFINED XCODE_VERSION_INT) + find_program(XCODEBUILD_EXECUTABLE xcodebuild) + if(NOT XCODEBUILD_EXECUTABLE) + message(FATAL_ERROR "xcodebuild not found. Please install either the standalone commandline tools or Xcode.") + endif() + execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version + OUTPUT_VARIABLE XCODE_VERSION_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION_INT "${XCODE_VERSION_INT}") + string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION_INT "${XCODE_VERSION_INT}") + set(XCODE_VERSION_INT "${XCODE_VERSION_INT}" CACHE INTERNAL "") +endif() + +# Assuming that xcode 12.0 is installed you most probably have ios sdk 14.0 or later installed (tested on Big Sur) +# if you don't set a deployment target it will be set the way you only get 64-bit builds +if(NOT DEFINED DEPLOYMENT_TARGET AND XCODE_VERSION_INT VERSION_GREATER 12.0) + # Temporarily fix the arm64 issues in CMake install-combined by excluding arm64 for simulator builds (needed for Apple Silicon...) + set(CMAKE_XCODE_ATTRIBUTE_EXCLUDED_ARCHS[sdk=iphonesimulator*] "arm64") +endif() + +# Check if the platform variable is set +if(DEFINED PLATFORM) + # Environment variables are always preserved. + set(ENV{_PLATFORM} "${PLATFORM}") +elseif(DEFINED ENV{_PLATFORM}) + set(PLATFORM "$ENV{_PLATFORM}") +elseif(NOT DEFINED PLATFORM) + message(FATAL_ERROR "PLATFORM argument not set. Bailing configure since I don't know what target you want to build for!") +endif () + +# Safeguard that the platform value is set and is one of the supported values +list(FIND _supported_platforms ${PLATFORM} contains_PLATFORM) +if("${contains_PLATFORM}" EQUAL "-1") + string(REPLACE ";" "\n * " _supported_platforms_formatted "${_supported_platforms}") + message(FATAL_ERROR " Invalid PLATFORM specified! Current value: ${PLATFORM}.\n" + " Supported PLATFORM values: \n * ${_supported_platforms_formatted}") +endif() + +# Check if Apple Silicon is supported +if(PLATFORM MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$" AND ${CMAKE_VERSION} VERSION_LESS "3.19.5") + message(FATAL_ERROR "Apple Silicon builds requires a minimum of CMake 3.19.5") +endif() + +# Touch toolchain variable to suppress "unused variable" warning. +# This happens if CMake is invoked with the same command line the second time. +if(CMAKE_TOOLCHAIN_FILE) +endif() + +# Fix for PThread library not in path +set(CMAKE_THREAD_LIBS_INIT "-lpthread") +set(CMAKE_HAVE_THREADS_LIBRARY 1) +set(CMAKE_USE_WIN32_THREADS_INIT 0) +set(CMAKE_USE_PTHREADS_INIT 1) + +# Specify minimum version of deployment target. +if(NOT DEFINED DEPLOYMENT_TARGET) + if (PLATFORM MATCHES "WATCHOS") + # Unless specified, SDK version 4.0 is used by default as minimum target version (watchOS). + set(DEPLOYMENT_TARGET "4.0") + elseif(PLATFORM STREQUAL "MAC") + # Unless specified, SDK version 10.13 (High sierra) is used by default as minimum target version (macos). + set(DEPLOYMENT_TARGET "10.13") + elseif(PLATFORM STREQUAL "MAC_ARM64") + # Unless specified, SDK version 11.0 (Big Sur) is used by default as minimum target version (macos on arm). + set(DEPLOYMENT_TARGET "11.0") + elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64") + # Unless specified, SDK version 13.0 is used by default as minimum target version (mac catalyst minimum requirement). + set(DEPLOYMENT_TARGET "13.0") + else() + # Unless specified, SDK version 11.0 is used by default as minimum target version (iOS, tvOS). + set(DEPLOYMENT_TARGET "11.0") + endif() + message(STATUS "[DEFAULTS] Using the default min-version since DEPLOYMENT_TARGET not provided!") +elseif(DEFINED DEPLOYMENT_TARGET AND PLATFORM STREQUAL "MAC_CATALYST" AND ${DEPLOYMENT_TARGET} VERSION_LESS "13.0") + message(FATAL_ERROR "Mac Catalyst builds requires a minimum deployment target of 13.0!") +endif() + +# Store the DEPLOYMENT_TARGET in the cache +set(DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}" CACHE INTERNAL "") + +# Handle the case where we are targeting iOS and a version above 10.3.4 (32-bit support dropped officially) +if(PLATFORM STREQUAL "OS" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) + set(PLATFORM "OS64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +elseif(PLATFORM STREQUAL "SIMULATOR" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) + set(PLATFORM "SIMULATOR64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +endif() + +set(PLATFORM_INT "${PLATFORM}") + +if(DEFINED ARCHS) + string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") +endif() + +# Determine the platform name and architectures for use in xcodebuild commands +# from the specified PLATFORM_INT name. +if(PLATFORM_INT STREQUAL "OS") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + set(ARCHS armv7 armv7s arm64) + set(APPLE_TARGET_TRIPLE_INT arm-apple-ios) + endif() +elseif(PLATFORM_INT STREQUAL "OS64") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS arm64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example + else() + set(ARCHS arm64) + endif() + set(APPLE_TARGET_TRIPLE_INT aarch64-apple-ios) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios) + endif() +elseif(PLATFORM_INT STREQUAL "OS64COMBINED") + set(SDK_NAME iphoneos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS arm64 x86_64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64") + else() + set(ARCHS arm64 x86_64) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64") + endif() + set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-ios) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the OS64COMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS i386) + set(APPLE_TARGET_TRIPLE_INT i386-apple-ios) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios) + endif() + message(DEPRECATION "SIMULATOR IS DEPRECATED. Consider using SIMULATOR64 instead.") +elseif(PLATFORM_INT STREQUAL "SIMULATOR64") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + set(APPLE_TARGET_TRIPLE_INT x86_64-apple-ios) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios) + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATORARM64") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT aarch64-apple-ios) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios) + endif() +elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME appletvos) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT aarch64-apple-tvos) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos) + endif() +elseif (PLATFORM_INT STREQUAL "TVOSCOMBINED") + set(SDK_NAME appletvos) + if(MODERN_CMAKE) + if(NOT ARCHS) + set(ARCHS arm64 x86_64) + set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-tvos) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "x86_64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvsimulator*] "x86_64") + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the TVOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME appletvsimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + set(APPLE_TARGET_TRIPLE_INT x86_64-apple-tvos) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos) + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME watchos) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32) + set(APPLE_TARGET_TRIPLE_INT aarch64_32-apple-watchos) + else() + set(ARCHS armv7k) + set(APPLE_TARGET_TRIPLE_INT arm-apple-watchos) + endif() + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos) + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOSCOMBINED") + set(SDK_NAME watchos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32 i386) + set(APPLE_TARGET_TRIPLE_INT aarch64_32-i386-apple-watchos) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k arm64_32") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k arm64_32") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386") + else() + set(ARCHS armv7k i386) + set(APPLE_TARGET_TRIPLE_INT arm-i386-apple-watchos) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386") + endif() + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the WATCHOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME watchsimulator) + if(NOT ARCHS) + set(ARCHS i386) + set(APPLE_TARGET_TRIPLE_INT i386-apple-watchos) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos) + endif() +elseif(PLATFORM_INT STREQUAL "MAC" OR PLATFORM_INT STREQUAL "MAC_CATALYST") + set(SDK_NAME macosx) + if(NOT ARCHS) + set(ARCHS x86_64) + endif() + string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") + if(PLATFORM_INT STREQUAL "MAC") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx) + elseif(PLATFORM_INT STREQUAL "MAC_CATALYST") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi) + endif() +elseif(PLATFORM_INT MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$") + set(SDK_NAME macosx) + if(NOT ARCHS) + set(ARCHS arm64) + endif() + string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") + if(PLATFORM_INT STREQUAL "MAC_ARM64") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx) + elseif(PLATFORM_INT STREQUAL "MAC_CATALYST_ARM64") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi) + endif() +else() + message(FATAL_ERROR "Invalid PLATFORM: ${PLATFORM_INT}") +endif() + +if(MODERN_CMAKE AND PLATFORM_INT MATCHES ".*COMBINED" AND NOT CMAKE_GENERATOR MATCHES "Xcode") + message(FATAL_ERROR "The COMBINED options only work with Xcode generator, -G Xcode") +endif() + +if(CMAKE_GENERATOR MATCHES "Xcode" AND PLATFORM_INT MATCHES "MAC_CATALYST_.*") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + set(CMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "macosx") + set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-maccatalyst") + if(NOT DEFINED MACOSX_DEPLOYMENT_TARGET) + set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "10.15") + else() + set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "${MACOSX_DEPLOYMENT_TARGET}") + endif() +elseif(CMAKE_GENERATOR MATCHES "Xcode") + set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}") + if(NOT PLATFORM_INT MATCHES ".*COMBINED") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=${SDK_NAME}*] "${ARCHS}") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=${SDK_NAME}*] "${ARCHS}") + endif() +endif() + +# If user did not specify the SDK root to use, then query xcodebuild for it. +if(DEFINED CMAKE_OSX_SYSROOT_INT) + # Environment variables are always preserved. + set(ENV{_CMAKE_OSX_SYSROOT_INT} "${CMAKE_OSX_SYSROOT_INT}") +elseif(DEFINED ENV{_CMAKE_OSX_SYSROOT_INT}) + set(CMAKE_OSX_SYSROOT_INT "$ENV{_CMAKE_OSX_SYSROOT_INT}") +elseif(NOT DEFINED CMAKE_OSX_SYSROOT_INT) + execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version -sdk ${SDK_NAME} Path + OUTPUT_VARIABLE CMAKE_OSX_SYSROOT_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +if (NOT DEFINED CMAKE_OSX_SYSROOT_INT AND NOT DEFINED CMAKE_OSX_SYSROOT) + message(SEND_ERROR "Please make sure that Xcode is installed and that the toolchain" + "is pointing to the correct path. Please run:" + "sudo xcode-select -s /Applications/Xcode.app/Contents/Developer" + "and see if that fixes the problem for you.") + message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} " + "does not exist.") +elseif(DEFINED CMAKE_OSX_SYSROOT_INT) + set(CMAKE_OSX_SYSROOT_INT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") + # Specify the location or name of the platform SDK to be used in CMAKE_OSX_SYSROOT. + set(CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") +endif() + +# Use bitcode or not +if(NOT DEFINED ENABLE_BITCODE AND NOT ARCHS MATCHES "((^|;|, )(i386|x86_64))+") + # Unless specified, enable bitcode support by default + message(STATUS "[DEFAULTS] Enabling bitcode support by default. ENABLE_BITCODE not provided!") + set(ENABLE_BITCODE TRUE) +elseif(NOT DEFINED ENABLE_BITCODE) + message(STATUS "[DEFAULTS] Disabling bitcode support by default on simulators. ENABLE_BITCODE not provided for override!") + set(ENABLE_BITCODE FALSE) +endif() +set(ENABLE_BITCODE_INT ${ENABLE_BITCODE} CACHE BOOL + "Whether or not to enable bitcode" FORCE) +# Use ARC or not +if(NOT DEFINED ENABLE_ARC) + # Unless specified, enable ARC support by default + set(ENABLE_ARC TRUE) + message(STATUS "[DEFAULTS] Enabling ARC support by default. ENABLE_ARC not provided!") +endif() +set(ENABLE_ARC_INT ${ENABLE_ARC} CACHE BOOL "Whether or not to enable ARC" FORCE) +# Use hidden visibility or not +if(NOT DEFINED ENABLE_VISIBILITY) + # Unless specified, disable symbols visibility by default + set(ENABLE_VISIBILITY FALSE) + message(STATUS "[DEFAULTS] Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!") +endif() +set(ENABLE_VISIBILITY_INT ${ENABLE_VISIBILITY} CACHE BOOL "Whether or not to hide symbols from the dynamic linker (-fvisibility=hidden)" FORCE) +# Set strict compiler checks or not +if(NOT DEFINED ENABLE_STRICT_TRY_COMPILE) + # Unless specified, disable strict try_compile() + set(ENABLE_STRICT_TRY_COMPILE FALSE) + message(STATUS "[DEFAULTS] Using NON-strict compiler checks by default. ENABLE_STRICT_TRY_COMPILE not provided!") +endif() +set(ENABLE_STRICT_TRY_COMPILE_INT ${ENABLE_STRICT_TRY_COMPILE} CACHE BOOL + "Whether or not to use strict compiler checks" FORCE) + +# Get the SDK version information. +if(DEFINED SDK_VERSION) + # Environment variables are always preserved. + set(ENV{_SDK_VERSION} "${SDK_VERSION}") +elseif(DEFINED ENV{_SDK_VERSION}) + set(SDK_VERSION "$ENV{_SDK_VERSION}") +elseif(NOT DEFINED SDK_VERSION) + execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -sdk ${CMAKE_OSX_SYSROOT_INT} -version SDKVersion + OUTPUT_VARIABLE SDK_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +# Find the Developer root for the specific iOS platform being compiled for +# from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in +# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain +# this information from xcrun or xcodebuild. +if (NOT DEFINED CMAKE_DEVELOPER_ROOT AND NOT CMAKE_GENERATOR MATCHES "Xcode") + get_filename_component(PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT_INT} PATH) + get_filename_component(CMAKE_DEVELOPER_ROOT ${PLATFORM_SDK_DIR} PATH) + if (NOT EXISTS "${CMAKE_DEVELOPER_ROOT}") + message(FATAL_ERROR "Invalid CMAKE_DEVELOPER_ROOT: ${CMAKE_DEVELOPER_ROOT} does not exist.") + endif() +endif() + +# Find the C & C++ compilers for the specified SDK. +if(DEFINED CMAKE_C_COMPILER) + # Environment variables are always preserved. + set(ENV{_CMAKE_C_COMPILER} "${CMAKE_C_COMPILER}") +elseif(DEFINED ENV{_CMAKE_C_COMPILER}) + set(CMAKE_C_COMPILER "$ENV{_CMAKE_C_COMPILER}") +elseif(NOT DEFINED CMAKE_C_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang + OUTPUT_VARIABLE CMAKE_C_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() +if(DEFINED CMAKE_CXX_COMPILER) + # Environment variables are always preserved. + set(ENV{_CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER}") +elseif(DEFINED ENV{_CMAKE_CXX_COMPILER}) + set(CMAKE_CXX_COMPILER "$ENV{_CMAKE_CXX_COMPILER}") +elseif(NOT DEFINED CMAKE_CXX_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang++ + OUTPUT_VARIABLE CMAKE_CXX_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() +# Find (Apple's) libtool. +if(DEFINED BUILD_LIBTOOL) + # Environment variables are always preserved. + set(ENV{_BUILD_LIBTOOL} "${BUILD_LIBTOOL}") +elseif(DEFINED ENV{_BUILD_LIBTOOL}) + set(BUILD_LIBTOOL "$ENV{_BUILD_LIBTOOL}") +elseif(NOT DEFINED BUILD_LIBTOOL) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find libtool + OUTPUT_VARIABLE BUILD_LIBTOOL + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() +# Find the toolchain's provided install_name_tool if none is found on the host +if(DEFINED CMAKE_INSTALL_NAME_TOOL) + # Environment variables are always preserved. + set(ENV{_CMAKE_INSTALL_NAME_TOOL} "${CMAKE_INSTALL_NAME_TOOL}") +elseif(DEFINED ENV{_CMAKE_INSTALL_NAME_TOOL}) + set(CMAKE_INSTALL_NAME_TOOL "$ENV{_CMAKE_INSTALL_NAME_TOOL}") +elseif(NOT DEFINED CMAKE_INSTALL_NAME_TOOL) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find install_name_tool + OUTPUT_VARIABLE CMAKE_INSTALL_NAME_TOOL_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(CMAKE_INSTALL_NAME_TOOL ${CMAKE_INSTALL_NAME_TOOL_INT} CACHE INTERNAL "") +endif() + +# Configure libtool to be used instead of ar + ranlib to build static libraries. +# This is required on Xcode 7+, but should also work on previous versions of +# Xcode. +get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) +foreach(lang ${languages}) + set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "${BUILD_LIBTOOL} -static -o " CACHE INTERNAL "") +endforeach() + +# CMake 3.14+ support building for iOS, watchOS and tvOS out of the box. +if(MODERN_CMAKE) + if(SDK_NAME MATCHES "iphone") + set(CMAKE_SYSTEM_NAME iOS) + elseif(SDK_NAME MATCHES "macosx") + set(CMAKE_SYSTEM_NAME Darwin) + elseif(SDK_NAME MATCHES "appletv") + set(CMAKE_SYSTEM_NAME tvOS) + elseif(SDK_NAME MATCHES "watch") + set(CMAKE_SYSTEM_NAME watchOS) + endif() + # Provide flags for a combined FAT library build on newer CMake versions + if(PLATFORM_INT MATCHES ".*COMBINED") + set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO") + set(CMAKE_IOS_INSTALL_COMBINED YES) + message(STATUS "Will combine built (static) artifacts into FAT lib...") + endif() +elseif(NOT DEFINED CMAKE_SYSTEM_NAME AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10") + # Legacy code path prior to CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified + set(CMAKE_SYSTEM_NAME iOS) +elseif(NOT DEFINED CMAKE_SYSTEM_NAME) + # Legacy code path prior to CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified + set(CMAKE_SYSTEM_NAME Darwin) +endif() +# Standard settings. +set(CMAKE_SYSTEM_VERSION ${SDK_VERSION} CACHE INTERNAL "") +set(UNIX TRUE CACHE BOOL "") +set(APPLE TRUE CACHE BOOL "") +if(PLATFORM STREQUAL "MAC" OR PLATFORM STREQUAL "MAC_ARM64") + set(IOS FALSE CACHE BOOL "") + set(MACOS TRUE CACHE BOOL "") +elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64") + set(IOS TRUE CACHE BOOL "") + set(MACOS TRUE CACHE BOOL "") +else() + set(IOS TRUE CACHE BOOL "") +endif() +set(CMAKE_AR ar CACHE FILEPATH "" FORCE) +set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE) +set(CMAKE_STRIP strip CACHE FILEPATH "" FORCE) +# Set the architectures for which to build. +set(CMAKE_OSX_ARCHITECTURES ${ARCHS} CACHE INTERNAL "") +# Change the type of target generated for try_compile() so it'll work when cross-compiling, weak compiler checks +if(NOT ENABLE_STRICT_TRY_COMPILE_INT) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +endif() +# All iOS/Darwin specific settings - some may be redundant. +set(CMAKE_MACOSX_BUNDLE YES) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") +set(CMAKE_SHARED_LIBRARY_PREFIX "lib") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") +set(CMAKE_SHARED_MODULE_PREFIX "lib") +set(CMAKE_SHARED_MODULE_SUFFIX ".so") +set(CMAKE_C_COMPILER_ABI ELF) +set(CMAKE_CXX_COMPILER_ABI ELF) +set(CMAKE_C_HAS_ISYSROOT 1) +set(CMAKE_CXX_HAS_ISYSROOT 1) +set(CMAKE_MODULE_EXISTS 1) +set(CMAKE_DL_LIBS "") +set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") +set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") +set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") +set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") + +if(ARCHS MATCHES "((^|;|, )(arm64|arm64e|x86_64))+") + set(CMAKE_C_SIZEOF_DATA_PTR 8) + set(CMAKE_CXX_SIZEOF_DATA_PTR 8) + if(ARCHS MATCHES "((^|;|, )(arm64|arm64e))+") + set(CMAKE_SYSTEM_PROCESSOR "aarch64") + else() + set(CMAKE_SYSTEM_PROCESSOR "x86_64") + endif() +else() + set(CMAKE_C_SIZEOF_DATA_PTR 4) + set(CMAKE_CXX_SIZEOF_DATA_PTR 4) + set(CMAKE_SYSTEM_PROCESSOR "arm") +endif() + +# Note that only Xcode 7+ supports the newer more specific: +# -m${SDK_NAME}-version-min flags, older versions of Xcode use: +# -m(ios/ios-simulator)-version-min instead. +if(${CMAKE_VERSION} VERSION_LESS "3.11") + if(PLATFORM_INT STREQUAL "OS" OR PLATFORM_INT STREQUAL "OS64") + if(XCODE_VERSION_INT VERSION_LESS 7.0) + set(SDK_NAME_VERSION_FLAGS + "-mios-version-min=${DEPLOYMENT_TARGET}") + else() + # Xcode 7.0+ uses flags we can build directly from SDK_NAME. + set(SDK_NAME_VERSION_FLAGS + "-m${SDK_NAME}-version-min=${DEPLOYMENT_TARGET}") + endif() + elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-simulator-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-simulator-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "MAC") + set(SDK_NAME_VERSION_FLAGS + "-mmacosx-version-min=${DEPLOYMENT_TARGET}") + else() + # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min. + set(SDK_NAME_VERSION_FLAGS + "-mios-simulator-version-min=${DEPLOYMENT_TARGET}") + endif() +elseif(NOT PLATFORM_INT STREQUAL "MAC_CATALYST") + # Newer versions of CMake sets the version min flags correctly, skip this for Mac Catalyst targets + set(CMAKE_OSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET}) +endif() + +if(DEFINED APPLE_TARGET_TRIPLE_INT) + set(APPLE_TARGET_TRIPLE ${APPLE_TARGET_TRIPLE_INT} CACHE INTERNAL "") +endif() + +if(PLATFORM_INT STREQUAL "MAC_CATALYST") + set(C_TARGET_FLAGS "-target ${APPLE_TARGET_TRIPLE_INT} -isystem ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/usr/include") +endif() + +if(ENABLE_BITCODE_INT) + set(BITCODE "-fembed-bitcode") + set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES") +else() + set(BITCODE "") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO") +endif() + +if(ENABLE_ARC_INT) + set(FOBJC_ARC "-fobjc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES") +else() + set(FOBJC_ARC "-fno-objc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "NO") +endif() + +if(NOT ENABLE_VISIBILITY_INT) + foreach(lang ${languages}) + set(CMAKE_${lang}_VISIBILITY_PRESET "hidden" CACHE INTERNAL "") + endforeach() + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES") + set(VISIBILITY "-fvisibility=hidden -fvisibility-inlines-hidden") +else() + foreach(lang ${languages}) + set(CMAKE_${lang}_VISIBILITY_PRESET "default" CACHE INTERNAL "") + endforeach() + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "NO") + set(VISIBILITY "-fvisibility=default") +endif() + +#Check if Xcode generator is used, since that will handle these flags automagically +if(CMAKE_GENERATOR MATCHES "Xcode") + message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as generator.") +else() + # Hidden visibility is required for C++ on iOS. + set(CMAKE_C_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g ${CMAKE_CXX_FLAGS_DEBUG}") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG -Os -ffast-math ${CMAKE_CXX_FLAGS_MINSIZEREL}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG -O2 -g -ffast-math ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG -O3 -ffast-math ${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_C_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") + set(CMAKE_CXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") + set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -arch ${CMAKE_OSX_ARCHITECTURES}") +endif() + +## Print status messages to inform of the current state +message(STATUS "Configuring ${SDK_NAME} build for platform: ${PLATFORM_INT}, architecture(s): ${ARCHS}") +message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT_INT}") +message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}") +message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}") +message(STATUS "Using libtool: ${BUILD_LIBTOOL}") +message(STATUS "Using install name tool: ${CMAKE_INSTALL_NAME_TOOL}") +if(DEFINED APPLE_TARGET_TRIPLE) + message(STATUS "Autoconf target triple: ${APPLE_TARGET_TRIPLE}") +endif() +message(STATUS "Using minimum deployment version: ${DEPLOYMENT_TARGET}" + " (SDK version: ${SDK_VERSION})") +if(MODERN_CMAKE) + message(STATUS "Merging integrated CMake 3.14+ iOS,tvOS,watchOS,macOS toolchain(s) with this toolchain!") +endif() +if(CMAKE_GENERATOR MATCHES "Xcode") + message(STATUS "Using Xcode version: ${XCODE_VERSION_INT}") +endif() +message(STATUS "CMake version: ${CMAKE_VERSION}") +if(DEFINED SDK_NAME_VERSION_FLAGS) + message(STATUS "Using version flags: ${SDK_NAME_VERSION_FLAGS}") +endif() +message(STATUS "Using a data_ptr size of: ${CMAKE_CXX_SIZEOF_DATA_PTR}") +if(ENABLE_BITCODE_INT) + message(STATUS "Bitcode: Enabled") +else() + message(STATUS "Bitcode: Disabled") +endif() + +if(ENABLE_ARC_INT) + message(STATUS "ARC: Enabled") +else() + message(STATUS "ARC: Disabled") +endif() + +if(ENABLE_VISIBILITY_INT) + message(STATUS "Hiding symbols: Disabled") +else() + message(STATUS "Hiding symbols: Enabled") +endif() + +# Set global properties +set_property(GLOBAL PROPERTY PLATFORM "${PLATFORM}") +set_property(GLOBAL PROPERTY APPLE_TARGET_TRIPLE "${APPLE_TARGET_TRIPLE_INT}") +set_property(GLOBAL PROPERTY SDK_VERSION "${SDK_VERSION}") +set_property(GLOBAL PROPERTY XCODE_VERSION "${XCODE_VERSION_INT}") +set_property(GLOBAL PROPERTY OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") + +# Export configurable variables for the try_compile() command. +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES + PLATFORM + XCODE_VERSION_INT + SDK_VERSION + DEPLOYMENT_TARGET + CMAKE_DEVELOPER_ROOT + CMAKE_OSX_SYSROOT_INT + ENABLE_BITCODE + ENABLE_ARC + CMAKE_C_COMPILER + CMAKE_CXX_COMPILER + BUILD_LIBTOOL + CMAKE_INSTALL_NAME_TOOL + CMAKE_C_FLAGS + CMAKE_CXX_FLAGS + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_RELEASE + CMAKE_C_LINK_FLAGS + CMAKE_CXX_LINK_FLAGS + CMAKE_ASM_FLAGS + ) + +set(CMAKE_PLATFORM_HAS_INSTALLNAME 1) +set(CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") +set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") +set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names") +set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") +set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a") +set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name") + +# Set the find root to the SDK developer roots. +# Note: CMAKE_FIND_ROOT_PATH is only useful when cross-compiling. Thus, do not set on macOS builds. +if(NOT PLATFORM_INT STREQUAL "MAC" AND NOT PLATFORM_INT STREQUAL "MAC_ARM64") + list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") + set(CMAKE_IGNORE_PATH "/System/Library/Frameworks;/usr/local/lib" CACHE INTERNAL "") +endif() + +# Default to searching for frameworks first. +set(CMAKE_FIND_FRAMEWORK FIRST) + +# Set up the default search directories for frameworks. +if(PLATFORM_INT MATCHES "MAC_CATALYST.*") + set(CMAKE_FRAMEWORK_PATH + ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks + ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks + ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/System/Library/Frameworks + ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "") +else() + set(CMAKE_FRAMEWORK_PATH + ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks + ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks + ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "") +endif() + +# By default, search both the specified iOS SDK and the remainder of the host filesystem. +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "") +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH CACHE INTERNAL "") +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH CACHE INTERNAL "") +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH CACHE INTERNAL "") +endif() + +# +# Some helper-macros below to simplify and beautify the CMakeFile +# + +# This little macro lets you set any Xcode specific property. +macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION) + set(XCODE_RELVERSION_I "${XCODE_RELVERSION}") + if(XCODE_RELVERSION_I STREQUAL "All") + set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}") + else() + set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}") + endif() +endmacro(set_xcode_property) + +# This macro lets you find executable programs on the host system. +macro(find_host_package) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) + set(_TOOLCHAIN_IOS ${IOS}) + set(IOS FALSE) + find_package(${ARGN}) + set(IOS ${_TOOLCHAIN_IOS}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) +endmacro(find_host_package) diff --git a/database/src/common/data_snapshot.cc b/database/src/common/data_snapshot.cc index 5515b6962a..3bbc44bd34 100644 --- a/database/src/common/data_snapshot.cc +++ b/database/src/common/data_snapshot.cc @@ -23,7 +23,7 @@ #if FIREBASE_PLATFORM_ANDROID #include "database/src/android/data_snapshot_android.h" #include "database/src/android/database_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "database/src/ios/data_snapshot_ios.h" #include "database/src/ios/database_ios.h" #elif defined(FIREBASE_TARGET_DESKTOP) @@ -33,7 +33,7 @@ #include "database/src/stub/data_snapshot_stub.h" #include "database/src/stub/database_stub.h" #endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, - // defined(FIREBASE_TARGET_DESKTOP) + // FIREBASE_PLATFORM_TVOS, defined(FIREBASE_TARGET_DESKTOP) #include "database/src/common/cleanup.h" diff --git a/database/src/common/database.cc b/database/src/common/database.cc index ab0bfb6707..aeb9852fcd 100644 --- a/database/src/common/database.cc +++ b/database/src/common/database.cc @@ -30,14 +30,14 @@ // DatabaseInternal is defined in these 3 files, one implementation for each OS. #if FIREBASE_PLATFORM_ANDROID #include "database/src/android/database_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "database/src/ios/database_ios.h" #elif defined(FIREBASE_TARGET_DESKTOP) #include "database/src/desktop/database_desktop.h" #else #include "database/src/stub/database_stub.h" #endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, - // defined(FIREBASE_TARGET_DESKTOP) + // FIREBASE_PLATFORM_TVOS, defined(FIREBASE_TARGET_DESKTOP) // Register the module initializer. FIREBASE_APP_REGISTER_CALLBACKS(database, diff --git a/database/src/common/database_reference.cc b/database/src/common/database_reference.cc index 366097630b..b71c578418 100644 --- a/database/src/common/database_reference.cc +++ b/database/src/common/database_reference.cc @@ -23,7 +23,7 @@ #if FIREBASE_PLATFORM_ANDROID #include "database/src/android/database_android.h" #include "database/src/android/database_reference_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "database/src/ios/database_ios.h" #include "database/src/ios/database_reference_ios.h" #elif defined(FIREBASE_TARGET_DESKTOP) @@ -33,7 +33,7 @@ #include "database/src/stub/database_reference_stub.h" #include "database/src/stub/database_stub.h" #endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, - // defined(FIREBASE_TARGET_DESKTOP) + // FIREBASE_PLATFORM_TVOS, defined(FIREBASE_TARGET_DESKTOP) #include "database/src/common/cleanup.h" diff --git a/database/src/common/disconnection.cc b/database/src/common/disconnection.cc index dff6c507be..18da226990 100644 --- a/database/src/common/disconnection.cc +++ b/database/src/common/disconnection.cc @@ -21,7 +21,7 @@ #if FIREBASE_PLATFORM_ANDROID #include "database/src/android/database_android.h" #include "database/src/android/disconnection_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "database/src/ios/database_ios.h" #include "database/src/ios/disconnection_ios.h" #elif defined(FIREBASE_TARGET_DESKTOP) @@ -31,7 +31,7 @@ #include "database/src/stub/database_stub.h" #include "database/src/stub/disconnection_stub.h" #endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, - // defined(FIREBASE_TARGET_DESKTOP) + // FIREBASE_PLATFORM_TVOS, defined(FIREBASE_TARGET_DESKTOP) #include "database/src/common/cleanup.h" diff --git a/database/src/common/mutable_data.cc b/database/src/common/mutable_data.cc index 016e61de0c..fa0ad7a31f 100644 --- a/database/src/common/mutable_data.cc +++ b/database/src/common/mutable_data.cc @@ -21,7 +21,7 @@ #if FIREBASE_PLATFORM_ANDROID #include "database/src/android/database_android.h" #include "database/src/android/mutable_data_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "database/src/ios/database_ios.h" #include "database/src/ios/mutable_data_ios.h" #elif defined(FIREBASE_TARGET_DESKTOP) @@ -31,7 +31,7 @@ #include "database/src/stub/database_stub.h" #include "database/src/stub/mutable_data_stub.h" #endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, - // defined(FIREBASE_TARGET_DESKTOP) + // FIREBASE_PLATFORM_TVOS, defined(FIREBASE_TARGET_DESKTOP) #include "database/src/common/cleanup.h" diff --git a/database/src/common/query.cc b/database/src/common/query.cc index b480328725..685893bb8d 100644 --- a/database/src/common/query.cc +++ b/database/src/common/query.cc @@ -23,7 +23,7 @@ #if FIREBASE_PLATFORM_ANDROID #include "database/src/android/database_android.h" #include "database/src/android/query_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "database/src/ios/database_ios.h" #include "database/src/ios/query_ios.h" #elif defined(FIREBASE_TARGET_DESKTOP) @@ -33,7 +33,7 @@ #include "database/src/stub/database_stub.h" #include "database/src/stub/query_stub.h" #endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, - // defined(FIREBASE_TARGET_DESKTOP) + // FIREBASE_PLATFORM_TVOS, defined(FIREBASE_TARGET_DESKTOP) #include "database/src/common/cleanup.h" diff --git a/functions/src/common/callable_reference.cc b/functions/src/common/callable_reference.cc index b0c70b9310..c2e536bd68 100644 --- a/functions/src/common/callable_reference.cc +++ b/functions/src/common/callable_reference.cc @@ -22,13 +22,14 @@ #if FIREBASE_PLATFORM_ANDROID #include "functions/src/android/callable_reference_android.h" #include "functions/src/android/functions_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "functions/src/ios/callable_reference_ios.h" #include "functions/src/ios/functions_ios.h" #else #include "functions/src/desktop/callable_reference_desktop.h" #include "functions/src/desktop/functions_desktop.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { class Variant; diff --git a/functions/src/common/functions.cc b/functions/src/common/functions.cc index 5dfdba7857..58816c346a 100644 --- a/functions/src/common/functions.cc +++ b/functions/src/common/functions.cc @@ -30,11 +30,12 @@ // QueryInternal is defined in these 3 files, one implementation for each OS. #if FIREBASE_PLATFORM_ANDROID #include "functions/src/android/functions_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "functions/src/ios/functions_ios.h" #else #include "functions/src/desktop/functions_desktop.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS // Register the module initializer. FIREBASE_APP_REGISTER_CALLBACKS(functions, diff --git a/installations/src/installations_internal.h b/installations/src/installations_internal.h index 31475bb082..c7ecd7880f 100644 --- a/installations/src/installations_internal.h +++ b/installations/src/installations_internal.h @@ -21,10 +21,11 @@ // each OS. #if FIREBASE_PLATFORM_ANDROID || FIREBASE_ANDROID_FOR_DESKTOP #include "installations/src/android/installations_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "installations/src/ios/installations_ios.h" #else #include "installations/src/stub/installations_stub.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS #endif // FIREBASE_FIS_CLIENT_CPP_SRC_INSTALLATIONS_INTERNAL_H_ diff --git a/messaging/src/ios/messaging.mm b/messaging/src/ios/messaging.mm index 6c6430a679..39f514a4fa 100644 --- a/messaging/src/ios/messaging.mm +++ b/messaging/src/ios/messaging.mm @@ -196,6 +196,7 @@ void NotifyListenerSet(Listener* listener) { LogInfo("FCM: Using FCM senderID %s", senderID.UTF8String); id appDelegate = [UIApplication sharedApplication]; + #if FIREBASE_PLATFORM_IOS // Register for remote notifications. Both codepaths result in // application:didRegisterForRemoteNotificationsWithDeviceToken: being called when they // complete, or application:didFailToRegisterForRemoteNotificationsWithError: if there was an @@ -215,6 +216,7 @@ void NotifyListenerSet(Listener* listener) { [appDelegate registerUserNotificationSettings:settings]; [appDelegate registerForRemoteNotifications]; } + #endif // FIREBASE_PLATFORM_IOS // Only request the token automatically if permitted if ([FIRMessaging messaging].autoInitEnabled) { @@ -522,6 +524,7 @@ static BOOL AppDelegateApplicationDidFinishLaunchingWithOptions(id self, SEL sel [user_notification_center setDelegate:(id)application]; } + #if FIREBASE_PLATFORM_IOS // If the app was launched with a notification, cache it until we're connected. g_launch_notification = [launch_options objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; @@ -548,6 +551,7 @@ static BOOL AppDelegateApplicationDidFinishLaunchingWithOptions(id self, SEL sel [invocation getReturnValue:&ret]; return ret; } + #endif // FIREBASE_PLATFORM_IOS return NO; } @@ -854,6 +858,7 @@ + (void)load { }); } +#if FIREBASE_PLATFORM_IOS - (void)userNotificationCenter:(UNUserNotificationCenter *)notificationCenter willPresentNotification:(UNNotification *)notification withCompletionHandler: @@ -890,6 +895,7 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)notificationCenter withCompletionHandler:completionHandler]; } } +#endif // FIREBASE_PLATFORM_IOS @end diff --git a/remote_config/src/remote_config.cc b/remote_config/src/remote_config.cc index 471b37a66a..1d3fcfcdb2 100644 --- a/remote_config/src/remote_config.cc +++ b/remote_config/src/remote_config.cc @@ -25,11 +25,12 @@ // QueryInternal is defined in these 3 files, one implementation for each OS. #if FIREBASE_PLATFORM_ANDROID #include "remote_config/src/android/remote_config_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "remote_config/src/ios/remote_config_ios.h" #else #include "remote_config/src/desktop/remote_config_desktop.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace remote_config { diff --git a/storage/src/common/controller.cc b/storage/src/common/controller.cc index 4ea2831042..48d31e709a 100644 --- a/storage/src/common/controller.cc +++ b/storage/src/common/controller.cc @@ -19,11 +19,12 @@ // Controller is defined in these 3 files, one implementation for each OS. #if FIREBASE_PLATFORM_ANDROID #include "storage/src/android/controller_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "storage/src/ios/controller_ios.h" #else #include "storage/src/desktop/controller_desktop.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace storage { diff --git a/storage/src/common/listener.cc b/storage/src/common/listener.cc index 429dfe1f6d..d873a78036 100644 --- a/storage/src/common/listener.cc +++ b/storage/src/common/listener.cc @@ -18,11 +18,12 @@ #if FIREBASE_PLATFORM_ANDROID #include "storage/src/stub/listener_stub.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "storage/src/ios/listener_ios.h" #else #include "storage/src/desktop/listener_desktop.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace storage { diff --git a/storage/src/common/metadata.cc b/storage/src/common/metadata.cc index 79b4f2cd17..efd1dc8b3c 100644 --- a/storage/src/common/metadata.cc +++ b/storage/src/common/metadata.cc @@ -23,13 +23,14 @@ #if FIREBASE_PLATFORM_ANDROID #include "storage/src/android/metadata_android.h" #include "storage/src/android/storage_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "storage/src/ios/metadata_ios.h" #include "storage/src/ios/storage_ios.h" #else #include "storage/src/desktop/metadata_desktop.h" #include "storage/src/desktop/storage_desktop.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS namespace firebase { namespace storage { diff --git a/storage/src/common/storage.cc b/storage/src/common/storage.cc index 8e84fba83a..f5f26ae337 100644 --- a/storage/src/common/storage.cc +++ b/storage/src/common/storage.cc @@ -31,11 +31,12 @@ // QueryInternal is defined in these 3 files, one implementation for each OS. #if FIREBASE_PLATFORM_ANDROID #include "storage/src/android/storage_android.h" -#elif FIREBASE_PLATFORM_IOS +#elif FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_TVOS #include "storage/src/ios/storage_ios.h" #else #include "storage/src/desktop/storage_desktop.h" -#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS +#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, + // FIREBASE_PLATFORM_TVOS // Register the module initializer. FIREBASE_APP_REGISTER_CALLBACKS(storage, diff --git a/storage/src/common/storage_reference.cc b/storage/src/common/storage_reference.cc index 0d7adadc79..54bc6983b7 100644 --- a/storage/src/common/storage_reference.cc +++ b/storage/src/common/storage_reference.cc @@ -24,7 +24,7 @@ #if defined(__ANDROID__) #include "storage/src/android/storage_android.h" #include "storage/src/android/storage_reference_android.h" -#elif TARGET_OS_IPHONE +#elif TARGET_OS_IPHONE || TARGET_OS_TV #include "storage/src/ios/storage_ios.h" #include "storage/src/ios/storage_reference_ios.h" #else