Mobile Development 15 min read

How SoulAPP Cut iOS Build Times by 30 Minutes: A Deep Dive into Compilation Optimizations

This article details how SoulAPP reduced its iOS clean‑build time from around 30 minutes to just a few minutes by applying precompiled headers, Xcode build‑setting tweaks, component‑based architecture, binary caching with Rugby, and targeted CI optimizations.

Soul Technical Team
Soul Technical Team
Soul Technical Team
How SoulAPP Cut iOS Build Times by 30 Minutes: A Deep Dive into Compilation Optimizations

1. Single‑Project Phase

1.1 Xcode Build Process

Pre‑process: macro expansion, comment removal, header inclusion, producing .i files.

Compile: converting .i to assembly .s files.

Assemble: turning .s into object .o files.

Link: resolving symbols and creating the final executable.

1.2 Compilation‑Option Tweaks

Set Debug Information Format to DWARF to avoid full symbol tables.

Enable Build Active Architecture Only for Debug builds.

Optimize header search paths to eliminate recursive -I entries.

Set Swift Compilation Mode to Incremental for Debug and Whole Module for Release.

Use No Optimization (‑O0) for Debug.

Disable Index‑While‑Building to defer indexing to idle time.

These adjustments saved roughly two minutes per build, with header‑search‑path optimization contributing the most.

2. Componentized Project Phase

2.1 Goals and Benefits

Decouple modules so changes in one do not affect others.

Enable independent compilation of modules, reducing overall build time.

Clarify module boundaries for better teamwork.

Improve project maintainability.

Facilitate reuse of component functionality.

2.2 Binary Compilation Optimization

The team introduced binary caching for many components, similar to cocoapods‑binary. A custom automation script packages components as pre‑compiled frameworks, cutting total compile time by about 20 minutes.

A custom CocoaPods plugin reads component versions from a JSON file linked to the internal R&D platform, allowing seamless switching between source and binary modes.

Component architecture diagram
Component architecture diagram

3. Full‑Source Compilation Optimization

The team evaluated Google Bazel but found the learning curve and integration effort prohibitive. Instead, they adopted the open‑source Rugby project (https://github.com/swiftyfinch/Rugby), which converts CocoaPods pods into pre‑compiled frameworks and caches them.

Typical usage: rugby build --arch arm64 --sdk ios To exclude a pod from caching:

rugby build --arch arm64 --sdk ios -e RangersAppLog

Performance comparison on an Intel machine with 16 GB RAM:

Full source build without Rugby: 1141 s.

Full source build with Rugby: 980 s.

Switching a component source↔binary without Rugby: 1150 s.

Switching the same component with Rugby: 150 s.

The improvement stems from avoiding a full pod install ‑triggered rebuild; only the changed component is recompiled and linked.

Rugby performance chart
Rugby performance chart

4. Ancillary Tools

An internal regex‑based tool scans the codebase weekly for unused classes, resources, and scripts, helping to prevent resource bloat.

Unused resource detection example
Unused resource detection example

5. Summary

By applying stage‑specific compilation strategies—starting with precompiled headers, then modularizing the codebase, and finally leveraging binary caching with Rugby—the clean‑build time was reduced from roughly 30 minutes to a few minutes, dramatically improving developer productivity and CI throughput. Additional tooling such as Xcode Build Timing Summary, Build Timeline, and XCLogParser (https://github.com/MobileNativeFoundation/XCLogParser) were used to measure and analyze build performance.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSbuild optimizationXcodeComponentizationprecompiled headersbinary cachingRugby
Soul Technical Team
Written by

Soul Technical Team

Technical practice sharing from Soul

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.