Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect ccache and provide a default configuration #42051

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions packages/react-native/scripts/cocoapods/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,42 @@ def self.set_node_modules_user_settings(installer, react_native_path)
end
end

def self.set_ccache_compiler_and_linker_build_settings(installer, react_native_path, ccache_enabled)
projects = self.extract_projects(installer)

ccache_path = `command -v ccache`.strip
cipolleschi marked this conversation as resolved.
Show resolved Hide resolved
ccache_available = !ccache_path.empty?

message_prefix = "[Ccache]"

if ccache_available
Pod::UI.puts("#{message_prefix}: Ccache found at #{ccache_path}")
end

if ccache_available and ccache_enabled
Pod::UI.puts("#{message_prefix}: Setting CC, LD, CXX & LDPLUSPLUS build settings")
# Using scripts wrapping the ccache executable, to allow injection of configurations
ccache_clang_sh = File.join("$(REACT_NATIVE_PATH)", 'scripts', 'xcode', 'ccache-clang.sh')
ccache_clangpp_sh = File.join("$(REACT_NATIVE_PATH)", 'scripts', 'xcode', 'ccache-clang++.sh')

projects.each do |project|
project.build_configurations.each do |config|
# Using the un-qualified names means you can swap in different implementations, for example ccache
config.build_settings["CC"] = ccache_clang_sh
config.build_settings["LD"] = ccache_clang_sh
config.build_settings["CXX"] = ccache_clangpp_sh
config.build_settings["LDPLUSPLUS"] = ccache_clangpp_sh
end

project.save()
end
elsif ccache_available and !ccache_enabled
Pod::UI.puts("#{message_prefix}: Pass ':ccache_enabled => true' to 'react_native_post_install' in your Podfile or set environment variable 'USE_CCACHE=1' to increase the speed of subsequent builds")
elsif !ccache_available and ccache_enabled
Pod::UI.warn("#{message_prefix}: Install ccache or ensure your neither passing ':ccache_enabled => true' nor setting environment variable 'USE_CCACHE=1'")
end
end

def self.fix_library_search_paths(installer)
projects = self.extract_projects(installer)

Expand Down
4 changes: 3 additions & 1 deletion packages/react-native/scripts/react_native_pods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ def get_default_flags()
def react_native_post_install(
installer,
react_native_path = "../node_modules/react-native",
mac_catalyst_enabled: false
mac_catalyst_enabled: false,
ccache_enabled: ENV['USE_CCACHE'] == '1'
)
ReactNativePodsUtils.turn_off_resource_bundle_react_core(installer)

Expand All @@ -276,6 +277,7 @@ def react_native_post_install(
ReactNativePodsUtils.update_search_paths(installer)
ReactNativePodsUtils.set_use_hermes_build_setting(installer, hermes_enabled)
ReactNativePodsUtils.set_node_modules_user_settings(installer, react_native_path)
ReactNativePodsUtils.set_ccache_compiler_and_linker_build_settings(installer, react_native_path, ccache_enabled)
ReactNativePodsUtils.apply_xcode_15_patch(installer)
ReactNativePodsUtils.apply_ats_config(installer)
ReactNativePodsUtils.updateOSDeploymentTarget(installer)
Expand Down
10 changes: 10 additions & 0 deletions packages/react-native/scripts/xcode/ccache-clang++.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

# Get the absolute path of this script
SCRIPT_DIR=$(dirname $(readlink -f "$0"))

REACT_NATIVE_CCACHE_CONFIGPATH=$SCRIPT_DIR/ccache.conf
# Provide our config file if none is already provided
export CCACHE_CONFIGPATH="${CCACHE_CONFIGPATH:-$REACT_NATIVE_CCACHE_CONFIGPATH}"

exec ccache clang++ "$@"
10 changes: 10 additions & 0 deletions packages/react-native/scripts/xcode/ccache-clang.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

# Get the absolute path of this script
SCRIPT_DIR=$(dirname $(readlink -f "$0"))

REACT_NATIVE_CCACHE_CONFIGPATH=$SCRIPT_DIR/ccache.conf
# Provide our config file if none is already provided
export CCACHE_CONFIGPATH="${CCACHE_CONFIGPATH:-$REACT_NATIVE_CCACHE_CONFIGPATH}"

exec ccache clang "$@"
5 changes: 5 additions & 0 deletions packages/react-native/scripts/xcode/ccache.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# See https://ccache.dev/manual/4.3.html#_configuration_options for details and available options
sloppiness = clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros
file_clone = true
depend_mode = true
inode_cache = true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been contemplating adding the compiler_check = content mentioned in the guide: https://reactnative.dev/docs/build-speed#using-this-approach-on-a-ci .. I believe it'll make compilations marginally slower, but it would make this even more useful on CI.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you checked how cacheable this config is? We've been using this on CI and have typically seen cache hits above 95% when bumping patch releases: https://github.com/microsoft/react-native-test-app/blob/449fe0254d9a8aebe89322fc182ddf7643e07c23/.ccache/ccache.conf

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This config is the one suggested on our "Speeding up your Build phase" guide, just converted from env variables to the ccache conf format. I've seen 100% hit rates on a newly instantiated template while deleting the ios/build directory in between builds.

3 changes: 2 additions & 1 deletion packages/react-native/template/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ target 'HelloWorld' do
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false
:mac_catalyst_enabled => false,
# :ccache_enabled => true
)
end
end
Loading