spm-build-analysis
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSPM Build Analysis
SPM构建分析
Use this skill when package structure, plugins, or dependency configuration are likely contributing to slow Xcode builds.
当包结构、插件或依赖配置可能导致Xcode构建缓慢时,使用此技能。
Core Rules
核心规则
- Treat package analysis as evidence gathering first, not a mandate to replace dependencies.
- Separate package-graph issues from project-setting issues.
- Do not rewrite package manifests or dependency sources without explicit approval.
- 首先将包分析视为证据收集工作,而非必须替换依赖项。
- 将包图问题与项目设置问题分开处理。
- 未经明确批准,不得重写包清单或依赖源。
What To Inspect
检查内容
- and
Package.swiftPackage.resolved - local packages vs remote packages
- package plugin and build-tool usage
- binary target footprint
- dependency layering, repeated imports, and potential cycles
- build logs or timing summaries that show package-related work
- 和
Package.swiftPackage.resolved - 本地包 vs 远程包
- 包插件和构建工具的使用情况
- 二进制目标的占用规模
- 依赖分层、重复导入以及潜在的循环依赖
- 显示包相关工作的构建日志或时间摘要
Verification Before Recommending
推荐前的验证
Before including any local package in a recommendation, verify that it is actually part of the project's dependency graph. A directory may contain packages that are not linked to any target.
Vendor/- Check for
project.pbxprojentries that reference the package path.XCLocalSwiftPackageReference - Check entries to confirm the package's product is linked to at least one target.
XCSwiftPackageProductDependency - If a local package exists on disk but is not referenced in the project, do not include it in build-time recommendations.
When recommending version pins for branch-tracked dependencies:
- Use the helper script to scan all branch-pinned dependencies at once:
This checksbash
python3 scripts/check_spm_pins.py --project App.xcodeprojfor each branch-pinned package and reports which have tags available for pinning.git ls-remote --tags - If no tags exist, recommend pinning to a specific commit revision hash for determinism instead.
- Note which packages are branch-pinned because the upstream simply has no tags, versus packages that have tags but are intentionally tracking a branch.
在推荐中包含任何本地包之前,需确认它确实属于项目依赖图的一部分。目录中可能包含未链接到任何目标的包。
Vendor/- 检查中引用包路径的
project.pbxproj条目。XCLocalSwiftPackageReference - 检查条目,确认包的产物已链接到至少一个目标。
XCSwiftPackageProductDependency - 如果本地包存在于磁盘上但未在项目中引用,请勿将其纳入构建时间优化建议。
当推荐对分支跟踪的依赖项进行版本固定时:
- 使用辅助脚本一次性扫描所有分支固定的依赖项:
该脚本会为每个分支固定的包执行bash
python3 scripts/check_spm_pins.py --project App.xcodeproj,并报告哪些包有可用于固定的标签。git ls-remote --tags - 如果没有可用标签,建议固定到特定的提交哈希以确保确定性。
- 区分两种分支固定的包:一种是上游根本没有标签的包,另一种是有标签但故意跟踪分支的包。
Focus Areas
重点关注领域
- package graph shape and how much work changes trigger downstream
- plugin overhead during local development and CI
- checkout or fetch cost signals that show up in clean environments
- configuration drift that forces duplicate module builds
- risks from package targets that use different macros or options while sharing dependencies
- dependency direction violations (features depending on each other instead of shared lower layers)
- circular dependencies between modules (extract shared contracts into a protocol module)
- oversized modules (200+ files) that widen incremental rebuild scope
- umbrella modules using that create hidden dependency chains
@_exported import - missing interface/implementation separation that blocks build parallelism
- test targets depending on the app target instead of the module under test
- Swift macro rebuild cascading: heavy use of Swift macros (e.g., TCA, swift-syntax-based libraries) can cause a trivial source change to cascade into near-full rebuilds because macro expansion invalidates downstream modules
- building universally (all architectures) when no prebuilt binary is available, adding significant clean-build overhead
swift-syntax - multi-platform build multiplication: adding a secondary platform target (e.g., watchOS) can cause shared SPM packages to build multiple times (e.g., iOS arm64, iOS x86_64, watchOS arm64), multiplying ,
SwiftCompile, andSwiftEmitModuletasksScanDependencies
- 包图结构,以及变更会触发多少下游工作
- 本地开发和CI过程中的插件开销
- 清洁环境中出现的检出或拉取成本信号
- 导致重复模块构建的配置差异
- 共享依赖但使用不同宏或选项的包目标带来的风险
- 依赖方向违规(功能模块相互依赖,而非依赖共享底层模块)
- 模块间的循环依赖(将共享契约提取到协议模块中)
- 过大的模块(200+文件)会扩大增量重建的范围
- 使用的伞形模块会创建隐藏的依赖链
@_exported import - 缺少接口/实现分离,阻碍构建并行化
- 测试目标依赖于应用目标而非被测模块
- Swift宏重建级联:大量使用Swift宏(如TCA、基于swift-syntax的库)可能导致微小的源码变更引发近乎完全的重建,因为宏展开会使下游模块失效
- 当没有预构建二进制文件时,会进行全架构(所有架构)构建,显著增加清洁构建的开销
swift-syntax - 多平台构建倍增:添加次要平台目标(如watchOS)会导致共享SPM包多次构建(如iOS arm64、iOS x86_64、watchOS arm64),使、
SwiftCompile和SwiftEmitModule任务的数量倍增ScanDependencies
Modular SDK Migration Caveat
模块化SDK迁移注意事项
Migrating a dependency from a monolithic target to a modular multi-target SDK (e.g., replacing one umbrella library with separate Core, RUM, Logs, Trace modules) does not automatically reduce build time. Modular targets increase the number of , , and tasks because each target must be compiled, scanned, and emit its module independently. The build-time trade-off depends on the project's parallelism headroom and how many of the modular targets are actually needed.
SwiftCompileSwiftEmitModuleScanDependenciesWhen considering a modular SDK migration:
- Compare the total task count before and after.
SwiftCompile - Benchmark both configurations before recommending the migration for build speed.
- If the motivation is API surface reduction (importing only what you use), note that build time may stay flat or increase while import hygiene improves.
- Only recommend modular SDK migration for build speed when the project currently compiles large portions of the monolithic SDK that it does not use, and the modular alternative lets it skip those unused portions entirely.
将依赖项从单体目标迁移到模块化多目标SDK(例如,用单独的Core、RUM、Logs、Trace模块替换一个伞形库)并不会自动减少构建时间。模块化目标会增加、和任务的数量,因为每个目标都必须独立编译、扫描并生成其模块。构建时间的权衡取决于项目的并行处理空间以及实际需要多少个模块化目标。
SwiftCompileSwiftEmitModuleScanDependencies考虑进行模块化SDK迁移时:
- 比较迁移前后任务的总数。
SwiftCompile - 在推荐通过迁移提升构建速度之前,对两种配置进行基准测试。
- 如果迁移的动机是减少API暴露面(仅导入所需内容),需注意构建时间可能保持不变或增加,但导入规范性会提升。
- 只有当项目当前编译了单体SDK中大量未使用的部分,而模块化替代方案可以完全跳过这些未使用部分时,才推荐通过模块化SDK迁移来提升构建速度。
Explicit Module Dependency Angle
显式模块依赖角度
When the same module appears multiple times in timing output, investigate whether different package or target options are forcing extra module variants. Uniform options often matter more than shaving a small amount of source code.
当同一个模块多次出现在时间输出中时,需调查是否是不同的包或目标选项导致了额外的模块变体。统一选项通常比减少少量源码更重要。
Reporting Format
报告格式
For each finding, include:
- evidence
- affected package or plugin
- likely clean-build vs incremental-build impact
- CI impact if relevant
- estimated impact
- approval requirement
If the main problem is not package-related, hand off to or by reading the target skill's SKILL.md and applying its workflow to the same project context.
xcode-project-analyzerxcode-compilation-analyzer对于每个发现,需包含:
- 证据
- 受影响的包或插件
- 对清洁构建与增量构建的可能影响
- 相关的CI影响(如果有的话)
- 预估影响程度
- 批准要求
如果主要问题与包无关,请将任务转交给或,方法是阅读目标技能的SKILL.md并将其工作流应用到相同的项目环境中。
xcode-project-analyzerxcode-compilation-analyzerAdditional Resources
额外资源
- For the detailed audit checklist, see references/spm-analysis-checks.md
- For the shared recommendation structure, see references/recommendation-format.md
- For source citations, see references/build-optimization-sources.md
- 详细的审核清单,请参阅references/spm-analysis-checks.md
- 共享的建议结构,请参阅references/recommendation-format.md
- 来源引用,请参阅references/build-optimization-sources.md