Xcode 16で「executable contains bitcode」エラーを解決
問題の説明
Xcode 16およびmacOS 15 Sequoiaへのアップデート後、アプリのビルドをApp Storeにアップロードする際に次のエラーが発生することがあります:
Asset validation failed invalid executable.
The executable 'myapp.app/frameworks/cardio.framework/cardio' contains bitcode
この問題の原因は、AppleがXcode 16でBitcodeのサポートを廃止したことにあります。Bitcodeは以前まで利用されていた中間コード表現ですが、最新のXcode環境ではビルド成果物にBitcodeが含まれていると検証エラーが発生します。
エラーメッセージに表示されるフレームワーク(この例ではcardio.framework
)はプロジェクトごとに異なり、主にサードパーティライブラリやCocoaPodsで導入された依存関係に含まれています。
注意
エラーメッセージはビルドしようとするプロジェクトで使用されている特定のフレームワークを表示します。表示されたフレームワーク名は必ずメモしてください。
解決方法
根本的な解決策は、問題を起こしているフレームワークからBitcodeを削除することです。以下の手順でPodfileにスクリプトを追加することで、ビルド時に自動的にBitcodeを除去できます。
ステップ1: Podfileの編集
プロジェクトのPodfile
を開き、post_install
ブロックを追加または修正します:
post_install do |installer|
# 他のpost_installスクリプトがあればその上に追加
# bitcode_stripツールのパスを取得
bitcode_strip_path = `xcrun --find bitcode_strip`.chop!
# Bitcodeを削除するヘルパー関数
def strip_bitcode(bitcode_strip_path, framework_path)
full_path = File.join(Dir.pwd, framework_path)
command = "#{bitcode_strip_path} #{full_path} -r -o #{full_path}"
puts "Bitcodeを削除: #{command}"
system(command)
end
# Bitcodeを削除するフレームワークのパスを指定
target_frameworks = [
"Pods/LogRocket/LogRocket.xcframework/ios-arm64/LogRocket.framework/LogRocket",
"Pods/hermes-engine/destroot/Library/Frameworks/macosx/hermes.framework/hermes",
# エラーメッセージで表示されたフレームワークを追加
"Pods/<エラーの出たフレームワーク>/<パス>/<フレームワーク名>"
]
# 各フレームワークに対してBitcode削除を実行
target_frameworks.each do |framework|
strip_bitcode(bitcode_strip_path, framework)
end
end
ステップ2: フレームワークパスの特定方法
target_frameworks
配列には、エラーの対象となったフレームワークの正確なパスを指定する必要があります。パスを特定する方法は2つあります:
方法1: エラーメッセージから直接取得
Xcodeのエラーメッセージに表示されたパスから構造を抽出:
'myapp.app/frameworks/cardio.framework/cardio'
↓ 変換後
"Pods/cardio/cardio.framework/cardio"
方法2: ターミナルで検索
フレームワーク名が分かっている場合、find
コマンドで検索:
find Pods -name "<フレームワーク名>"
例(glog
フレームワークの場合):
find Pods -name "glog"
出力例:
Pods/Flipper-Glog/Frameworks/glog.xcframework/ios-arm64_i386_x86_64-simulator/glog.framework/glog
Pods/Flipper-Glog/Frameworks/glog.xcframework/ios-arm64_x86_64-maccatalyst/glog.framework/glog
ステップ3: 変更を適用
- ターミナルでプロジェクトの
ios
ディレクトリに移動 - 以下のコマンドを実行:bash
pod install
- Xcodeでクリーンビルド(
Product
→Clean Build Folder
) - アーカイブを再生成してアップロード
複数フレームワークの対応
異なるフレームワークで複数回エラーが発生する場合は、target_frameworks
配列に対象のパスを全て追加してください。 エラーごとにパスが異なるので、それぞれに対応する必要があります。
仕組みと補足説明
Bitcodeは以前、Appleがアプリを最適化するために使用していた中間表現コードでしたが、Xcode 16で正式に廃止されました。このスクリプトでは、bitcode_strip
ツールの-r
オプションを使って実行ファイルからBitcodeセクションを削除しています。
command = "#{bitcode_strip_path} #{full_path} -r -o #{full_path}"
-r
オプション:Bitcodeを含むセクションを完全に削除-o
オプション:出力ファイル(入力ファイルを上書き)
注意事項
- この処理はCocoaPodsを使用しているプロジェクトのみに適用されます
- フレームワークのバージョンアップ後は再びBitcodeが含まれる可能性があるため、再度実施が必要
- 修正後もエラーが発生する場合は、パスの記述ミスが最も一般的な原因です
代替方法:手動でのBitcode削除
CI環境などで自動化が難しい場合、ビルド後に手動でBitcodeを除去:
xcrun bitcode_strip -r \
[フレームワークのフルパス] \
-o [出力パス(通常は入力と同じ)]
例:
xcrun bitcode_strip -r \
Pods/cardio/cardio.framework/cardio \
-o Pods/cardio/cardio.framework/cardio
よくあるフレームワークのパス例
頻出するフレームワークのパスパターンを紹介します:
framework_paths = [
# React Native関連
"Pods/hermes-engine/destroot/Library/Frameworks/universal/hermes.xcframework/ios-arm64_x86_64-maccatalyst/hermes.framework/hermes",
# 主要SDK
"Pods/FBSDKCoreKit/XCFrameworks/FBSDKCoreKit.xcframework/ios-arm64/FBSDKCoreKit.framework/FBSDKCoreKit",
# マップ系
"Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents",
# ユーティリティ
"Pods/Shake/Sources/Shake.xcframework/ios-arm64/Shake.framework/Shake"
]
新しいフレームワークを追加する際は、実際のプロジェクト構造とエラーメッセージを照合しながら進めてください。適切にパスを設定すれば、Xcode 16環境でもスムーズにアプリを公開できます。