[iOS][Carthage] ビルド時間短縮のため外部ライブラリの一部をCocoaPodsからCarthageに移行した
プロジェクトが育つにつれビルド時間が長くなって開発効率が落ちてきていたので、改善の一環としてネックとなっていたCocoaPods管理下のライブラリ群の一部をCarthageに移管した。
今更感はさておき復習も兼ねて記事化と共有。
1. Carthage インストール
Carthageが入っていない場合、インストール
$ brew update
$ brew install carthage
Carthageのバージョンが古い場合、アップデート
バージョン確認
$ carthage version
0.29.0
アップデート
$ brew upgrade carthage
.pkgでもインストール可能な模様。
https://github.com/Carthage/Carthage/releases
2. Cartfileの作成
Carthageのパッケージファイルを作成。
$ vi Cartfile
パッケージマネージャ | CocoaPods | Carthage | Swift Package Manager |
---|---|---|---|
パッケージファイル | Podfile | Cartfile | Package.swift |
ロックファイル | Podfile.lock | Cartfile.resolved | Package.pins |
3. PodfileからCartfileに移行
3-1. Cartfileの編集
指定方法は極めてシンプル。
とりあえずAlamofireから入れてみる。
github "Alamofire/Alamofire"
バージョン指定もpodと書き方は同じ
# 4.5.0固定
github "Alamofire/Alamofire" == 4.5.0
# 4.5以降
github "Alamofire/Alamofire" >= 4.5
# 4.5と互換性があるバージョン
github "Alamofire/Alamofire" ~> 4.5
参考: ライブラリ管理ツールCarthageのCartfileの書き方
但し、互換指定に関してCocoaPodsとは結果が異なるため注意が必要。
3-2. ビルド
Cartfileを保存したら carthage update
を実行してビルド。
$ carthage update --platform iOS
--platform iOS
はプラットフォームの指定。macOSやwatchOSが必要な人は指定なしで。
--cache-builds
というオプションもあってビルド済のライブラリはスキップしてくれる。ビルドキャッシュのバージョンとかもみてくれている模様。 xcode-select --switch
した時も大丈夫。
--no-use-binaries
はGitHubに上がっているバイナリデータを使わないオプション。0.20.0以降、このオプションが無くても自動的に判定してSwiftバージョンが異なる場合などソースコードからビルドしてくれるようになったらしいのでこれはもう不要。
carthage update
と carthage bootstrap
は何が違うのかというと、
update
はCartfileの記述からCartfile.resolvedにバージョンを書き込むのでアップデートされる可能性がある。
bootstrap
はCartfile.resolvedで指定されているバージョンを使用する。
単にcheckoutしてビルドしたい時とか、CIでの実行は以下で実行するようにした。
$ carthage bootstrap --platform iOS --cache-builds
ビルドが終わると プロジェクトルート/Carthage/Build/iOS
以下に.frameworkができている。
3-3. Linked Frameworks and librariesに追加
プロジェクト > ターゲット > Generalタブ > Linked Frameworks and libraries に3-2でビルドした.frameworksを追加する。
+
> Add Other...
を押して プロジェクトルート/Carthage/Build/iOS/Alamofire.framework
を選択し追加。
直接FinderからDropしてもOK。
メインターゲットに自前のEmbed Frameworkを含んでいてそれも同じframeworkに依存している場合、そのframeworkのターゲット > Generalタブ > Linked Frameworks and libraries にも同様に追加しておく。
あとUnit TestやUI Testのターゲットにも同様に追加しておきましょう。
- アプリのターゲット > Generalタブ > Linked Frameworks and libraries
- Unit Testのターゲット > Generalタブ > Linked Frameworks and libraries
- UI Testのターゲット > Generalタブ > Linked Frameworks and libraries
- 自前frameworkのターゲット > Generalタブ > Linked Frameworks and libraries
3-4. Build Phaseの追加
プロジェクト > ターゲット > Build PhaseにRun Scriptを追加する。
Shellの内容
/usr/local/bin/carthage copy-frameworks
Input Filesの追加
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
UI Testのターゲットにも同様の追加が必要。
3-5. podからの除外
Podfileの pod 'Alamofire'
の記述を削除して pod install
しておく
4. lint対象からの除外
lintツールとか入れている場合、そのままビルドするとframework内の記述が怒られてしまいビルドが通らないので、対象から除外しておく必要がある。
SwiftLintの場合
...
excluded:
- Pods
- Carthage # 追加
...
xcode-select
複数のXcodeバージョンを使い分けている人は、意図せずxcode-selectの向き先が想定していないXcodeバージョンを向いていることがあり、プロジェクトの設定とframeworkのSwiftのバージョンが合わない場合にビルドエラーになるので要チェック。
確認
$ xcode-select -print-path
変更
$ sudo xcode-select --switch /Applications/Xcode8.3.3.app
5. ライセンス表示
CocoaPodsでは自動的にライセンス表示のためのplistが作られるのでPodfileでSettings.bundle内にコピーすれば良いだけだったが、Carthageはシンプルが故に自前で行う必要がある。
併用しているのでCocoaPodsが作ったplistをベースにCarthage管理下のライブラリのライセンス情報を追加して新たなplistを生成してSettings.bundle内にコピーするシェルを書いてみた。(もっと効率良い書き方や方法があったらお教えください)
#!/bin/sh
if [ $# -ne 1 ]; then
echo "Error: Parameter is required."
exit 1
fi
# Move to project root directory
cd $1
# Copy plist file to Settings.bundle
inPlistPath="Pods/Target Support Files/Pods-<APP_NAME>/Pods-<APP_NAME>-acknowledgements.plist"
outPlistPath="<APP_NAME>/Settings.bundle/Acknowledgements.plist"
cp "$inPlistPath" $outPlistPath
# Read contents of Carthage/Checkouts
directories="Carthage/Checkouts/*"
# Add license to plist
for directory in $directories; do
licenseTextPath="${directory}/LICENSE"
licenseText=`cat $licenseTextPath`
libraryName="`basename $directory`"
item="<dict><key>FooterText</key><string>${licenseText}</string><key>Title</key><string>${libraryName}</string><key>Type</key><string>PSGroupSpecifier</string></dict>"
keyPath="PreferenceSpecifiers.0"
# Insert to plist file
plutil -insert $keyPath -xml "$item" $outPlistPath
done
これをメインターゲット > Build Phase > New Run Script Phase して実行しておけば、ビルドごとに勝手に上書きされるようになる。
${PROJECT_DIR}/acknowledgements.sh ${PROJECT_DIR}
6. プロジェクトをビルド
念のためCleanしてからビルド。
他のライブラリも同様に移行したい場合、ステップ3を行う。
7. その他
自分の場合、移行に伴い下記のタスクも必要になった。
- CI環境でCarthageに対応しておく。
- プロジェクトに README.md とか含んでいる場合、Carthageの記述を追加しておく。
感想
下記のライブラリをCarthageにしたがビルドが非常に早くなった!
github "Alamofire/Alamofire"
github "realm/realm-cocoa"
github "johnsundell/unbox"
github "mxcl/PromiseKit"
github "SnapKit/SnapKit"
自前で対応しないとならない部分もあるけど、いろいろ勝手に作られないし、何よりもわかりやすい。将来的にはCocoaPodsは廃止したいなぁ。
Bitrise でもCarthageステップを追加して対応し、2回目以降はworkflow実行時間が30%ほど削減できた
Author And Source
この問題について([iOS][Carthage] ビルド時間短縮のため外部ライブラリの一部をCocoaPodsからCarthageに移行した), 我々は、より多くの情報をここで見つけました https://qiita.com/a_jike/items/65147ccc8783f19d4a4a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .