spm-build-analysis

spm-build-analysis

热门

分析 Swift Package Manager 依赖、包插件、模块变体以及面向 CI 的构建开销,这些因素会拖慢 Xcode 构建速度。当开发者怀疑包、插件或依赖图结构影响了干净构建或增量构建性能,提及 SPM 缓慢、包解析时间、构建插件开销、配置漂移导致的重复模块构建、模块间的循环依赖、需要拆分的超大模块或模块化最佳实践时使用。

1185Star
45Fork
更新于 2026/4/15
SKILL.md
readonly只读
name
spm-build-analysis
description

分析 Swift Package Manager 依赖、包插件、模块变体以及面向 CI 的构建开销,这些因素会拖慢 Xcode 构建速度。当开发者怀疑包、插件或依赖图结构影响了干净构建或增量构建性能,提及 SPM 缓慢、包解析时间、构建插件开销、配置漂移导致的重复模块构建、模块间的循环依赖、需要拆分的超大模块或模块化最佳实践时使用。

SPM 构建分析

当包结构、插件或依赖配置可能导致 Xcode 构建缓慢时,使用此技能。

核心规则

  • 将包分析视为证据收集,而非替换依赖的指令。
  • 区分包图问题与项目设置问题。
  • 未经明确批准,不得重写包清单或依赖源码。

检查内容

  • Package.swiftPackage.resolved
  • 本地包与远程包
  • 包插件和构建工具的使用
  • 二进制目标占用空间
  • 依赖分层、重复导入及潜在循环
  • 显示包相关工作的构建日志或时间摘要

推荐前的验证

在将任何本地包纳入推荐之前,请验证它是否实际属于项目的依赖图。Vendor/ 目录可能包含未链接到任何目标的包。

  • 检查 project.pbxproj 中引用包路径的 XCLocalSwiftPackageReference 条目。
  • 检查 XCSwiftPackageProductDependency 条目,确认包的产品已链接到至少一个目标。
  • 如果本地包存在于磁盘但未在项目中引用,则不要将其纳入构建时间推荐。

当推荐为分支跟踪依赖固定版本时:

  • 使用辅助脚本一次性扫描所有分支固定的依赖:
    python3 scripts/check_spm_pins.py --project App.xcodeproj
    
    这会为每个分支固定的包检查 git ls-remote --tags,并报告哪些包有可用的标签用于固定。
  • 如果没有标签,建议固定到特定的提交修订哈希以确保确定性。
  • 注意哪些包因上游没有标签而分支固定,哪些包虽然有标签但有意跟踪分支。

重点关注领域

  • 包图形状以及变更触发下游工作的程度
  • 本地开发和 CI 期间的插件开销
  • 在干净环境中显现的检出或获取成本信号
  • 强制重复模块构建的配置漂移
  • 使用不同宏或选项但共享依赖的包目标带来的风险
  • 依赖方向违规(功能相互依赖而非共享底层)
  • 模块间的循环依赖(将共享契约提取到协议模块中)
  • 超大模块(200+ 文件)扩大增量重建范围
  • 使用 @_exported import 的伞模块创建隐藏依赖链
  • 缺少接口/实现分离阻碍构建并行性
  • 测试目标依赖应用目标而非被测模块
  • Swift 宏重建级联:大量使用 Swift 宏(例如 TCA、基于 swift-syntax 的库)可能导致微小源码变更级联为近乎完全重建,因为宏展开会使下游模块失效
  • swift-syntax 在没有预构建二进制文件时通用构建(所有架构),显著增加干净构建开销
  • 多平台构建倍增:添加次要平台目标(例如 watchOS)可能导致共享 SPM 包多次构建(例如 iOS arm64、iOS x86_64、watchOS arm64),倍增 SwiftCompileSwiftEmitModuleScanDependencies 任务

模块化 SDK 迁移注意事项

将依赖从单体目标迁移到模块化多目标 SDK(例如,用一个伞库替换为独立的 Core、RUM、Logs、Trace 模块)并不会自动减少构建时间。模块化目标会增加 SwiftCompileSwiftEmitModuleScanDependencies 任务的数量,因为每个目标必须独立编译、扫描和发出模块。构建时间的权衡取决于项目的并行度余量以及实际需要多少个模块化目标。

在考虑模块化 SDK 迁移时:

  • 比较迁移前后的总 SwiftCompile 任务数。
  • 在推荐迁移以提升构建速度之前,对两种配置进行基准测试。
  • 如果动机是减少 API 表面积(仅导入使用的内容),请注意构建时间可能持平或增加,同时导入规范性得到改善。
  • 仅当项目当前编译了单体 SDK 中大量未使用的部分,且模块化替代方案允许完全跳过这些未使用部分时,才推荐为构建速度进行模块化 SDK 迁移。

显式模块依赖角度

当同一模块在时间输出中多次出现时,调查不同的包或目标选项是否强制产生了额外的模块变体。统一选项通常比削减少量源代码更重要。

报告格式

对于每个发现,包括:

  • 证据
  • 受影响的包或插件
  • 可能的干净构建与增量构建影响
  • CI 影响(如果相关)
  • 预估影响
  • 批准要求

如果主要问题与包无关,请通过阅读目标技能的 SKILL.md 并将其工作流程应用于同一项目上下文,移交给 xcode-project-analyzerxcode-compilation-analyzer

附加资源