この記事はコネヒトアドベントカレンダー2022の19日目の記事です。
こんにちは!コネヒトでiOSエンジニアをやっていますyanamuraです。
Apple Siliconを搭載したMacをつかって開発していますが、ママリのiOSアプリはXcodeではRosetta2上でしかビルドが通らずCPU性能を生かしきれていませんでした。
なぜRosetta2上でしかビルドが通らなかったのか
原因はいくつかのライブラリでソースコードではなくバイナリで提供されているものがあり、それらがsimulator 向けarm64のバイナリを含んでいなかったためです。
Apple SiliconはiPhoneのCPUと同じARM系チップの64bit CPUなので、fat binaryにarm64のバイナリが含まれていれば普通にsimulatorでも動くだろうと思っていたのですが、なんとそうはいきません。
なぜなら、arm64向けのbinaryでも、simulatorとdevice用では若干違い(LC_BUILD_VERSION、LC_VERSION_MIN_IPHONEOSの有無)があるためdevice用のarm64のバイナリをsimulatorで利用することはできません。また、これらの両方のarm64バイナリを含んだfat binaryが生成できないため、XCFrameworkにしてかつApple Silicon Macでビルド1してバイナリを生成する必要があるのです。
この辺の話の詳細が知りたい場合はこちらの記事を読んでみてください。 https://bogo.wtf/arm64-to-sim.html
ママリiOSアプリでやったこと
基本的な手順としては以下になります
- XcodeをApple Silicon上で起動(Open using Rosettaのチェックをはずす)してビルド
Ld: XXX, building for iOS simulator, but linking in object file built for iOS, file YYY for architecture arm64
のエラーがでたframeworkをXCFramework版に変更する
2の対応で一部ライブラリがXCFrameworkに対応していないという問題が発生しました。
具体的には、2022年12月現在GoogleMapsSDKがXCFrameworkに対応していませんでした。
GoogleMapsSDKのXCFramework対応
正式版ではXCFrameworkにまだ対応していませんが、ベータ版が公開されていたのでこれを開発用にだけ利用することにしました。
ママリではCocoaPodsを利用しているので、CocoaPodsでのやり方を紹介します。
本番用では以下のようにReleaseビルドのときだけGoogleMapsSDKの正式版を使うようにし
pod 'GoogleMaps', '~> 7.2.0’, :configurations => ['Release']
開発用ではベータ版をダウンロードしたものをprivateリポジトリに作成してつかっています。
pod 'GoogleMaps-dev', :configurations => ['Debug']
改善結果
RosettaとApple Siliconでビルドした時間を比べてみました。
結果としては約140secだったのが約90secとかなりの改善効果を得ることができました。
ビルド時間(sec) | |
---|---|
Rosetta | 140 |
Apple Silicon | 90 |
ビルド時間が早くなるとビルド中にTwitterを見る時間は減りますが生産性があがるので脱Rosettaはおすすめです!
コネヒトでの開発に興味を持っていただいた方はカジュアルにお話しましょう〜 TwitterのDMなどでも大丈夫ですのでお気軽にどうぞ 日本中の家族をITの力で笑顔にしたい、iOSエンジニア募集! - コネヒト株式会社のモバイルエンジニアの採用 - Wantedly
- Apple Silicon Macでビルドする必要が本当にあるかは未確認です。クロスコンパイルできると思うので不要そうな気はしています。↩