Bitcode:什么是中间字节码与编译

作者: IT Sectr 发布日期: 2026-04-17 阅读时间: 9 分钟

Bitcode — 是 iOS 应用程序编译阶段程序的中间表示。与机器码不同,Bitcode 不依赖于特定的处理器架构。根据 Apple Developer Documentation,App Store 能够为目标架构重新编译 Bitcode,从而提高性能并减小安装文件的大小。开发者将 Bitcode 发送到 App Store,商店本身为每种设备类型生成优化的二进制文件。

要点

  • Bitcode — 在 iOS 项目编译阶段生成的中间 LLVM 字节码
  • App Store 将 Bitcode 重新编译为用户设备处理器的代码
  • 优化 二进制文件大小通过硬件相关的指令实现
  • 启用 Bitcode 在 Xcode 设置中通过 Enable Bitcode 标志完成
  • 限制 — Bitcode 仅支持 iOS 和 tvOS,不支持 macOS

iOS 开发中的 Bitcode 是什么

Bitcode 是 LLVM 编译器基础设施生成的程序中间表示(Intermediate Representation, IR)。Apple 从 Xcode 7 和 iOS 9 开始引入对 Bitcode 的支持,作为 watchOS 应用程序的必需要求和 iOS 和 tvOS 的可选要求。从 Xcode 14 开始,除 watchOS 外所有平台的强制性要求已被取消。

Bitcode 的出现历史

中间代码表示的概念自 2000 年代以来就在 LLVM 项目框架内存在,该项目由 Chris Lattner 在伊利诺伊大学创立。Apple 于 2011 年将 LLVM 适配到 Xcode,并于 2015 年将 Bitcode 作为无需重新提交到 App Store 即可更新应用程序的方式推出。该技术在 WWDC 2015 的 “What’s New in Xcode” 会议上宣布。

Bitcode 与机器码的区别

机器码 — 是针对特定处理器的二进制指令:arm64、armv7 或 x86_64。Bitcode 以独立于硬件的格式存储,允许 App Store 从单一源代码表示为不同架构生成优化的二进制文件。这是决定该技术所有优势的关键区别。

特性Bitcode机器码
架构依赖性独立依赖于 CPU
二进制文件大小紧凑较大
重新编译能力
App Store 支持可重新编译按原样使用
调试受限完全支持

Bitcode 不是可执行文件。它是二进制格式的 LLVM IR,由开发者连同项目元数据一起发送到 App Store。应用程序商店启动重新编译过程,使代码适应每个目标平台和操作系统版本。

Bitcode 在 iOS 编译中如何工作

Bitcode 生成过程始于编译器的前端,它将 Swift 或 Objective-C 源代码转换为 LLVM IR。在链接阶段,Xcode 将 IR 打包为 .bc(Bitcode)格式的文件,然后与 .xcarchive 归档一起发送到 App Store。App Store 随后在其端启动重新编译过程。

LLVM 阶段和中间代码生成

LLVM 基础设施由三部分组成:前端(用于 C/ObjC 的 Clang,用于 Swift 的 Swift Frontend)、Middle-End 优化器和后端(机器码生成器)。Bitcode — 是前两个阶段的结果,无需过渡到生成汇编指令。Middle-End 执行平台无关的优化:死代码消除、内联和常量折叠。

swift
// 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 中的重新编译

App Store Connect 接收包含 Bitcode 的归档并启动自己的编译基础设施。系统确定用户设备的目标架构并生成机器码,进一步针对处理器的特定特性进行优化。对于 arm64e(A12+ 和 M 系列处理器),应用额外的安全优化。

此过程称为 App Thinning — 一种允许仅向设备提供其架构所需资源和代码的技术。配备 A17 Pro 处理器的 iPhone 用户获得针对 arm64e 优化的二进制文件,没有针对过时架构的多余指令。这缩短了加载时间并节省了设备空间。

使用 Bitcode 的优势

Bitcode 为 iOS 应用程序开发者提供了几个关键优势。主要优势是自动为新的 Apple 处理器进行优化,无需在 App Store 中重新发布更新。这在过渡到新架构时尤为重要,例如从 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。

  • 自动适应 新处理器,无需开发者重新构建项目
  • 缩短应用程序加载时间 在用户设备上
  • 简化分发 — 一个归档适用于所有架构,一套元数据
  • 未来兼容性 — 应用程序在尚未发布的 Apple 处理器上也能运行

如何在 Xcode 项目中启用 Bitcode

Bitcode 配置 在 Xcode 的构建配置中完成。Enable Bitcode 参数位于 Build Settings 中,默认对新项目启用,但开发者可以在调试或使用不支持 Bitcode 的第三方库时禁用它。

通过 Build Settings 配置

objective-c
// Build Settings -> Apple Clang - Code Generation
// Enable Bitcode = YES

// 或通过 Info.plist 为单个 target 设置
@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 在构建时未被生成。

通过终端检查

bash
# 检查归档中是否存在 Bitcode
otool -l YourApp.app/YourApp | grep __LLVM

# 结果:如果有 __LLVM 部分 — Bitcode 存在
# 如果结果为空 — Bitcode 未启用或未生成

# 也可以通过 size 命令检查
size -m -l YourApp.app/YourApp | grep __LLVM

当通过 CocoaPods 或 SPM 使用第三方库时,确保所有依赖项都使用 Bitcode 构建。如果至少有一个库不支持 Bitcode,Xcode 将在归档阶段生成链接错误。对于 CocoaPods,请检查 podspec 中的 bitcode_enabled 标志,或使用带有 enable_bitcode 的 use_frameworks!。

Bitcode 的限制和陷阱

Bitcode 并非适用于所有类型 iOS 项目的通用解决方案。该技术有限制,开发者在构建配置中启用该选项之前应考虑这些限制。了解这些限制有助于避免在归档和发布阶段出现问题。

与库的兼容性

并非所有第三方库都提供 Bitcode 支持。如果库仅以编译后的二进制文件形式分发而不含 Bitcode,则启用该选项的项目将无法构建。在这种情况下,开发者必须禁用 Bitcode 或向供应商请求带有 Bitcode 的版本。这对于不再更新的旧库尤其重要。

调试和崩溃报告

使用 Bitcode 构建的应用程序的 崩溃报告 需要额外处理。重新编译代码的符号(dSYM)由 App Store 生成,可通过 Xcode Organizer 下载。如果不下载相应的 dSYM 文件,崩溃报告中的调用堆栈将不可读,从而难以诊断问题。

  • 下载 dSYM — 用于解密重新编译后来自 App Store 的崩溃日志是必需的
  • 归档大小 — 带有 Bitcode 的 .xcarchive 占用开发者更多磁盘空间
  • 编译时间 — 生成 Bitcode 会使项目的编译阶段延长约 10–15%
  • macOS — Bitcode 不支持 macOS 和 watchOS 应用程序
  • 旧项目 — 大型项目的迁移可能需要更新所有依赖项

根据 iOS 17 和 Xcode 15 的状态,Apple 不要求在 App Store 发布时强制启用 Bitcode。然而,对于 watchOS 应用程序,Bitcode 仍然是 App Store Connect 规则级别设定的强制性条件。建议开发者为新项目启用 Bitcode(如果所有依赖项都支持它)。

常见问题

在 App Store 发布是否必须启用 Bitcode?

对于 iOS 和 tvOS 应用,Bitcode 从 Xcode 14 开始不是强制性的。对于 watchOS,Bitcode 支持仍然是强制性的。Apple 建议为新项目启用 Bitcode,但不阻止没有它的发布。

Bitcode 如何影响 App Store 中应用程序的大小?

Bitcode 允许 App Store 应用 App Thinning — 仅针对用户设备架构生成机器码。这将下载的二进制文件大小减少 15–40%,具体取决于项目中支持的架构数量。

启用 Bitcode 时是否需要上传 dSYM 文件?

是的,dSYM 文件 对于来自重新编译的二进制文件的崩溃报告符号化是必需的。App Store 在处理归档后提供通过 Xcode Organizer 下载 dSYM 的功能。没有它们,Crashlytics 和 console 中的调用堆栈将只包含内存地址。

Swift Package Manager 是否支持 Bitcode?

如果依赖项以源代码形式分发而不是二进制文件,SPM 支持 Bitcode。通过 SPM 的二进制依赖项必须提供带有 Bitcode 的版本,否则启用该选项的项目将无法编译。

Bitcode 与普通机器码有何不同?

Bitcode — 是一种独立于硬件的中间 LLVM IR 表示,不能由处理器直接执行。机器码 包含针对特定架构(arm64、x86_64)的现成指令,无需额外编译即可执行。

总结

  • Bitcode — 在 Xcode 中编译 iOS 应用程序时生成的中间 LLVM IR 表示
  • App Store 将 Bitcode 为用户设备架构重新编译,应用 App Thinning
  • 下载的应用程序大小 通过消除不必要的机器指令减少 15–40%
  • 新的 Apple 处理器 自动支持,无需开发者重新发布更新
  • Bitcode 的启用 通过 Xcode 项目的 Build Settings 中的 Enable Bitcode 标志配置
  • 限制 包括崩溃报告需要 dSYM 文件以及所有第三方库的兼容性
  • 建议 — 为新项目启用 Bitcode,但要检查所有使用中的依赖项的支持

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读