Xcode 12がリリースされてから、Apple Silicon絡みでCarthageのビルドが通らなくなってしまい、途方に暮れたiOSアプリエンジニアは少なくないと思います。 この問題は公式のリポジトリに乗っているワークアラウンド(シェルスクリプト)で一時的に回避することができます。
Bitrise上でXcode 12を使いたい場合でも
- ワークフローの「Carthage」ステップを「Script」ステップに置き換える
- 「Script」ステップ内で同様のシェルスクリプトを実行する
という風にすればCarthageのビルドが可能になりますが、Carthageのビルドキャッシュが利用できなくなるという問題が発生します。 これは、「Carthage」ステップの中身で実行されているような、キャッシュがあったらビルドをスキップするという処理が欠けているためです。 しかしこれをまた自前で書くのは車輪の再発明です。無駄な工数を割きたくなければ、どうにかして「Carthage」ステップを使いたいと考えるでしょう。
そこでCarthageのビルドキャッシュは活かしつつ、Bitrise上でXcode 12を使えるワークフローを組みました。それについてまとめようと思います。
やりたいこと
- Bitrise上で、Xcode 12を使ってCarthageをビルドする
- Carthageのキャッシュを利用してビルド時間を短縮する
環境
- Bitrise Stack
- Xcode 12.0.x
- macOS 10.15.6(Catalina)
- 各ステップ
- Bitrise.io Cache:Pull 2.1.6
- Carthage: 3.2.3
- Carthage自体は0.35.0
- Bitrise.io Cache:Push 2.3.2
Carthage周りのワークフローの順番
以下のような順番で組みました。
Bitrise.io Cache:Pull ↓
Script (Carthage Workaround) ↓
Carthage ↓
Script (Remove XCODE_XCCONFIG_FILE) ↓
Bitrise.io Cache:Push
ただし、「Bitrise.io Cache:Pull」と「Script (Carthage Workaround)」については、「Carthage」の前にさえあれば順番が入れ替わっても・間に他のステップが入っても大丈夫です。 「Script (Remove XCODE_XCCONFIG_FILE)」と「Bitrise.io Cache:Push」についても同様に「Carthage」の後にあれば良いです。

ステップの説明
Bitrise.io Cache:Pull
名前の通りキャッシュをダウンロードしてくる。特筆事項はなし。
Script (Carthage Workaround)
こちらのワークアラウンドを参考にして、以下のようなスクリプトを実行します
set -euo pipefail
xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX)
# For Xcode 12 make sure EXCLUDED_ARCHS is set to arm architectures otherwise
# the build will fail on lipo due to duplicate architectures.
CURRENT_XCODE_VERSION=$(xcodebuild -version | grep "Build version" | cut -d' ' -f3)
echo "EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200__BUILD_$CURRENT_XCODE_VERSION = arm64 arm64e armv7 armv7s armv6 armv8" >> $xcconfig
echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200 = $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200__BUILD_$(XCODE_PRODUCT_BUILD_VERSION))' >> $xcconfig
echo 'EXCLUDED_ARCHS = $(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))' >> $xcconfig
envman add --key XCODE_XCCONFIG_FILE --value "$xcconfig"
参考元からの変更点は以下の通りです。
trap 'rm -f "$xcconfig"' INT TERM HUP EXITを削除- スクリプトの実行後に、作成したコンフィグファイルを削除するコマンドのよう。
- 作成したコンフィグファイルは後に続くCarthageステップで使用したいので、削除を回避するためにこの行を消した。
export XCODE_XCCONFIG_FILE="$xcconfig"ではなくenvman add --key XCODE_XCCONFIG_FILE --value "$xcconfig"にする- Bitriseではステップごとに環境変数が消えるらしいので、
exportのままだとビルドに失敗する。 envmanを使うことで以降のステップでもその環境変数が使えるようになる。
- Bitriseではステップごとに環境変数が消えるらしいので、
Carthage
- Carthage command to run:
bootstrap - Additional options for
carthagecommand:--platform iOS - Github Personal Access Token:
$GITHUB_ACCESS_TOKEN
にするくらいで、特別な設定は必要ないです。
Script (Remove XCODE_XCCONFIG_FILE)
- Run if previous Step failedを有効にする
以下のスクリプトを実行する
trap 'rm -f "$xcconfig"' INT TERM HUP EXIT
Script (Carthage Workaround)で削除した行をここに追加します。 これを実行しないと(多分)一時的に生成したコンフィグファイルが残り続けるからです。
Bitrise.io Cache:Push
- Run if previous Step failedを有効にする
- Cache pathsに
./Carthage -> ./Carthage/Cachefileを追加する
まとめ
以上のワークフローを組むことで、Bitrise上でXcode 12を使用する場合でも、キャッシュを活かしCarthageのビルド時間を短縮することができました。SIWAやApple Siliconなど色々とAppleに振り回されてしまいますが、がんばっていきましょう。
参考
永田駿平
iOSアプリを作っています
音楽とガジェットが好きです