Fix ccache never being invoked on iOS builds - #58066
Open
janicduplessis wants to merge 1 commit into
Open
Conversation
janicduplessis
force-pushed
the
ccache-resolve-binary-without-build-setting
branch
3 times, most recently
from
August 21, 2026 20:25
c501680 to
2969cb2
Compare
CCACHE_BINARY is set as an Xcode build setting by
set_ccache_compiler_and_linker_build_settings, and ccache-clang.sh reads it as an
environment variable. Xcode does not export build settings into the environment
of a compile task, so it is empty during a build and
exec $CCACHE_BINARY clang "$@"
word-splits down to plain clang. ccache is never invoked, and every translation
unit pays for a shell fork that achieves nothing.
Verified by logging the variable from inside the launcher during a clean
rn-tester build: empty on all 1578 compiler invocations, with 0 cacheable calls.
The build setting came from react#48257, which fixed a real problem -- builds started
from Xcode.app have no Homebrew on PATH. The intent was right, but the delivery
mechanism is not available to a compiler launcher: Xcode passes it neither build
settings nor arguments (a CC value containing arguments fails to spawn).
pod install now generates the launchers into Pods/ with both paths resolved at
install time, and points CC/CXX at those. The generated scripts are the ones this
removes, with CCACHE_BINARY replaced by the resolved ccache path and the config
path absolute rather than derived from $0. Pods/ is regenerated by every pod
install and is gitignored in the app templates, so the paths cannot go stale and
nothing tracked gains a machine-specific value.
Dropping the build setting also stops pod install writing an absolute ccache path
into a tracked project.pbxproj.
rn-tester, clean Debug simulator build, Xcode 26.6, Apple M4:
before 215s, 0 cacheable calls
after, cold 210s, 1578/1582 cacheable
after, warm 19s, 1578/1578 hits
janicduplessis
force-pushed
the
ccache-resolve-binary-without-build-setting
branch
from
August 21, 2026 20:32
2969cb2 to
1674751
Compare
janicduplessis
marked this pull request as ready for review
August 22, 2026 03:11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
ccacheis never invoked on iOS builds, even withUSE_CCACHE=1.set_ccache_compiler_and_linker_build_settingspointsCC/CXXatccache-clang.shand passes the resolved path alongside as a build setting, which the script reads as an environment variable:Xcode does not export build settings into the environment of a compile task, so
CCACHE_BINARYis empty during a build and that line word-splits down toexec clang "$@". The build succeeds and looks normal, so it fails silently: you get plain clang plus a shell fork per translation unit, which is slower than leaving ccache off. Logging the variable from inside the launcher during a clean rn-tester build printed an empty value on all 1578 compiler invocations, with 0 cacheable calls.pod installnow generates the launchers intoPods/with both paths resolved at install time, and pointsCC/CXXat those. The generated script is the one this removes, with$CCACHE_BINARYreplaced by the resolved ccache path and the config path absolute rather than derived from$0:Pods/is regenerated by everypod installand is gitignored in the app templates, so the paths cannot go stale and nothing tracked gains a machine-specific value. Dropping the build setting also stopspod installwriting an absolute ccache path into a trackedproject.pbxproj.There is deliberately no fallback when the ccache path is missing — silently continuing without ccache is the bug being fixed here, so the build fails with the path in the error and
pod installputs it right.I have only tested command-line
xcodebuild, not a build started from Xcode.app.Changelog:
[IOS] [FIXED] - Actually invoke ccache when it is enabled, and stop writing an absolute ccache path into the Xcode project
Test Plan:
rn-tester, clean Debug build for the iOS simulator, Xcode 26.6, Apple M4:
ccache -sWarm run is the same command after
rm -rf /tmp/rnt/Build/Intermediates.noindex, so every path stays identical.ruby utils-test.rb— three tests added for the generated script, covering both compilers and the embedded paths. The suite has 29 pre-existing errors onmain, unchanged by this PR.After
pod install,project.pbxprojcontains noCCACHE_BINARY; previously two occurrences carrying an absolute path.