CarthageのXcode 12エラー: This usually indicates that project itself failed to compile.を直す

Xcode 12でCarthageでライブラリーをビルドしようとしたら、ビルドが失敗して以下のようなエラーを出力されました。
Carthageのバージョンは0.36.0で試しています。

This usually indicates that project itself failed to compile. 
Please check the xcodebuild log for more details: /var/folders/jm/pyy6p95j177_btm91tj0mkdm0000gn/T/carthage-xcodebuild.WPi9jL.log

このエラーは下記issuesから引用
https://github.com/Carthage/Carthage/issues/3019

実行環境

  • Xcode 12.4
  • Carthage: 0.36.0 -> 0.37.0

エラーの原因

Xcode 11までは実機用のビルドのみにarm64アーキテクチャが含まれていましたが、Xcode 12からは、シュミレーター用のアーキテクチャにもarm64が含まれるようになりました。
一方でCarthageはライブラリーをサポートされるすべてのアーキテクチャでビルドします。
このため、Xcode 12でビルドするとarm64用のバイナリが実機用とシュミレーター用で重複してしまいます。
そのためビルドが失敗します。

公式のワークアラウンド(0.36.0バージョン)

これを解決するため、Carthage公式からワークアラウンドが提供されました。
次のスクリプトをcarthage.shなどのファイル名で作成します。

# carthage.sh
# Usage example: ./carthage.sh build --platform iOS

set -euo pipefail

xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX)
trap 'rm -f "$xcconfig"' INT TERM HUP EXIT

# 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

export XCODE_XCCONFIG_FILE="$xcconfig"
carthage "$@"

このスクリプトはコンパイルする際にシュミレーター用のarm64アーキテクチャを取り除く処理をしています。

carthage.shの実行権限を付与します。

$ chmod +x /usr/local/bin/carthage.sh

そして、carthageコマンドの替わりにcarthage.shを使うようにします。
つまり

$ carthage bootstrap --platform iOS --cache-builds

のように実行していたコマンドを

$ carthage.sh bootstrap --platform iOS --cache-builds

のように実行します。
オプションもそのまま使えます。

ワークアラウンドの副作用

carthage.shでやっているのはコンパイルする際ににシュミレーター用のarm64アーキテクチャを取り除く処理です。
そのため、carthage.shでコンパイルされたフレームワークはApple SiliconのMacでは利用できなくなります。

真の解決策(0.37.0バージョン)

carthage.shスクリプトはあくまでワークアラウンドです。
2021年2月2日にCarthageは0.37.0バージョンをリリースし、それを使うことが推奨されています。

Carthageバージョン0.37.0から依存ライブラリーをXCFrameworkでビルドできるようになりました。
XCFrameworkはXcode 11から登場した、複数のフレームワークを1つにまとめられる仕組みです。
CarthageからXCFrameworkでライブラリーをビルドすることでXcode 12でも利用できるようになります。

まずはcarthageコマンドをアップデートしましょう。
brewを使っているならupgradeコマンドを実行します。

$ brew upgrade carthage

一応バージョンを確認しておきましょう。

$ carthage version
0.37.0

そして--use-xcframeworksオプションを使ってXCFrameworkでライブラリーをビルドします。

$ carthage bootstrap --platform iOS --use-xcframeworks 

carthage.shを使う必要はもうありません。

まとめ

Xcode 12でシュミレーター用にarm64アーキテクチャが追加されるようになり、Carthageでビルドができなくなりました。
Carthage公式でワークアラウンドが提供されましたが、Apple SiliconのMacでは利用できない制限がありました。
0.37.0からXCFrameworkでビルドできるようになりました。
XCFrameworkでビルドすることでXcode 12でCarthageが使えるようになります。

宣伝

インプレスR&D社より、「1人でアプリを作る人を支えるSwiftUI開発レシピ」発売中です。
「SwiftUIでアプリを作る!」をコンセプトにSwiftUI自体の解説とそれを組み合わせた豊富なサンプルアプリでどんな風にアプリ実装すればいいかが理解できる本となっています。
iOS 14対応、Widgetの作成も一章まるまるハンズオンで解説しています。
SwiftUIを学びたい方、ぜひこちらのリンクをチェックしてください!




https://nextpublishing.jp/book/12491.html

参考文献