Uh oh!
There was an error while loading. Please reload this page.
Add CCACHE_BINARY path to Xcode build settings and use it in ccache scripts - #48257
Add CCACHE_BINARY path to Xcode build settings and use it in ccache scripts#48257ste7en wants to merge 2 commits into
Conversation
…ccache_compiler_and_linker_build_settings
The `$CCACHE_BINARY` env is set at `pod install` time when the USE_CCACHE flag is 1. This fixes ccache not found react#46126 as the ccache path is directly used.
facebook-github-bot
commented
Dec 13, 2024
Hi @ste7en! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
cipolleschi
commented
Dec 16, 2024
@ste7en thanks for the fix! Could you sign the CLA, please? Otherwise I'm not allowed to import the PR in our repo! |
ste7en
commented
Dec 16, 2024
Sure @cipolleschi, didn't know about the CLA. Just signed it, thanks! |
facebook-github-bot
commented
Dec 16, 2024
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
facebook-github-bot
commented
Dec 16, 2024
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
facebook-github-bot
commented
Dec 16, 2024
@cipolleschi merged this pull request in d31ac83. |
react-native-bot
commented
Dec 16, 2024
This pull request was successfully merged by @ste7en in d31ac83 When will my fix make it into a release? | How to file a pick request? |
@ste7en Thanks for the fix. Works great. But I wonder is it okay to store local setup ccache path into project.pbxproj? Maybe it's worth to consider moving this variable to .xcode.env generating script (with-environment.sh) |
ste7en
commented
Jan 28, 2025
Yes @mefjuu, I agree it would be a much cleaner solution |
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, and ccache reported 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, so looking ccache up there finds nothing. The intent was right, the delivery mechanism just is not available to a compiler launcher: Xcode passes it neither build settings nor arguments (a CC value containing arguments fails with 'unable to spawn process'). So pod install now generates the launchers into Pods/ with the resolved path baked in, and points CC/CXX at those. Pods/ is regenerated by every pod install and is gitignored in the app templates, so the path can never go stale and nothing tracked gains a machine-specific value. The shipped scripts existed only to be pointed at by the mechanism that never worked, so they are removed. 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 232s, 1578/1582 cacheable after, warm 18s, 1578/1578 hits
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
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
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
Summary:
When building a react native app from Xcode and ccache has been set to be used, the
ccache-clang.shandccache-clang++.shscripts cannot findccache, because Xcode PATH does not include ccache binary.What I've done is setting a
CCACHE_BINARYuser-defined Xcode setting containing the result of executingcommand -v ccacheduring pod install execution and directly calling it in ccache scripts, set by ReactNativePodsUtils when ccache is enabled.Fixes#46126
Changelog:
[IOS] [FIXED] - fix ccache not found error exporting ccache binary path as Xcode user-defined setting to be used by ccache scripts
Test Plan:
Correctly builds helloworld and RNTester apps using ccache by enabling it at pod install time:
USE_CCACHE=1 pod install.