🦕

PodBuilderを使ってRemoteCacheを導入しビルド時間を改善

2021/08/10に公開

はじめに

この記事はたくさんのCocoaPodsに依存したプロジェクトにおいてフルビルド時間が長すぎるといった悩みを抱えてる方向けの記事です。CocoaPodsを利用している人は一度は通った道かもしれません。導入は比較的簡単で行えるので最終的に導入するかは置いておき、このような問題に悩んでいる方は一度試していただけると嬉しいです。

PodBuilderとは

PodBuilderとはCocoaPodsで導入しているライブラリをpre-build(事前にbuild)し、それを保持することで実際のxcodebuildのタイミングではbuild済みのものにpathを通すだけで良くなるものです。そのため依存している数が多ければ多いほどビルド速度は改善します。

類似のものとの違い

類似のものとしてcocoapods-binary, cocoapods-binary-cache, Rugbyなどが存在しますが今回はこちらを選んだ経緯は以下の理由があります(2021/8現在)

  • cocoapods-binaryはxcode11以降で不具合を確認。継続的なメンテがされていない
  • cocoapods-binary-cacheは中でcocoapods-binaryを利用している
  • Rugbyはpre-buildに失敗するものが多数存在し、また安定して利用できるものではなかった

導入方法

1. インストール

  • Gemfileで管理している場合
gem 'pod-builder' 

その後

$ bundle install
  • Gemfileで管理していない場合
$ gem install pod-builder

https://github.com/Subito-it/PodBuilder#requirements に記載されているようにこちらのversionの基準を満たしている必要があります(2021/8現在)

Ruby 2.6.3 or newer. Cocoapods 1.9.0 or newer

2. initする

$ cd path-to-your-repo;
$ pod_builder init

/PodBuilderというディレクトリが作成されます

3. 設定をいじる

PodBuilderは多種多様のconfigを設定することができます。https://github.com/Subito-it/PodBuilder#configuration-file を参考に自分のプロジェクトにあった設定を行ってください

4. buildする

$ pod_builder build_all

よしなにやってくれます。待ちましょう。終了したらxcodeを開いてbuildしてみてください。

実際の数値

自分が導入したプロジェクト12ライブラリ(22モジュール)に導入した結果がこちらです。
(MBP 13inc メモリ 32GB)

今までのClean Build PodBuilderを利用したClean Build 差分
平均時間(秒) 275秒 194秒 -81秒 (-29%)

注意: 平均の測定には5回ほどそれぞれ実行したものです。差分buildだと差分次第で数値が大きく左右するので掲載していません。また自分が計測に利用したプロジェクトは型推論をあらゆるところで利用しているのでそもそもbuild時間が長くなる傾向にあります。減少した割合ではなく、減少した秒数に着目することをお勧めします。

Git LFSでRemoteCacheする

Podbuilderの問題点としてpre-buildする必要があるのでそのbuild時間が長いという問題点があります。しかもそれは依存しているライブラリのいずれかのversionが変わる毎発生します。その度にlocalでコマンドを打っては待機するのは鬱陶しさもあるのでそこで利用するのがRemoteCacheです。RemoteCacheはbuildした結果をcommit単位でrepositoryに紐づけて管理します。よって依存しているライブラリのいずれかのversionが変わるたびにそのcacheがライブラリの更新者一人が更新してあげることで他のチームメンバーが何度もpre-buildをしてあげる必要がなくなります。

Git LFSの導入方法

1. HomeBrewでインストール

$ brew install git-lfs

2. Git LFSの導入

$ git lfs install

3. Git LFSで管理するファイルを選択

git lfs trackというコマンドを利用し、管理するファイルを選択します。

git lfs track "PodBuilder/Prebuilt/**/*.framework/*"
git lfs track "PodBuilder/Prebuilt/**/*.a"
git lfs track "PodBuilder/dSYM/**/*"

これらのファイルを実行すると.gitattributesというファイルが生成され、trackしたものが追加されていると思います。
(自分の環境ではPodBuilder/Prebuilt以降のファイルが正しくtrackされないという問題が発生しました。また上記で書いたものだとライブラリによっては全てtrackできない問題がありました。その場合はtrackする箇所をPodBuilder/Prebuilt/*みたいにする必要がありそうです。)

追記

FirebaseでCrashlyticsを導入している場合、Build Phaseにrunさせる処理を追加する必要があると思います。それは通常の導入方法では不可能で、以下のissueを参考にすると良さそうです

The script is part of our (@Subito-it) internal release pipeline which is not public. If automating this is not an option you can:

  • Add FirebaseCrashlytics to the skip_pods list. The binaries should be checked out to the usual location under Pods (you'll loose the prebuild performance improvements for just this pod)
  • Manually download the upload-dsym binary from the firebase repo with the aforementioned links

https://github.com/Subito-it/PodBuilder/issues/36

Discussion