diff --git a/scripts/cocoapods/__tests__/utils-test.rb b/scripts/cocoapods/__tests__/utils-test.rb index 5fac9c1ed4dcca..2a135b46c8d5e5 100644 --- a/scripts/cocoapods/__tests__/utils-test.rb +++ b/scripts/cocoapods/__tests__/utils-test.rb @@ -677,6 +677,74 @@ def test_applyFlagsForFabric_whenFabricDisabled_doNothing assert_nil(config.build_settings["OTHER_CFLAGS"]) end end + + # ============================= # + # Test - Enable Hermes Profiler # + # ============================= # + + def test_enableHermesProfiler_whenEnableHermesProfileIsTrue_setsFlagsInRelease + # Arrange + first_target = prepare_target("FirstTarget") + second_target = prepare_target("SecondTarget") + third_target = prepare_target("ThirdTarget", "com.apple.product-type.bundle") + user_project_mock = UserProjectMock.new("a/path", [ + prepare_config("Debug"), + prepare_config("Release"), + ], + :native_targets => [ + first_target, + second_target + ] + ) + pods_projects_mock = PodsProjectMock.new([third_target], {"hermes-engine" => {}}) + installer = InstallerMock.new(pods_projects_mock, [ + AggregatedProjectMock.new(user_project_mock) + ]) + + # Act + ReactNativePodsUtils.enable_hermes_profiler(installer, enable_hermes_profiler: true) + + # Assert + installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result| + target_installation_result.native_target.build_configurations.each do |config| + if config.name != "Release" + assert_nil(config.build_settings["OTHER_CFLAGS"]) + else + assert_equal(config.build_settings["OTHER_CFLAGS"], "$(inherited) -DRCT_REMOTE_PROFILE=1") + end + end + end + end + + def test_enableHermesProfiler_whenEnableHermesProfileIsFalse_doesNothing + # Arrange + first_target = prepare_target("FirstTarget") + second_target = prepare_target("SecondTarget") + third_target = prepare_target("ThirdTarget", "com.apple.product-type.bundle") + user_project_mock = UserProjectMock.new("a/path", [ + prepare_config("Debug"), + prepare_config("Release"), + ], + :native_targets => [ + first_target, + second_target + ] + ) + pods_projects_mock = PodsProjectMock.new([third_target], {"hermes-engine" => {}}) + installer = InstallerMock.new(pods_projects_mock, [ + AggregatedProjectMock.new(user_project_mock) + ]) + + # Act + ReactNativePodsUtils.enable_hermes_profiler(installer) + + # Assert + installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result| + target_installation_result.native_target.build_configurations.each do |config| + assert_nil(config.build_settings["OTHER_CFLAGS"]) + end + end + end end # ===== # diff --git a/scripts/cocoapods/new_architecture.rb b/scripts/cocoapods/new_architecture.rb index 207c79c2eb5a5b..a0606c59c557cd 100644 --- a/scripts/cocoapods/new_architecture.rb +++ b/scripts/cocoapods/new_architecture.rb @@ -50,7 +50,8 @@ def self.modify_flags_for_new_architecture(installer, is_new_arch_enabled) if config_name == "Release" config_file.attributes['OTHER_CPLUSPLUSFLAGS'] = config_file.attributes['OTHER_CPLUSPLUSFLAGS'] + ndebug_flag - config_file.attributes['OTHER_CFLAGS'] = "$(inherited)" + ndebug_flag + other_cflags = config_file.attributes['OTHER_CFLAGS'] != nil ? config_file.attributes['OTHER_CFLAGS'] : "$(inherited)" + config_file.attributes['OTHER_CFLAGS'] = other_cflags + ndebug_flag end xcconfig_path = aggregate_target.xcconfig_path(config_name) @@ -68,9 +69,10 @@ def self.modify_flags_for_new_architecture(installer, is_new_arch_enabled) target_installation_result.native_target.build_configurations.each do |config| if config.name == "Release" - current_flags = config.build_settings['OTHER_CPLUSPLUSFLAGS'] != nil ? config.build_settings['OTHER_CPLUSPLUSFLAGS'] : "" + current_flags = config.build_settings['OTHER_CPLUSPLUSFLAGS'] != nil ? config.build_settings['OTHER_CPLUSPLUSFLAGS'] : "$(inherited)" config.build_settings['OTHER_CPLUSPLUSFLAGS'] = current_flags + ndebug_flag - config.build_settings['OTHER_CFLAGS'] = "$(inherited)" + ndebug_flag + current_cflags = config.build_settings['OTHER_CFLAGS'] != nil ? config.build_settings['OTHER_CFLAGS'] : "$(inherited)" + config.build_settings['OTHER_CFLAGS'] = current_cflags + ndebug_flag end end end diff --git a/scripts/cocoapods/utils.rb b/scripts/cocoapods/utils.rb index d7a54cb8d18e32..a4198ef88fe176 100644 --- a/scripts/cocoapods/utils.rb +++ b/scripts/cocoapods/utils.rb @@ -54,7 +54,7 @@ def self.turn_off_resource_bundle_react_core(installer) end def self.exclude_i386_architecture_while_using_hermes(installer) - projects = self.exrtract_projects(installer) + projects = self.extract_projects(installer) # Hermes does not support `i386` architecture excluded_archs_default = self.has_pod(installer, 'hermes-engine') ? "i386" : "" @@ -70,7 +70,7 @@ def self.exclude_i386_architecture_while_using_hermes(installer) def self.set_node_modules_user_settings(installer, react_native_path) Pod::UI.puts("Setting REACT_NATIVE build settings") - projects = self.exrtract_projects(installer) + projects = self.extract_projects(installer) projects.each do |project| project.build_configurations.each do |config| @@ -82,7 +82,7 @@ def self.set_node_modules_user_settings(installer, react_native_path) end def self.fix_library_search_paths(installer) - projects = self.exrtract_projects(installer) + projects = self.extract_projects(installer) projects.each do |project| project.build_configurations.each do |config| @@ -125,19 +125,7 @@ def self.apply_flags_for_fabric(installer, fabric_enabled: false) return if !fabric_enabled fabric_flag = "-DRN_FABRIC_ENABLED" - projects = self.exrtract_projects(installer) - - projects.each do |project| - project.build_configurations.each do |config| - cflags = config.build_settings["OTHER_CFLAGS"] ? config.build_settings["OTHER_CFLAGS"] : "$(inherited)" - - if !cflags.include?(fabric_flag) - cflags = "#{cflags} #{fabric_flag}" - end - config.build_settings["OTHER_CFLAGS"] = cflags - end - project.save() - end + self.add_compiler_flag_to_project(installer, fabric_flag) end private @@ -198,7 +186,7 @@ def self.detect_use_frameworks(target_definition) def self.update_search_paths(installer) return if ENV['USE_FRAMEWORKS'] == nil - projects = self.exrtract_projects(installer) + projects = self.extract_projects(installer) projects.each do |project| project.build_configurations.each do |config| @@ -230,13 +218,69 @@ def self.update_search_paths(installer) end end - def self.exrtract_projects(installer) + def self.enable_hermes_profiler(installer, enable_hermes_profiler: false) + return if !enable_hermes_profiler + + Pod::UI.puts "[Hermes Profiler] Enable Hermes Sample profiler" + # self.add_compiler_flag_to_project(installer, "-DRCT_REMOTE_PROFILE=1", configuration: "Release") + self.add_compiler_flag_to_pods(installer, "-DRCT_REMOTE_PROFILE=1", configuration: "Release") + end + + # ========= # + # Utilities # + # ========= # + + def self.extract_projects(installer) return installer.aggregate_targets .map{ |t| t.user_project } .uniq{ |p| p.path } .push(installer.pods_project) end + def self.add_compiler_flag_to_project(installer, flag, configuration: nil) + projects = self.extract_projects(installer) + + projects.each do |project| + project.build_configurations.each do |config| + self.set_flag_in_config(config, flag, configuration: configuration) + end + project.save() + end + end + + def self.add_compiler_flag_to_pods(installer, flag, configuration: nil) + installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result| + target_installation_result.native_target.build_configurations.each do |config| + self.set_flag_in_config(config, flag, configuration: configuration) + end + end + end + + def self.set_flag_in_config(config, flag, configuration: nil) + if configuration == nil || config.name == configuration + self.add_flag_for_key(config, flag, "OTHER_CFLAGS") + self.add_flag_for_key(config, flag, "OTHER_CPLUSPLUSFLAGS") + end + end + + + def self.add_flag_for_key(config, flag, key) + current_setting = config.build_settings[key] ? config.build_settings[key] : "$(inherited)" + + if current_setting.kind_of?(Array) + current_setting = current_setting + .map { |s| s.gsub('"', '') } + .map { |s| s.gsub('\"', '') } + .join(" ") + end + + if !current_setting.include?(flag) + current_setting = "#{current_setting} #{flag}" + end + + config.build_settings[key] = current_setting + end + def self.add_search_path_if_not_included(current_search_paths, new_search_path) if !current_search_paths.include?(new_search_path) current_search_paths << " #{new_search_path}" diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index 16439ba72f968c..aec2cdb24bb447 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -203,7 +203,13 @@ def use_flipper!(versions = {}, configurations: ['Debug']) # - installer: the Cocoapod object that allows to customize the project. # - react_native_path: path to React Native. # - mac_catalyst_enabled: whether we are running the Pod on a Mac Catalyst project or not. -def react_native_post_install(installer, react_native_path = "../node_modules/react-native", mac_catalyst_enabled: false) +# - enable_hermes_profiler: whether the hermes profiler should be turned on in Release mode +def react_native_post_install( + installer, react_native_path = "../node_modules/react-native", + mac_catalyst_enabled: false, + enable_hermes_profiler: false +) + enable_hermes_profiler = enable_hermes_profiler || ENV["ENABLE_HERMES_PROFILER"] == "1" ReactNativePodsUtils.turn_off_resource_bundle_react_core(installer) ReactNativePodsUtils.apply_mac_catalyst_patches(installer) if mac_catalyst_enabled @@ -219,11 +225,13 @@ def react_native_post_install(installer, react_native_path = "../node_modules/re ReactNativePodsUtils.update_search_paths(installer) ReactNativePodsUtils.set_node_modules_user_settings(installer, react_native_path) ReactNativePodsUtils.apply_flags_for_fabric(installer, fabric_enabled: fabric_enabled) + ReactNativePodsUtils.enable_hermes_profiler(installer, enable_hermes_profiler: enable_hermes_profiler) NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer) is_new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == "1" NewArchitectureHelper.modify_flags_for_new_architecture(installer, is_new_arch_enabled) + Pod::UI.puts "Pod install took #{Time.now.to_i - $START_TIME} [s] to run".green end