Skip to content

Commit abad576

Browse files
cipolleschifacebook-github-bot
authored andcommitted
Fix symbol not found _jump_fcontext with use_frameworks! (#42230)
Summary: Pull Request resolved: #42230 While developing Xcode 15, Apple reimplemented the linker. In Xcode 15.0, the linker was making old iOS (< 15) crash when they were built using Xcode 15. To fix that, we make Apple create new compiler flags (`-ld_classic`) to have a backward compatible linker. In Xcode 15.1, Apple fixed that behavior, so the flags should not be required anymore. But now, if we pass `-ld_classic` to the linker and we have an app that is using `use_framworks!`, that app crashes at startup. This change remove the flags if the Xcode that is used is 15.1 or greater. *Note:* The previous change added the flags to Hermes as well. I tested this fix in a configuration where Hermes has the flags and React Native does not, and it works. So we are removing the flags only from React Native. This Fixes #39945 ## Changelog: [Internal] - Do not add the `-ld_classic` flag if the app is built with Xcode 15.1 or greater. Reviewed By: cortinico Differential Revision: D52658197 fbshipit-source-id: 37d6bc895921c0fc3661f301870477191e7e42b3
1 parent a7c5c28 commit abad576

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

packages/react-native/scripts/cocoapods/__tests__/utils-test.rb

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,52 @@ def test_applyXcode15Patch_whenXcodebuild14_correctlyAppliesNecessaryPatch
484484
assert_equal(2, XcodebuildMock.version_invocation_count)
485485
end
486486

487+
def test_applyXcode15Patch_whenXcodebuild15_1_does_not_apply_patch
488+
# Arrange
489+
XcodebuildMock.set_version = "Xcode 15.1"
490+
first_target = prepare_target("FirstTarget")
491+
second_target = prepare_target("SecondTarget")
492+
third_target = TargetMock.new("ThirdTarget", [
493+
BuildConfigurationMock.new("Debug", {
494+
"GCC_PREPROCESSOR_DEFINITIONS" => '$(inherited) "SomeFlag=1" '
495+
}),
496+
BuildConfigurationMock.new("Release", {
497+
"GCC_PREPROCESSOR_DEFINITIONS" => '$(inherited) "SomeFlag=1" '
498+
}),
499+
], nil)
500+
501+
user_project_mock = UserProjectMock.new("/a/path", [
502+
prepare_config("Debug"),
503+
prepare_config("Release"),
504+
],
505+
:native_targets => [
506+
first_target,
507+
second_target
508+
]
509+
)
510+
pods_projects_mock = PodsProjectMock.new([], {"hermes-engine" => {}}, :native_targets => [
511+
third_target
512+
])
513+
installer = InstallerMock.new(pods_projects_mock, [
514+
AggregatedProjectMock.new(user_project_mock)
515+
])
516+
517+
# Act
518+
user_project_mock.build_configurations.each do |config|
519+
assert_nil(config.build_settings["OTHER_LDFLAGS"])
520+
end
521+
522+
ReactNativePodsUtils.apply_xcode_15_patch(installer, :xcodebuild_manager => XcodebuildMock)
523+
524+
# Assert
525+
user_project_mock.build_configurations.each do |config|
526+
assert_equal("$(inherited) ", config.build_settings["OTHER_LDFLAGS"])
527+
end
528+
529+
# User project and Pods project
530+
assert_equal(2, XcodebuildMock.version_invocation_count)
531+
end
532+
487533
def test_applyXcode15Patch_whenXcodebuild15_correctlyAppliesNecessaryPatch
488534
# Arrange
489535
XcodebuildMock.set_version = "Xcode 15.0"
@@ -1018,13 +1064,13 @@ def test_add_flag_to_map_with_inheritance_whenUsedWithBuildConfigBuildSettings
10181064
})
10191065
twiceProcessed_config = BuildConfigurationMock.new("TwiceProcessedConfig");
10201066
test_flag = " -DTEST_FLAG=1"
1021-
1067+
10221068
# Act
10231069
ReactNativePodsUtils.add_flag_to_map_with_inheritance(empty_config.build_settings, "OTHER_CPLUSPLUSFLAGS", test_flag)
10241070
ReactNativePodsUtils.add_flag_to_map_with_inheritance(initialized_config.build_settings, "OTHER_CPLUSPLUSFLAGS", test_flag)
10251071
ReactNativePodsUtils.add_flag_to_map_with_inheritance(twiceProcessed_config.build_settings, "OTHER_CPLUSPLUSFLAGS", test_flag)
10261072
ReactNativePodsUtils.add_flag_to_map_with_inheritance(twiceProcessed_config.build_settings, "OTHER_CPLUSPLUSFLAGS", test_flag)
1027-
1073+
10281074
# Assert
10291075
assert_equal("$(inherited)" + test_flag, empty_config.build_settings["OTHER_CPLUSPLUSFLAGS"])
10301076
assert_equal("$(inherited) INIT_FLAG" + test_flag, initialized_config.build_settings["OTHER_CPLUSPLUSFLAGS"])
@@ -1051,7 +1097,7 @@ def test_add_flag_to_map_with_inheritance_whenUsedWithXCConfigAttributes
10511097
assert_equal("$(inherited) INIT_FLAG" + test_flag, initialized_xcconfig.attributes["OTHER_CPLUSPLUSFLAGS"])
10521098
assert_equal("$(inherited)" + test_flag, twiceProcessed_xcconfig.attributes["OTHER_CPLUSPLUSFLAGS"])
10531099
end
1054-
1100+
10551101
def test_add_ndebug_flag_to_pods_in_release
10561102
# Arrange
10571103
xcconfig = XCConfigMock.new("Config")
@@ -1061,7 +1107,7 @@ def test_add_ndebug_flag_to_pods_in_release
10611107
custom_debug_config2 = BuildConfigurationMock.new("Custom")
10621108
custom_release_config1 = BuildConfigurationMock.new("CustomRelease")
10631109
custom_release_config2 = BuildConfigurationMock.new("Production")
1064-
1110+
10651111
installer = prepare_installer_for_cpp_flags(
10661112
[ xcconfig ],
10671113
{
@@ -1072,7 +1118,7 @@ def test_add_ndebug_flag_to_pods_in_release
10721118
)
10731119
# Act
10741120
ReactNativePodsUtils.add_ndebug_flag_to_pods_in_release(installer)
1075-
1121+
10761122
# Assert
10771123
assert_equal(nil, default_debug_config.build_settings["OTHER_CPLUSPLUSFLAGS"])
10781124
assert_equal("$(inherited) -DNDEBUG", default_release_config.build_settings["OTHER_CPLUSPLUSFLAGS"])
@@ -1150,4 +1196,3 @@ def prepare_installer_for_cpp_flags(xcconfigs, build_configs)
11501196
:pod_target_installation_results => pod_target_installation_results_map
11511197
)
11521198
end
1153-

packages/react-native/scripts/cocoapods/utils.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def self.apply_xcode_15_patch(installer, xcodebuild_manager: Xcodebuild)
172172
project.build_configurations.each do |config|
173173
# fix for weak linking
174174
self.safe_init(config, other_ld_flags_key)
175-
if self.is_using_xcode15_or_greater(:xcodebuild_manager => xcodebuild_manager)
175+
if self.is_using_xcode15_0(:xcodebuild_manager => xcodebuild_manager)
176176
self.add_value_to_setting_if_missing(config, other_ld_flags_key, xcode15_compatibility_flags)
177177
else
178178
self.remove_value_from_setting_if_present(config, other_ld_flags_key, xcode15_compatibility_flags)
@@ -404,7 +404,7 @@ def self.remove_value_from_setting_if_present(config, setting_name, value)
404404
end
405405
end
406406

407-
def self.is_using_xcode15_or_greater(xcodebuild_manager: Xcodebuild)
407+
def self.is_using_xcode15_0(xcodebuild_manager: Xcodebuild)
408408
xcodebuild_version = xcodebuild_manager.version
409409

410410
# The output of xcodebuild -version is something like
@@ -415,7 +415,8 @@ def self.is_using_xcode15_or_greater(xcodebuild_manager: Xcodebuild)
415415
regex = /(\d+)\.(\d+)(?:\.(\d+))?/
416416
if match_data = xcodebuild_version.match(regex)
417417
major = match_data[1].to_i
418-
return major >= 15
418+
minor = match_data[2].to_i
419+
return major == 15 && minor == 0
419420
end
420421

421422
return false

0 commit comments

Comments
 (0)