Skip to content

[build-tools] Add local Xcode compilation cache - #4204

Draft
sjchmiela wants to merge 3 commits into
mainfrom
stanley/xcode-local-compilation-cache
Draft

[build-tools] Add local Xcode compilation cache#4204
sjchmiela wants to merge 3 commits into
mainfrom
stanley/xcode-local-compilation-cache

Conversation

@sjchmiela

@sjchmiela sjchmiela commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Why

Xcode 26 has a compilation cache, but C and Objective-C cache tasks require a remote service path. EAS needs a local-only cache that can be archived after a build and restored on another CI machine. This must not require Bazel, Tuist, or a remote CAS service.

The deprecated worker CacheManager is not used for this feature. The implementation uses the active build-cache path that already restores and saves ccache and the Gradle build cache.

How

  • Add a local CAS shim that loads Apple's Xcode CAS plugin.
  • Forward every llcas_* operation to Apple's implementation.
  • Accept and discard only the remote-service-path option. This makes Xcode schedule C, Objective-C, PCH, and PCM cache tasks without remote I/O.
  • Enable the feature explicitly with EAS_BUILD_XCODE_COMPILATION_CACHE=1.
  • Build one arm64 shim during iOS worker packaging and store it next to record-sim.
  • Load Apple's CAS plugin from the selected Xcode at build time, so the bundled shim does not bind to one Xcode installation.
  • Validate the bundled shim with Xcode's llvm-cas before enabling the cache. Disable compilation caching when the shim is missing or incompatible.
  • Set GYM_DERIVED_DATA_PATH so Fastlane and cache restore/save use the same ios/build directory.
  • Store the cache in ios/build/CompilationCache.noindex.
  • Restore and save it through restoreBuildCache.ts and saveBuildCache.ts, next to ccache and Gradle cache handling.
  • Run ccache and Xcode cache restore/save operations in parallel.
  • Use a separate cache key that includes the exact Xcode version and dependency lock hash.
  • Keep sparse-file archive and restore handling inside the Xcode compilation-cache module. The generic cache helpers are unchanged.
  • Support both the traditional iOS builder and the EAS build step path.

Test Plan

  • Build the C shim as arm64 with -Wall -Wextra -Werror and confirm it links only to libSystem.
  • Validate the shim with llvm-cas and ingest a file into a temporary CAS.
  • Build a temporary Objective-C Xcode project twice and confirm that the second clean build replays cache hits.
  • Archive, remove, restore, and reuse CompilationCache.noindex in another clean build.
  • Archive and restore a real 122 MB Xcode CAS directory:
    • archive: about 1 second
    • restore: about 1 second
    • all 35 files restored
  • Benchmark seven cold and seven warm clean builds:
    • cold median: 1.821 seconds
    • warm median: 0.955 seconds
    • about 48% faster for the test project
  • Run all build-tools unit tests:
    • 107 suites passed
    • 1,018 tests passed
  • Run build-tools type checking.
  • Validate the worker packaging shell script.
  • Run repository lint and format checks. Lint completes with 20 existing unrelated warnings and zero errors.

@sjchmiela
sjchmiela force-pushed the stanley/xcode-local-compilation-cache branch from 3d98633 to abe2ae6 Compare August 14, 2026 15:26
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.63551% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.56%. Comparing base (3cc58e5) to head (8a04ae6).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
packages/build-tools/src/ios/compilationCache.ts 84.49% 9 Missing ⚠️
...ild-tools/src/steps/functions/restoreBuildCache.ts 65.22% 8 Missing ⚠️
.../build-tools/src/steps/functions/saveBuildCache.ts 75.00% 5 Missing ⚠️
...ckages/build-tools/src/steps/utils/ios/fastlane.ts 25.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4204      +/-   ##
==========================================
+ Coverage   63.53%   63.56%   +0.03%     
==========================================
  Files        1028     1029       +1     
  Lines       46905    47019     +114     
  Branches     9842     9862      +20     
==========================================
+ Hits        29798    29883      +85     
- Misses      17005    17034      +29     
  Partials      102      102              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sjchmiela
sjchmiela force-pushed the stanley/xcode-local-compilation-cache branch 2 times, most recently from 9e252c9 to 25c441b Compare August 14, 2026 16:06
@sjchmiela
sjchmiela force-pushed the stanley/xcode-local-compilation-cache branch from 25c441b to aa6e610 Compare August 14, 2026 16:15
@github-actions

Copy link
Copy Markdown

❌ It looks like a changelog entry is missing for this PR. Add it manually to CHANGELOG.md.
⏩ If this PR doesn't require a changelog entry, such as if it's an internal change that doesn't affect the user experience, you can add the "no changelog" label to the PR.

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.

1 participant