Bitcodeは、iOSアプリケーションのコンパイル段階におけるプログラムの中間表現です。マシンコードとは異なり、Bitcodeは特定のプロセッサアーキテクチャに依存しません。Apple Developer Documentationによると、App Storeはターゲットアーキテクチャ向けにBitcodeを再コンパイルでき、パフォーマンスを向上させ、インストールファイルサイズを削減します。開発者はBitcodeをApp Storeに送信し、ストア自体が各デバイスタイプ向けに最適化されたバイナリファイルを生成します。
重要ポイント
Bitcodeは、LLVMコンパイラインフラストラクチャによって生成されるプログラムの中間表現(Intermediate Representation, IR)です。AppleはXcode 7とiOS 9から、watchOSアプリケーションでは必須、iOSとtvOSではオプションとしてBitcodeサポートを導入しました。Xcode 14以降、watchOSを除くすべてのプラットフォームでこの要件は廃止されました。
中間コード表現の概念は、2000年代からイリノイ大学でクリス・ラトナーが創設したLLVMプロジェクトの一部として存在しています。Appleは2011年にLLVMをXcodeに適応させ、2015年にBitcodeをApp Storeに再提出せずにアプリケーションを更新する方法として発表しました。この技術はWWDC 2015のセッション「What's New in Xcode」で発表されました。
マシンコードは、特定のプロセッサ(arm64、armv7、x86_64)向けのバイナリ命令です。Bitcodeはハードウェアに依存しない形式で保存され、App Storeが単一のソース表現から異なるアーキテクチャ向けに最適化されたバイナリファイルを生成できるようにします。この重要な違いが、この技術のすべての利点を定義しています。
| 特性 | Bitcode | マシンコード |
|---|---|---|
| アーキテクチャ依存性 | 独立 | CPUに依存 |
| バイナリファイルサイズ | コンパクト | 大きい |
| 再コンパイル機能 | あり | なし |
| App Storeサポート | 再コンパイルされる | そのまま使用 |
| デバッグ | 制限あり | 完全サポート |
Bitcodeは実行可能ファイルではありません。これは開発者がプロジェクトメタデータとともにApp Storeに送信するバイナリ形式のLLVM IRです。アプリストアは再コンパイルプロセスを実行し、各ターゲットプラットフォームとオペレーティングシステムバージョンにコードを適応させます。
Bitcode生成プロセスは、SwiftまたはObjective-CのソースコードをLLVM IRに変換するコンパイラフロントエンドから始まります。リンク段階で、XcodeはIRを.bc(Bitcode)形式ファイルにパッケージ化し、.xcarchiveとともにApp Storeに送信されます。App Storeは自社側で再コンパイルプロセスを実行します。
LLVMインフラストラクチャは3つの部分で構成されています:フロントエンド(C/ObjC用Clang、Swift用Swift Frontend)、Middle-Endオプティマイザ、バックエンド(マシンコードジェネレータ)。Bitcodeはアセンブリ命令の生成に進むことなく、最初の2つの段階の結果です。Middle-Endはプラットフォームに依存しない最適化(デッドコード削除、インライン化、定数折りたたみ)を実行します。
// Swiftソースコードの例
func calculateSum(a: Int, b: Int) -> Int {
return a + b
}
// コンパイル後のLLVM IR(簡略版)
; define i32 @calculateSum(i32 %a, i32 %b)
; %result = add i32 %a, %b
; ret i32 %result
IR生成後、コンパイラは表現レベルで一連の最適化(デッドコード削除、関数インライン化、定数折りたたみ)を実行します。これらの最適化はアーキテクチャに依存せず、Bitcodeに保持されます。App Storeでの再コンパイル時に、特定のプロセッサ向けの命令並べ替えなどのアーキテクチャ依存の最適化が追加されます。
App Store ConnectはBitcodeを含むアーカイブを受け取り、独自のコンパイルインフラストラクチャを実行します。システムはユーザーのデバイスのターゲットアーキテクチャを判別し、マシンコードを生成して、特定のプロセッサ特性にさらに最適化します。arm64e(A12+およびMシリーズプロセッサ)では、追加のセキュリティ最適化が適用されます。
このプロセスはApp Thinningと呼ばれます — デバイスのアーキテクチャに必要なリソースとコードのみをそのデバイスに配信する技術です。A17 Proプロセッサを搭載したiPhoneユーザーは、古いアーキテクチャ向けの不要な命令なしで、arm64e向けに最適化されたバイナリファイルを受け取ります。これによりダウンロード時間が短縮され、デバイスの容量を節約できます。
Bitcodeは、iOSアプリケーション開発者にいくつかの重要な利点を提供します。主な利点は、App Storeにアップデートを再提出することなく、新しいAppleプロセッサ向けに自動最適化されることです。これは、armv7からarm64への移行など、新しいアーキテクチャへの移行時に特に重要です。
Appleが新しいアーキテクチャのプロセッサをリリースすると、Bitcodeとともに送信されたアプリケーションは自動的にそのアーキテクチャ向けに再コンパイルされます。開発者はプロジェクトを再ビルドしてアップデートを公開する必要はありません — App Storeがユーザーが最初にダウンロードする際に自社側でこれを行います。これは、長期間にわたって維持されるアプリケーションにとって特に重要です。
App ThinningをBitcodeと組み合わせることで、インストールされるアプリケーションサイズを15〜40%削減できます。App Storeは特定のデバイスに必要なマシン命令のみを生成し、他のアーキテクチャや異なるiOSバージョン向けのコードを排除します。実際には、新しいiPhoneのユーザーはコンパクトなバイナリファイルを受け取ることになります。
Apple WWDC 2015 Session 102によると、BitcodeとApp Thinningを使用することで、すべてのアーキテクチャを含むユニバーサルバイナリファイルと比較して、ダウンロードされるアプリケーションサイズを平均25%削減できます。100 MBのアプリケーションの場合、ユーザーのデバイスで最大40 MBの節約になります。
Bitcode設定はXcodeのビルド設定で行います。Enable BitcodeパラメータはBuild Settingsにあり、新しいプロジェクトではデフォルトで有効ですが、開発者はデバッグ時やBitcodeをサポートしていないサードパーティライブラリを使用する際に無効にできます。
// Build Settings -> Apple Clang - Code Generation
// Enable Bitcode = YES
// または個別ターゲットのInfo.plist経由
@property (nonatomic, assign) BOOL enableBitcode;
- (void)configureBuildSettings {
// 設定でのBitcodeステータスの確認
if (self.enableBitcode) {
NSLog(@"Bitcode is enabled for this target");
} else {
NSLog(@"Bitcode is disabled");
}
}
アーカイブにBitcodeが含まれているか確認するには、Xcode Organizer経由で.xcarchiveファイルを開くか、ターミナルでotool -lコマンドを実行します。バイナリファイルに__LLVMセクションが存在すれば、Bitcodeが有効で正しくパッケージ化されていることを確認できます。セクションがない場合、ビルド中にBitcodeが生成されませんでした。
# アーカイブ内のBitcode存在確認
otool -l YourApp.app/YourApp | grep __LLVM
# 出力: __LLVMセクションがある場合 — Bitcodeが存在
# 出力が空の場合 — Bitcodeが有効でないか生成されていない
# sizeコマンドを使用して確認することも可能
size -m -l YourApp.app/YourApp | grep __LLVM
CocoaPodsやSPMを介してサードパーティライブラリを使用する場合、すべての依存関係がBitcodeでビルドされていることを確認してください。1つでもBitcodeをサポートしていないライブラリがあると、Xcodeはアーカイブ時にリンクエラーを生成します。CocoaPodsの場合は、サブスペックでbitcode_enabledフラグを確認するか、enable_bitcode付きのuse_frameworks!を使用してください。
BitcodeはすべてのタイプのiOSプロジェクトに対する万能な解決策ではありません。この技術には制限があり、開発者はビルド設定でオプションを有効にする前に考慮する必要があります。これらの制限を理解することで、アーカイブや公開時の問題を回避できます。
すべてのサードパーティライブラリがBitcodeをサポートしているわけではありません。ライブラリがBitcodeなしのコンパイル済みバイナリファイルとしてのみ配布されている場合、オプションを有効にしたプロジェクトはビルドできません。この場合、開発者はBitcodeを無効にするか、ベンダーにBitcode対応バージョンをリクエストする必要があります。これは特に、更新されなくなった古いライブラリに関連します。
Bitcodeでビルドされたアプリケーションからのクラッシュレポートは追加の処理が必要です。再コンパイルされたコードのシンボル(dSYM)はApp Storeによって生成され、Xcode Organizerを介してダウンロードできます。対応するdSYMファイルをロードしないと、クラッシュレポートのコールスタックが読み取れなくなり、問題の診断が困難になります。
iOS 17およびXcode 15の時点で、AppleはApp Storeへの公開にBitcodeの必須有効化を要求していません。ただし、watchOSアプリケーションについては、BitcodeはApp Store Connectポリシーレベルで必須要件のままです。開発者は、すべての依存関係がサポートしている場合、新しいプロジェクトでBitcodeを有効にすることをお勧めします。
よくある質問
iOSおよびtvOSアプリケーションの場合、Xcode 14以降Bitcodeは必須ではありません。watchOSの場合、Bitcodeサポートは引き続き必須です。Appleは新しいプロジェクトでBitcodeを有効にすることを推奨していますが、有効にしなくても公開をブロックすることはありません。
Bitcodeにより、App StoreはApp Thinningを適用できます — ユーザーのデバイスアーキテクチャ専用のマシンコードを生成します。これにより、プロジェクトでサポートされているアーキテクチャの数に応じて、ダウンロードされるバイナリファイルサイズが15〜40%削減されます。
はい、dSYMファイルは再コンパイルされたバイナリファイルからのクラッシュレポートをシンボル化するために必要です。App Storeはアーカイブ処理後、Xcode Organizerを介してdSYMをダウンロードする機能を提供します。これらがないと、Crashlyticsやコンソールのコールスタックにはメモリアドレスのみが含まれます。
SPMは、依存関係がバイナリファイルではなくソースコードで配布されている場合、Bitcodeをサポートします。SPMを介したバイナリ依存関係はBitcode対応バージョンを提供する必要があります。そうでない場合、オプションを有効にしたプロジェクトはコンパイルできません。
Bitcodeはハードウェアに依存しない中間LLVM IR表現であり、プロセッサが直接実行することはできません。マシンコードは特定のアーキテクチャ(arm64、x86_64)向けの準備済み命令を含み、追加のコンパイルなしで実行されます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。