Meet mergeable libraries
System & Services 进阶 20m

认识可合并库

Meet mergeable libraries

2023年6月5日

在 Apple 官方观看视频

一句话判断

Mergeable Libraries 让你同时获得动态库的构建速度和静态库的启动性能——Xcode 15 中一个 Build Setting 就能开启自动合并,把多个嵌入框架合并到 App 二进制中,减少 dyld 加载时间。

这场 Session 讲了什么

Session 介绍了 Xcode 15 中全新的 Mergeable Libraries 机制。

背景问题

  • 静态库:构建时复制代码到 App 二进制,启动快但构建慢(代码变更触发重新链接)。
  • 动态库:构建时只记录路径,启动时 dyld 加载,构建快但启动慢(框架越多越慢)。
  • 之前需要在这两者之间权衡测量。

Mergeable Libraries 的方案

  • 动态库构建时生成额外元数据(metadata),使链接器可以像静态库一样处理它们。
  • 合并时链接器去重:消除冗余符号引用、Objective-C 选择器、objc_msgSend 桩代码。
  • 最终输出是一个包含所有库段的单一二进制——启动时只需加载一个库。
  • 保留了开发时的模块化优势(代码分离、独立编译),同时获得运行时的合并性能。

两种启用方式

  1. 自动合并(Automatic Merging):一个 Build Setting 开关,自动合并所有直接依赖的嵌入框架。适合 App 目标。
  2. 手动合并(Manual Merging):精确控制哪些库合并、合并到哪里。适合需要精确控制的场景。

Debug 模式优化

  • Debug 模式下保持动态链接行为(构建速度快)。
  • Release 模式下执行合并(启动性能好)。
  • 调试和符号化完整支持。

值得深挖的点

**合并时的去重(De-duplication)**是性能提升的核心来源。当多个框架包含相同的字符串常量、符号引用或 Objective-C 选择器时,链接器只保留一份。对大型项目(几十个框架)来说,这种去重可以显著减少 App 包大小和内存占用。

Debug/Release 的自动切换消除了开发体验和用户性能之间的矛盾。Debug 模式下框架仍然是独立的动态库,增量构建速度快。Release 模式下自动合并为单一二进制,启动时 dyld 加载的框架数量大幅减少。开发者不需要维护两套配置。

导出符号的保留意味着合并后的库仍然可以导出符号,保持框架的公共 API 可用性。这对需要跨模块访问框架 API 的场景(如插件架构)很重要。

代码片段

启用自动合并(Xcode Build Setting):

// 在 Xcode 中:
// 1. 选择 App 目标
// 2. Build Settings 标签
// 3. 搜索 "Create Merged Binary" (MERGED_BINARY_TYPE)
// 4. 设置为 "Automatic"

// 效果:所有直接依赖的嵌入框架自动合并到 App 二进制中
// App 启动时不需要单独加载这些框架

手动合并配置:

// 手动控制哪些库合并、合并到哪里

// 步骤1:将库构建为 mergeable
// 在框架目标的 Build Settings 中:
// MERGEABLE_LIBRARY = YES
// 这会让链接器在库中生成元数据

// 步骤2:在目标二进制中合并指定库
// 在 App 目标的 Build Settings 中:
// MERGED_BINARY_TYPE = "Manual"
// 然后指定要合并的框架

// 底层链接器选项(Xcode 自动处理):
// -make_mergeable    → 为库生成元数据
// -merge_library     → 合并指定库
// -merge_framework   → 合并指定框架

框架合并策略:

// 合并前:App 依赖 4 个嵌入框架
// App → FrameworkA → FrameworkB → FrameworkC
//
// 启动时 dyld 需要加载 3 个框架
//
// 合并后:创建一个合并框架
// MergedFramework = merge(A, B, C)
// App → MergedFramework
//
// 启动时 dyld 只需加载 1 个框架
// 构建时各框架仍然独立编译和调试

最佳实践

  • 大型 App(10+ 嵌入框架)优先使用自动合并,一个开关就能获得显著改善。
  • Debug 模式不需要改动配置——保持动态链接以确保构建速度。
  • Release 构建验证合并后的包大小和启动时间是否确实改善。
  • 如果框架需要被其他独立二进制(如 App Extension)使用,不要合并它。
  • 符号化和崩溃报告在合并后仍然有效,不需要额外配置。
  • 测试合并后的 App 确保 import 和模块访问正常工作。

还有什么值得关注

  • Mergeable Libraries 是 Xcode 15 新静态链接器的能力。
  • 系统框架(如 SwiftUI)不参与合并——只有你自己的嵌入框架会被合并。
  • 合并后的二进制文件类型不变——App 仍然是 App,框架仍然是框架。
  • 对 CocoaPods 等第三方依赖管理工具的影响需要评估——多 framework 集成的项目受益最大。
  • 搭配 Session “What’s new in Xcode 15” 了解更多构建系统的改进。
WWDC 2023