From 79294b5e12852fb8a708658d26f01e3caafefde2 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Wed, 28 Jun 2023 01:30:46 +0800 Subject: [PATCH] [ios][updates][tools] fix swift casting runtime exception (#23132) # Why close ENG-9094 # How - this is again the swift runtime exception for casting versioned class to unversioned class like https://github.com/expo/expo/pull/23012#discussion_r1237294135. this time it's the `EXUpdatesUpdate` and solved by the `object_setClass` too. - moving the `object_setClass` to expo-go only `EXUpdatesBinding` class which is a proper place to do the casting. however, this requires more swift <-> objc interop like adding swift compatibility header to search paths and adding `-fmodule-map`. - some refactoring for the expokit podspec # Test Plan - ci passed - test local expo-go to load sdk 49 updates (both classic updates and eas updates) --- ios/ExpoKit.podspec | 16 +++----- .../Core/UniversalModules/EXUpdatesBinding.m | 20 +++++++++- ios/Podfile.lock | 4 +- .../Expo/ExpoKit/ABI49_0_0ExpoKit.podspec | 30 +++++++------- .../ABI49_0_0EXUpdatesBinding.m | 20 +++++++++- .../ABI49_0_0/postinstalls.rb | 2 + .../EXUpdates/EXUpdates/UpdatesModule.swift | 2 - packages/expo-updates/ios/EXUpdates.podspec | 3 ++ .../ios/EXUpdates/UpdatesModule.swift | 2 - template-files/ios/ExpoKit.podspec | 16 +++----- tools/src/versioning/ios/index.ts | 39 ++++++++++--------- 11 files changed, 88 insertions(+), 66 deletions(-) diff --git a/ios/ExpoKit.podspec b/ios/ExpoKit.podspec index 403c5285b8e851..2977078b307ffd 100644 --- a/ios/ExpoKit.podspec +++ b/ios/ExpoKit.podspec @@ -1,6 +1,10 @@ # generated from template-files/ios/ExpoKit.podspec +folly_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1' +folly_compiler_flags = folly_flags + ' ' + '-Wno-comma -Wno-shorten-64-to-32' +boost_compiler_flags = '-Wno-documentation' + Pod::Spec.new do |s| s.name = "ExpoKit" s.version = "49.0.0" @@ -14,18 +18,10 @@ Pod::Spec.new do |s| s.swift_version = '5.4' s.default_subspec = "Core" s.source = { :git => "http://github.com/expo/expo.git" } - s.xcconfig = { - 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17', - 'SYSTEM_HEADER_SEARCH_PATHS' => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", - 'OTHER_CPLUSPLUSFLAGS' => [ - "$(OTHER_CFLAGS)", - "-DFOLLY_NO_CONFIG", - "-DFOLLY_MOBILE=1", - "-DFOLLY_USE_LIBCPP=1" - ] - } + s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags s.pod_target_xcconfig = { + 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17', 'USE_HEADERMAP' => 'YES', 'DEFINES_MODULE' => 'YES', } diff --git a/ios/Exponent/Versioned/Core/UniversalModules/EXUpdatesBinding.m b/ios/Exponent/Versioned/Core/UniversalModules/EXUpdatesBinding.m index aa71a331284855..06a5056ee9732d 100644 --- a/ios/Exponent/Versioned/Core/UniversalModules/EXUpdatesBinding.m +++ b/ios/Exponent/Versioned/Core/UniversalModules/EXUpdatesBinding.m @@ -4,6 +4,16 @@ #import "EXUpdatesBinding.h" +#import + +#import "ExpoModulesCore-Swift.h" +#if __has_include() +#import +#else +#import "EXUpdatesInterface-Swift.h" +#endif +#import "EXUpdates-Swift.h" + NS_ASSUME_NONNULL_BEGIN @interface EXUpdatesBinding () @@ -34,7 +44,10 @@ - (instancetype)initWithScopeKey:(NSString *)scopeKey updatesKernelService:(id "http://github.com/expo/expo.git" } - s.xcconfig = { - 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17', - 'SYSTEM_HEADER_SEARCH_PATHS' => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", - 'OTHER_CPLUSPLUSFLAGS' => [ - "$(OTHER_CFLAGS)", - "-DFOLLY_NO_CONFIG", - "-DFOLLY_MOBILE=1", - "-DFOLLY_USE_LIBCPP=1" - ] - } + s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags s.pod_target_xcconfig = { 'USE_HEADERMAP' => 'YES', @@ -36,16 +27,21 @@ Pod::Spec.new do |s| } + header_search_paths = [ + '"$(PODS_ROOT)/boost"', + '"$(PODS_ROOT)/glog"', + '"$(PODS_ROOT)/DoubleConversion"', + '"$(PODS_ROOT)/RCT-Folly"', + '"$(PODS_ROOT)/Headers/Private/ABI49_0_0React-Core"', + '"$(PODS_CONFIGURATION_BUILD_DIR)/ABI49_0_0ExpoModulesCore/Swift Compatibility Header"', + '"$(PODS_CONFIGURATION_BUILD_DIR)/ABI49_0_0EXUpdatesInterface/Swift Compatibility Header"', + '"$(PODS_CONFIGURATION_BUILD_DIR)/ABI49_0_0EXUpdates/Swift Compatibility Header"', + ] s.pod_target_xcconfig = { + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", "USE_HEADERMAP" => "YES", "DEFINES_MODULE" => "YES", - "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_TARGET_SRCROOT)\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/Headers/Private/ABI49_0_0React-Core\" \"$(PODS_CONFIGURATION_BUILD_DIR)/ABI49_0_0ExpoModulesCore/Swift Compatibility Header\"" - } - s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.xcconfig = { - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/glog\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/Headers/Private/ABI49_0_0React-Core\" \"$(PODS_CONFIGURATION_BUILD_DIR)/ABI49_0_0ExpoModulesCore/Swift Compatibility Header\"", - "OTHER_CFLAGS" => "$(inherited)" + " " + folly_flags + "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), } s.subspec "Expo" do |ss| diff --git a/ios/versioned-react-native/ABI49_0_0/Expo/ExpoKit/Core/UniversalModules/ABI49_0_0EXUpdatesBinding.m b/ios/versioned-react-native/ABI49_0_0/Expo/ExpoKit/Core/UniversalModules/ABI49_0_0EXUpdatesBinding.m index 1db4871409bc2a..77fdfd2cf10356 100644 --- a/ios/versioned-react-native/ABI49_0_0/Expo/ExpoKit/Core/UniversalModules/ABI49_0_0EXUpdatesBinding.m +++ b/ios/versioned-react-native/ABI49_0_0/Expo/ExpoKit/Core/UniversalModules/ABI49_0_0EXUpdatesBinding.m @@ -4,6 +4,16 @@ #import "ABI49_0_0EXUpdatesBinding.h" +#import + +#import "ABI49_0_0ExpoModulesCore-Swift.h" +#if __has_include() +#import +#else +#import "ABI49_0_0EXUpdatesInterface-Swift.h" +#endif +#import "ABI49_0_0EXUpdates-Swift.h" + NS_ASSUME_NONNULL_BEGIN @interface ABI49_0_0EXUpdatesBinding () @@ -34,7 +44,10 @@ - (instancetype)initWithScopeKey:(NSString *)scopeKey updatesKernelService:(id other_c_flags, 'OTHER_SWIFT_FLAGS[config=Debug]' => other_swift_flags } + s.user_target_xcconfig = { + 'HEADER_SEARCH_PATHS' => '"${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/Swift Compatibility Header"', + } if !ex_updates_native_debug && !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0') s.source_files = "#{s.name}/**/*.h" diff --git a/packages/expo-updates/ios/EXUpdates/UpdatesModule.swift b/packages/expo-updates/ios/EXUpdates/UpdatesModule.swift index 7efa5f201afa0a..6c1c594c2437bf 100644 --- a/packages/expo-updates/ios/EXUpdates/UpdatesModule.swift +++ b/packages/expo-updates/ios/EXUpdates/UpdatesModule.swift @@ -20,8 +20,6 @@ public final class UpdatesModule: Module { public required init(appContext: AppContext) { updatesService = appContext.legacyModule(implementing: EXUpdatesModuleInterface.self) - // Ensures the universal UpdatesConfig can cast to versioned UpdatesConfig without exception in Swift - object_setClass(updatesService?.config, UpdatesConfig.self) super.init(appContext: appContext) } diff --git a/template-files/ios/ExpoKit.podspec b/template-files/ios/ExpoKit.podspec index 971fb353398b40..edb248954d6e7a 100644 --- a/template-files/ios/ExpoKit.podspec +++ b/template-files/ios/ExpoKit.podspec @@ -1,6 +1,10 @@ # generated from template-files/ios/ExpoKit.podspec +folly_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1' +folly_compiler_flags = folly_flags + ' ' + '-Wno-comma -Wno-shorten-64-to-32' +boost_compiler_flags = '-Wno-documentation' + Pod::Spec.new do |s| s.name = "ExpoKit" s.version = "${IOS_EXPONENT_CLIENT_VERSION}" @@ -14,18 +18,10 @@ Pod::Spec.new do |s| s.swift_version = '5.4' s.default_subspec = "Core" s.source = { :git => "http://github.com/expo/expo.git" } - s.xcconfig = { - 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17', - 'SYSTEM_HEADER_SEARCH_PATHS' => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", - 'OTHER_CPLUSPLUSFLAGS' => [ - "$(OTHER_CFLAGS)", - "-DFOLLY_NO_CONFIG", - "-DFOLLY_MOBILE=1", - "-DFOLLY_USE_LIBCPP=1" - ] - } + s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags s.pod_target_xcconfig = { + 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17', 'USE_HEADERMAP' => 'YES', 'DEFINES_MODULE' => 'YES', } diff --git a/tools/src/versioning/ios/index.ts b/tools/src/versioning/ios/index.ts index fc650f551b8b5f..74dd846f845cb5 100644 --- a/tools/src/versioning/ios/index.ts +++ b/tools/src/versioning/ios/index.ts @@ -629,29 +629,27 @@ async function generateExpoKitPodspecAsync( fileString = fileString.replace(/(?<=s.version = ").*?(?=")/g, versionNumber); // add Reanimated V2 RCT-Folly dependency - fileString = fileString - .replace( - /(?=Pod::Spec.new do \|s\|)/, - ` -folly_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1' -folly_compiler_flags = folly_flags + ' ' + '-Wno-comma -Wno-shorten-64-to-32' -boost_compiler_flags = '-Wno-documentation'\n\n` - ) - .replace( - /(?= s.subspec "Expo" do \|ss\|)/g, - ` + fileString = fileString.replace( + /(?= s.subspec "Expo" do \|ss\|)/g, + ` + header_search_paths = [ + '"$(PODS_ROOT)/boost"', + '"$(PODS_ROOT)/glog"', + '"$(PODS_ROOT)/DoubleConversion"', + '"$(PODS_ROOT)/RCT-Folly"', + '"$(PODS_ROOT)/Headers/Private/${versionName}React-Core"', + '"$(PODS_CONFIGURATION_BUILD_DIR)/${versionName}ExpoModulesCore/Swift Compatibility Header"', + '"$(PODS_CONFIGURATION_BUILD_DIR)/${versionName}EXUpdatesInterface/Swift Compatibility Header"', + '"$(PODS_CONFIGURATION_BUILD_DIR)/${versionName}EXUpdates/Swift Compatibility Header"', + ] s.pod_target_xcconfig = { + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", "USE_HEADERMAP" => "YES", "DEFINES_MODULE" => "YES", - "HEADER_SEARCH_PATHS" => "\\"$(PODS_TARGET_SRCROOT)/ReactCommon\\" \\"$(PODS_TARGET_SRCROOT)\\" \\"$(PODS_ROOT)/RCT-Folly\\" \\"$(PODS_ROOT)/boost\\" \\"$(PODS_ROOT)/DoubleConversion\\" \\"$(PODS_ROOT)/Headers/Private/${versionName}React-Core\\" \\"\$(PODS_CONFIGURATION_BUILD_DIR)/${versionName}ExpoModulesCore/Swift Compatibility Header\\"" + "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), } - s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.xcconfig = { - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", - "HEADER_SEARCH_PATHS" => "\\"$(PODS_ROOT)/boost\\" \\"$(PODS_ROOT)/glog\\" \\"$(PODS_ROOT)/RCT-Folly\\" \\"$(PODS_ROOT)/Headers/Private/${versionName}React-Core\\" \\"\$(PODS_CONFIGURATION_BUILD_DIR)/${versionName}ExpoModulesCore/Swift Compatibility Header\\"", - "OTHER_CFLAGS" => "$(inherited)" + " " + folly_flags - }\n\n` - ); + \n\n` + ); return fileString; }); @@ -828,6 +826,9 @@ if pod_name.start_with?('${versionedPodNames.React}') || pod_name == '${versione ${configValues.join(`\n${indent}`)} -fmodule-map-file="\${PODS_ROOT}/Headers/Public/${versionName}React-Core/${versionName}React/${versionName}React-Core.modulemap" -fmodule-map-file="\${PODS_ROOT}/Headers/Public/${versionName}ExpoModulesCore/${versionName}ExpoModulesCore.modulemap" + -fmodule-map-file="\${PODS_ROOT}/Headers/Public/${versionName}ExpoModulesCore/${versionName}ExpoModulesCore.modulemap" + -fmodule-map-file="\${PODS_ROOT}/Headers/Public/${versionName}EXUpdates/${versionName}EXUpdates.modulemap" + -fmodule-map-file="\${PODS_ROOT}/Headers/Public/${versionName}EXUpdatesInterface/${versionName}EXUpdatesInterface.modulemap" ] config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)'] config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << '${versionName}RCT_DEV=1'