XcodeでiOS Simulator向けにビルドした際、「building for iOS Simulator, but linking in object file built for iOS」というリンカーエラーが表示されることがあります。
このエラーは、シミュレータ向けに作成中のアプリへ、実機iOS向けとしてビルドされたライブラリやオブジェクトファイルをリンクしようとしたときに発生します。
原因
主な原因は、リンク対象のバイナリが現在のビルド先と互換性のないプラットフォーム向けに作成されていることです。特に、古い静的ライブラリやframeworkをApple Silicon Mac上のiOS Simulatorで利用すると発生しやすくなります。
arm64というCPUアーキテクチャ名が同じでも、iOS実機向けarm64とiOS Simulator向けarm64は別のプラットフォームとして扱われます。
代表的な発生状況
- 実機iOS向けにのみビルドされたframeworkをSimulatorで使用している
- 古いベンダーSDKがXCFrameworkに対応していない
- CocoaPodsや手動追加したバイナリにSimulator用sliceが含まれていない
- Apple Silicon Macへの移行後、Intel Macでは発生しなかった問題が出るようになった
- 独自frameworkをdevice用だけでビルドして配布している
確認手順
1. エラー対象のライブラリ名を確認する
Issue Navigatorまたはビルドログを開き、エラー行に表示されるframework、静的ライブラリ、object fileの名前を確認します。
2. バイナリのアーキテクチャを確認する
静的ライブラリやframework内の実行ファイルについて、次のように確認できます。
lipo -info path/to/Library.a
XCFrameworkの場合は、内部にiOS実機用とiOS Simulator用のディレクトリが分かれているか確認します。
3. 現在のビルド先を確認する
Xcode上部のRun DestinationがiPhone Simulatorなのか実機なのかを確認してください。Simulatorを選択している場合、依存バイナリにもSimulator対応が必要です。
解決方法
方法1:XCFramework版へ更新する
外部SDKやframeworkを利用している場合は、配布元が提供する最新のXCFramework版へ更新する方法が最も確実です。XCFrameworkはiOS実機用とSimulator用など、複数プラットフォームのバイナリを1つの配布物として扱えます。
方法2:依存ライブラリを最新化する
CocoaPods、Swift Package Manager、その他の依存管理を利用している場合は、該当ライブラリの新しいバージョンにSimulator対応が追加されていないか確認します。
pod repo update
pod update
Swift Package Managerでは、XcodeのPackage Dependenciesから依存関係を更新し、再解決します。
方法3:独自frameworkを実機用・Simulator用の両方でビルドする
自作frameworkの場合は、iOS実機用とiOS Simulator用をそれぞれarchiveし、XCFrameworkとしてまとめます。
xcodebuild archive -scheme MyFramework -destination "generic/platform=iOS" -archivePath "./build/MyFramework-iOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild archive -scheme MyFramework -destination "generic/platform=iOS Simulator" -archivePath "./build/MyFramework-Simulator" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES
続いてXCFrameworkを作成します。
xcodebuild -create-xcframework -framework "./build/MyFramework-iOS.xcarchive/Products/Library/Frameworks/MyFramework.framework" -framework "./build/MyFramework-Simulator.xcarchive/Products/Library/Frameworks/MyFramework.framework" -output "./build/MyFramework.xcframework"
方法4:一時的にSimulatorのarm64を除外する
更新できない古いライブラリをIntel向けSimulatorバイナリとして利用できる場合、Apple Silicon MacではBuild SettingsのExcluded ArchitecturesでSimulator SDKに対してarm64を除外すると回避できることがあります。
EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
これは互換性確保のための暫定策です。依存ライブラリが正しくSimulator arm64に対応できるなら、XCFrameworkや最新版への移行を優先してください。
方法5:DerivedDataを削除して再ビルドする
依存ライブラリを更新した後も古い成果物が残っている場合は、XcodeのProduct > Clean Build Folderを実行し、必要に応じてDerivedDataを削除してから再ビルドします。
rm -rf ~/Library/Developer/Xcode/DerivedData/*
注意点
- 単にarm64を除外するだけでは、実機向けバイナリをSimulator向けに変換できません。
- iOS実機用arm64とiOS Simulator用arm64は同じものではありません。
- 長期的には、deviceとSimulatorの両方を正式に含むXCFrameworkを利用するのが安全です。
- ライブラリ更新後は、Link Binary With LibrariesやFramework Search Pathsに古い参照が残っていないか確認してください。
まとめ
「building for iOS Simulator, but linking in object file built for iOS」は、Simulator向けビルドに実機iOS向けバイナリをリンクしていることを示すエラーです。まず対象ライブラリを特定し、XCFramework版またはSimulator対応版へ更新してください。自作frameworkなら実機用とSimulator用を別々にビルドしてXCFramework化します。arm64除外は古いライブラリ向けの暫定回避策として考えるのが適切です。
