iOS - 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** |

## 調査

https://github.com/TakkuMattsu/BinarySize_Carthage_And_Pods

今回は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の方はシュミレータのバイナリが入ってるのかな:thinking:

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">なんかシミュレータビルドも入っちゃってそうな大きさですね。</p>&mdash; ネバダ最速の鈴木 (@toshi0383) <a href="https://twitter.com/toshi0383/status/878585306995335168">2017年6月24日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

### 追記

@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用の２つのバイナリが結合したファットバイナリになっています。（シミュレータビルドした場合はおそらくこれにi386とx86_64が加わると思います）
>
```
xcrun lipo -thin arm64 ./RealmSwift.framework/RealmSwift -output RealmSwift_arm64
```
^ ファットバイナリから特定のアーキテクチャのバイナリだけを切り出すには上記のように書きます。新しくRealmSwift_arm64というファイルが作られます。これはarm64のバイナリだけが含まれています。（lipoでチェックしてみてください）
ファイルサイズは元のファットバイナリからおおよそ半分になります（元のファットバイナリは２つのアーキテクチャが含まれているので）。

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

```bash
# 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
```
```bash
# 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` で特定のアーキテクチャに切り出せるとのこと

```bash
# 切り出し
$ 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と同じになるかと思ったけどはまだサイズが違うな:thinking:

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

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

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

# まとめ

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