CarthageとCocoaPodsでバイナリのサイズが変わってる!?と思ったら変わってなかった


タイトルで落ちているのですが、一応調べたので備忘録ついでにまとめておきます。

概要

アプリのビルド時間短縮のためCarthageへの移行をしていた際に、同じライブラリでもCarthageとCocoaPodsで違っていたので調査しました。

調査した際のコードはGitHubに上げています。
https://github.com/TakkuMattsu/BinarySize_Carthage_And_Pods

結果

Xcodeでビルドして直接インストールしたものはサイズが変わっていますが、Archiveしてインストールしたものはサイズが同じになりました。

つまりリリース時は一緒になる

  • Xcode8.3.3
  • Carthage0.23.0
  • CocoaPods1.2.1
  • Swift3.1
  • Realm2.8.3
環境 アプリのサイズ 
Pods 41.1MB 
Carthage 81.3MB
Pods(Archive) 23.8MB
Carthage(Archive) 23.9MB

調査

今回はRealmで試しました。

  • Single View Applicationを使いプロジェクトを作成
  • PodsはPodfileにpod 'RealmSwift'を書いてpod updateを実施
  • CarthageはCartfileにgithub "realm/realm-cocoa"を書いてcarthage updateを実施

Xcodeでビルドして直接インストールした場合

Xcodeでビルドして直接インストールした場合はサイズに違いが出ました。

環境 アプリのサイズ 
Pods 41.1MB 
Carthage 81.3MB

以下のアドバイスを頂いけど調べ方が分からない...
Xcodeからインストールした場合、Carthageの方はシュミレータのバイナリが入ってるのかな

追記

@kishikawakatsumi さんよりコメントを頂きました。

おそらくXcode経由でインストールした際にはファットバイナリのままで、iTunes経由でインストールした際には対象のデバイスのアーキテクチャのみのバイナリになってますね。
サイズが見られているなら実際のファイルにアクセスできているでしょうから、lipoコマンドでファットバイナリかどうかや、ファットバイナリから特定のアーキテクチャだけ切り出すことができます。

xcrun lipo -info ./RealmSwift.framework/RealmSwift 
Architectures in the fat file: ./RealmSwift.framework/RealmSwift are: armv7 arm64 

^ のように使用します。Xcode付属のlipoとシステムのlipoは若干異なるのでxcrunをつけて実行します。
上記は普通にデバイスビルドした場合で、armv7用とarm64用の2つのバイナリが結合したファットバイナリになっています。(シミュレータビルドした場合はおそらくこれにi386とx86_64が加わると思います)

xcrun lipo -thin arm64 ./RealmSwift.framework/RealmSwift -output RealmSwift_arm64

^ ファットバイナリから特定のアーキテクチャのバイナリだけを切り出すには上記のように書きます。新しくRealmSwift_arm64というファイルが作られます。これはarm64のバイナリだけが含まれています。(lipoでチェックしてみてください)
ファイルサイズは元のファットバイナリからおおよそ半分になります(元のファットバイナリは2つのアーキテクチャが含まれているので)。

自分の試したやつで叩いてみました。

# Carthage
$ xcrun lipo -info CarthageRealm.app/Frameworks/Realm.framework/Realm
Architectures in the fat file: CarthageRealm.app/Frameworks/Realm.framework/Realm are: armv7 arm64
# サイズ確認
$ du -sh CarthageRealm.app/Frameworks/Realm.framework/Realm
47M     CarthageRealm.app/Frameworks/Realm.framework/Realm
# Pods
$ xcrun lipo -info PodsRealm.app/Frameworks/Realm.framework/Realm
Non-fat file: PodsRealm.app/Frameworks/Realm.framework/Realm is architecture: arm64
# サイズ確認
$ du -sh PodsRealm.app/Frameworks/Realm.framework/Realm
11M     PodsRealm.app/Frameworks/Realm.framework/Realm

Xcodeからビルドした場合、Carthageの方はファットバイナリでPodsの方はノンファットバイナリってことみたいです。

xcrun lipo -thin arm64 で特定のアーキテクチャに切り出せるとのこと

# 切り出し
$ xcrun lipo -thin arm64 CarthageRealm.app/Frameworks/Realm.framework/Realm -output Carthage_modify_arm64_realm
# 確認
$ crun lipo -info Carthage_modify_arm64_realm
Non-fat file: Carthage_modify_arm64_realm is architecture: arm64
# サイズ確認
$ du -sh Carthage_modify_arm64_realm
24M     Carthage_modify_arm64_realm

うーむ、ファットバイナリでなくしたらPodsと同じになるかと思ったけどはまだサイズが違うな

ArchiveしてiTunesからインストールした場合

ArchiveしてiTunesからインストールした場合はアプリのサイズはほぼ一緒になりました。

環境 アプリのサイズ 
Pods(Archive) 23.8MB
Carthage(Archive) 23.9MB

まとめ

ひとまずCarthageとPodsでバイナリのサイズに違いは出ないことがわかったので一安心。