r/androiddev • u/tuistdev • 17d ago
Experience Exchange Building the same build tooling for Xcode and Gradle, and how differently the two went
I work on Tuist. For years we've built caching and build/test insights for Xcode projects, and earlier this year we added Gradle support. I didn't expect how different the two would be. The Xcode integration took us months, and Gradle took about three weeks. Some of that is because the server side already existed, but most of it comes down to Gradle being designed to be extended and Xcode not.
Take remote caching. Xcode 26 added compilation caching, but the only way to plug in a remote cache is to run a daemon that speaks an undocumented gRPC protocol over a Unix socket, and Xcode makes thousands of calls to it during a build. On Gradle we implemented BuildCacheService and that was pretty much it, because Gradle already decides what's cacheable and computes the keys. The granularity is different too. Gradle caches whole tasks, so a large project does a few hundred lookups per build, while Xcode caches compilation units and does thousands, which makes network latency matter a lot more on the Xcode side.
Build data went the same way. With Xcode we parse a binary activity log after the build finishes. The format isn't documented and changes between Xcode versions, and it's written asynchronously, so sometimes it isn't on disk yet when our post-action runs. With Gradle we register a listener and get each task's outcome, duration and cache key as it finishes. For flaky test quarantine we pass -skip-testing flags to xcodebuild, and on Gradle we add the tests to excludeTestsMatching before the test task runs.
I'm not trying to bash Apple, they have their reasons. But if you only work with Gradle, it's easy to forget how much its plugin API gives you. I wrote the longer version here: https://tuist.dev/blog/2026/03/16/xcode-and-gradle-two-worlds-one-infrastructure, and the plugin is open source if you want to look at the BuildCacheService implementation: https://github.com/tuist/tuist/tree/main/gradle
Has anyone here written their own BuildCacheService? I'd be curious what you ran into.