Skip to content

ci(ios): cache native compilation with ccache - #1171

Closed
troZee wants to merge 5 commits into
mainfrom
ci/ios-build-cache
Closed

troZee wants to merge 5 commits into
mainfrom
ci/ios-build-cache

Conversation

@troZee

@troZee troZee commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Why

The iOS job spends ~32 min in Build iOS App. React Native core and Hermes are already prebuilt; the time goes to recompiling unchanged third-party pods in Release (RNReanimated 269 files, RNSVG 206, RNScreens 195, RNWorklets 134 …) vs. 42 files for react-native-pager-view.

What

  • ccache via Xcode's compiler launcher, following react-native-reanimated's setup. With USE_CCACHE_LAUNCHER=1, the Podfile sets C_COMPILER_LAUNCHER=<ccache> and CLANG_ENABLE_EXPLICIT_MODULES_WITH_COMPILER_LAUNCHER=YES on the Pods and app projects. Explicit modules stay on.
    • RN's own USE_CCACHE CC wrapper isn't used: it silently runs plain clang on Xcode 26 because CCACHE_BINARY isn't exported to the wrapper (Fix ccache being silently bypassed on iOS builds react/react-native#56612).
    • ccache is configured with --set-config, mirroring RN's ccache.conf, which only applies to that wrapper.
    • The cache (~/Library/Caches/ccache) is saved from main only; PRs restore from it. ccache --show-stats -v is printed.
  • COMPILER_INDEX_STORE_ENABLE=NO passed via --extra-params, since CI never uses the index.
  • ruby/setup-ruby with bundler-cache to stop reinstalling gems on every run.

Local builds are unaffected (the launcher is only enabled via env in CI).

Results

With the previous wrapper-based iteration of this PR, a warm cache gave 918/918 hits and a 9.4 min build (from ~32 min). Results for the launcher setup will be added after a warm re-run.

Before merging

  • Remove the temporary pull_request condition on "Save ccache" (it's only there to measure warm builds on this PR).

🤖 Generated with Claude Code

Most of the ~32 min iOS build is recompiling unchanged third-party pods
(Reanimated, SVG, Screens, Worklets) in Release. Route clang through
ccache via USE_CCACHE and persist the cache between runs, skip index
store generation, and cache Ruby gems with setup-ruby.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The workflow changes are coherent, scoped to CI, and use safe cache restoration and persistence behavior.

0 open findings

What changed in this PR

Adds ccache-based native compilation caching to reduce iOS CI build times.

Changes:

  • Configures Ruby/Bundler and ccache.
  • Restores and saves compilation caches around the Release build.
  • Disables unnecessary compiler index generation.
File Description
.github/​workflows/​ios.yml Adds Ruby dependency caching and iOS native compilation caching.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

🔴 e2e: no tests ran

ENGINE_FAILURE (launch) devices failed: Failed to start daemon Hint: Daemon startup did not establish a reachable owner. Retry with --debug and inspect daemon diagnostics. Before upgrading, stop all older clients and daemons with their original CLI and prevent th…

e2e 0.18.0 · 31.8s · 2 targets (ios, android) · run artifacts

troZee and others added 4 commits October 9, 2026 12:03
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Xcode does not export the CCACHE_BINARY build setting to the compiler
wrapper, so RN's ccache-clang.sh ran plain clang. Backport
react/react-native#56612 via a bun patch and drop the explicit
modules workaround.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow react-native-reanimated's setup: set ccache as C_COMPILER_LAUNCHER
with explicit modules kept on, instead of RN's CC wrapper. This drops the
react-native patch for the wrapper's CCACHE_BINARY bug. ccache is
configured with --set-config since RN's ccache.conf only applies to the
wrapper, and the cache is only saved from main (plus this PR, temporarily).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@troZee troZee closed this Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants