Skip to content

Commit

Permalink
Prepare cocoapods to accept the ENABLE_HERMES_PROFILER flag (#36352)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #36352

WIP

## Changelog:
[iOS][Changed] - Add support to enable the Hermes Sampling Profiler

Reviewed By: mdvacca

Differential Revision: D43699036

fbshipit-source-id: 9da5aed94541e09c705909fb7166623c36ce2a3e
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Mar 2, 2023
1 parent 2780ba3 commit dce9d8d
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 22 deletions.
68 changes: 68 additions & 0 deletions scripts/cocoapods/__tests__/utils-test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

# ===== #
Expand Down
8 changes: 5 additions & 3 deletions scripts/cocoapods/new_architecture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
80 changes: 62 additions & 18 deletions scripts/cocoapods/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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" : ""
Expand All @@ -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|
Expand All @@ -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|
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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|
Expand Down Expand Up @@ -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}"
Expand Down
10 changes: 9 additions & 1 deletion scripts/react_native_pods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down

0 comments on commit dce9d8d

Please sign in to comment.