🍎

AppleシリコンのMacでシミュレータビルドできない時

2022/01/26に公開

M1 MacなどのAppleシリコンのMacでシミュレータビルドする際にアーキテクチャの問題でmoduleが見つからなくなる場合があります。

Could not find module '<モジュール名>' for target 'arm64-apple-ios-simulator'; found: x86_64-apple-ios-simulator, x86_64, at: /path/to/Debug-iphonesimulator/<モジュール名>.framework/Modules/<モジュール名>.swiftmodule

これはアプリ本体または依存ライブラリ側のプロジェクト設定の EXCLUDED_ARCHS[sdk=iphonesimulator*]arm64 が設定されてしまっていると発生します。

この設定はIntel MacのXcode 12以降でシミュレータビルドするために必要な場合がありました。
今後はAppleシリコンがメインの環境となっていくため、この設定はできる限り削除したほうが良いです。

アプリ本体とライブラリ側を修正できる場合はこの設定を削除するとシミュレータビルドできるようになります。
しかし、特にライブラリ側を修正できない場合はワークアラウンドが必要になります。
CarthageやCocoaPodsを利用している場合によく発生するため、その場合の対処方法を共有します。

Carthage

Carthageでビルドする際に下記のスクリプトを利用します。

carthage.sh
set -euo pipefail

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

echo 'EXCLUDED_ARCHS = ""' >> $xcconfig
export XCODE_XCCONFIG_FILE="$xcconfig"
carthage "$@"

※Intel Macでframeworkとしてビルドをする時のスクリプトとは異なります。
https://github.com/Carthage/Carthage/issues/3201

使い方

./carthage.sh bootstrap --platform iOS --no-use-binaries --use-xcframeworks

xcframeworkの中にarm64x86_64の文字列を含むsimulatorのディレクトリが出来ていればビルド成功です。

% tree Carthage/Build/ -L 2
Carthage/Build/
├── <フレームワーク名>.xcframework
│   ├── Info.plist
│   ├── ios-arm64
│   └── ios-arm64_x86_64-simulator
└── <フレームワーク名>.xcframework
    ├── Info.plist
    ├── ios-arm64
    └── ios-arm64_x86_64-simulator

CocoaPods

Podfileに下記を追記します。

Podfile
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      if `uname -m`.strip == 'arm64'
        config.build_settings['EXCLUDED_ARCHS'] = ''
      else
        config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
      end
    end
  end
end

チームでAppleシリコンとIntel Macの両方を使っている場合もあるため、Appleシリコンの時は EXCLUDED_ARCHS を空にして、Intelの時はシミュレータのみarm64を除外するようにしています。

それ以外

ビルド済みフレームワークを使っている場合などソースコードからビルドできない場合は上記の設定は利用できません。

  • Carthageのbinaryでビルド済みframeworkをDLしている
  • Podの中に(XCFrameworkではない)frameworkへ依存しているライブラリがある
  • 直接frameworkをembedしている 等

その場合はXcodeをRosetta 2で動かしましょう。

Rosetta 2はApple Silicon上でx86_64としてアプリを動かせるエミュレート機能です。
下記のコマンドでインストールできます。

softwareupdate --install-rosetta

設定方法は簡単です。
Xcode.appをCtrl+クリックし、情報を見るを選びます。
開いたウィンドウで「Rosetta を使用して開く」にチェックを入れて、Xcodeを起動するだけです。

こうすることで、Intel Macに近い環境でアプリをビルドできます。
Rosettaの有無を切り替えるのが面倒な人は、Xcodeを複製して片方のみにチェックを入れると使い分けができて便利です。

RosettaをONにすると、ビルド速度が2倍遅くなることがありました。
良い状態とは言えないので、できる限り依存ライブラリ側で対応したいところです。

まとめ

Carthage、CocoaPods、ビルド済みフレームワークの場合の対応方法を紹介しました。

2020年の11月にAppleシリコンのMacが販売され、現在の最新シリーズのMacBook ProはAppleシリコンのみになりました。
Intel用の設定は過去のものとなりつつあるので、できる限りAppleシリコンをベースに環境を整えていきたいですね。

ちなみにSwift Package Manager (SwiftPM) のみを使っていて、依存しているXCFrameworkのアーキテクチャが揃っている場合はこの問題にぶつかることはありません。
SwiftPMを活用できていなかった場合はこの際、移行するのも良いと思います。

Discussion