Xcode コンパイルキャッシュの原理とヒット条件対照表
Xcode コンパイルキャッシュの実体は、主に Derived Data 配下のオブジェクトファイル・Swift モジュール・索引・ビルド記述子です。入力(ソース、生成コード、OTHER_SWIFT_FLAGS 等)とツールチェーン指紋が一致すると再コンパイルを省略しやすくなります。リモート Mac の iOS CI では、ジョブごとに作業ディレクトリを捨てる設計だとパスが揺れ、ヒット率が落ちがちです。
| 条件 | キャッシュ命中への影響 | 運用上のコツ |
|---|---|---|
| Xcode/Swift の版 | 不一致はほぼミス | xcodebuild -version と swift --version をキャッシュ鍵に含める |
| Derived Data パス | 固定パスで安定 | -derivedDataPath "$CI_DERIVED_DATA" を必ず明示 |
| SwiftPM 依存 | Package.resolved 変化で無効化 |
-clonedSourcePackagesDirPath "$CI_SPM_DIR" で共有キャッシュ |
| ビルド設定切替 | Debug⇄Release 等で無効化 | シナリオ別に DD サブディレクトリを分離 |
キャッシュ鍵例:runner.os + lock ファイルのハッシュ + Xcode ラベル + scheme。CI 依存プレプルと版整合と併用しやすいです。
リモート Mac ノードのウォームアップとクリーンアップ戦略
同一 runner を長期利用するとビルド加速に効きます。ウォームアップは依存解決+通常 build、クリーンアップはLRUで古い DD から削除するのがバランス良いです。
- ツールチェーン固定:
export DEVELOPER_DIR=/Applications/Xcode_16.2.app/Contents/Developer - SPM 事前解決:
xcodebuild -scheme "YourApp" -resolvePackageDependencies -clonedSourcePackagesDirPath "$CI_SPM_DIR" -derivedDataPath "$CI_DERIVED_DATA" - ビルド本体(シミュレータ例):
xcodebuild -scheme "YourApp" -destination 'platform=iOS Simulator,name=iPhone 16' -derivedDataPath "$CI_DERIVED_DATA" -clonedSourcePackagesDirPath "$CI_SPM_DIR" build - 索引負荷を下げたい場合:
export COMPILER_INDEX_STORE_ENABLE=NO(CI のみ。ローカル開発とは切り替え)
- 使用率警告:データボリュームが 85% 超 → ログ通知。runner の安定性監視に連動。
- 積極クリーン:90% 近傍、または空きが 20 GB 未満 → 当該プロジェクトの DerivedData サブフォルダから削除(全消しは最終手段)。
- 調査用ワンライナー:
du -sh "$CI_DERIVED_DATA"/* 2>/dev/null | sort -hr | head - シミュレータ肥大化:
xcrun simctl delete unavailableを週次メンテに組み込み
clean build とのパラメータの取捨
常時 clean は再現性と引き換えにコスト増、常時増分は速いがキャッシュ破損リスクあり。下表を PR/ナイトリー/提出用に割り当てます。
| パイプライン | 推奨スタンス | 主な xcodebuild 側の意思決定 |
|---|---|---|
| PR・フィーチャー | 増分優先 | 同一 -derivedDataPath を維持、clean しない。失敗時のみ部分 clean。 |
| ナイトリー統合 | 週次またはタグ付きで full clean | xcodebuild clean -scheme ... または DD サブフォルダ削除をスケジュール。 |
| リリース・アーカイブ | クリーン寄り | 成果物の再現性優先。キャッシュは「依存取得」に限定し、コンパイルはクリーンも検討。 |
| 署名/埋め込みエラー多発時 | スコープ限定 clean | プロビジョニングや Entitlements 変更後は当該 scheme の DD のみ削除して再実行。 |
Pods を使う場合は pod install のキャッシュ復元と DerivedData を同じ runner で回すと、ヘッダ検索パスまわりのミスマッチが減ります(詳細はGit・CocoaPods 加速ガイド)。
失敗フォールバックとディスク水位しきい値 FAQ
フォールバック順:(1) 同一 DD でリトライ → (2) 当該プロジェクト DD のみ削除 → (3) 新規 -derivedDataPath → (4) runner ローテ/全 DD 削除。
- 空き容量(MB)確認:
df -m "$CI_DERIVED_DATA" | awk 'NR==2{print $4}'— しきい値例:15360 MB(約15GB)未満で warn、10240 MB 未満でビルド中止。 - 使用率(%)アラート:
df -h "$CI_DERIVED_DATA" | awk 'NR==2{gsub(/%/,"",$5); print $5}'— 85 超で通知、92 超で新規ジョブ抑制。 - リトライ回数:コンパイル系は 2〜3 回、指数バックオフ 30〜90 秒。同時多発ビルドで IOPS が頭打ちの場合は並列度を下げる。
Q. ModuleCache エラー増
A. ツールチェーン更新直後に多い。該当 DD 削除と DEVELOPER_DIR の単一化を確認。
Q. 並列でリンク失敗
A. 同一 DD を複数プロセスで共有していないか確認。ジョブ別サブパスまたはロックを。
Q. 効果をメトリクス化
A. ログのコンパイル数・経過時間と DD サイズを可視化。プル安定性 FAQ、ヘルプセンターも参照。
まとめ
まとめ:-derivedDataPath 固定とツールチェーン入りキャッシュ鍵でXcode コンパイルキャッシュの命中率が上がります。Derived Data は SPM 解決+build でウォームアップ、ディスクは 85%/90% と空き GB の二段管理が実用的です。PR は増分、リリースは clean 寄り、異常時は段階フォールバックでノード安定性を維持します。専用リモート Macの検討はMacPull ホーム、料金プラン、購入、ヘルプ、ブログ一覧から(ログイン不要)。