mcpField
X
xcode-build-fixer

xcode-build-fixer

github.com/avdlee开发1.3k3.6k 次安装28 周前更新
代码仓库

关于 xcode-build-fixer

面向 Xcode 项目的构建优化技能,根据已获批准的方案或明确指令实施修改,并通过构建和基准测试验证结果。它逐项处理改动,并报告文件变更及构建耗时差异。

主要功能

  1. 01仅实施明确批准的优化
  2. 02逐项应用可审查的改动
  3. 03验证构建是否成功
  4. 04重新运行基准测试
  5. 05报告文件变更与耗时差异
  6. 06评估回退或保留建议

适用场景

  1. 01落实已批准的构建优化计划
  2. 02验证 Xcode 构建设置调整
  3. 03测量脚本阶段或源码改动的效果
  4. 04评估 Swift 包结构调整的影响

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/avdlee/xcode-build-optimization-agent-skill --skill xcode-build-fixer

安装后在 Claude Code 中输入/xcode-build-fixer确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
build-settings-best-practices.md
fix-patterns.md
recommendation-format.md
scripts/
benchmark_builds.py

详细介绍

Xcode 构建修复器

使用此技能来实施已批准的构建优化变更,并通过基准测试进行验证。

核心规则

  • 仅应用已获得开发者明确批准的变更。
  • 每次只应用一项逻辑上独立的修复,以便审查和回退。
  • 应用变更后重新运行基准测试,验证是否有所改进。
  • 准确报告具体变更、涉及的文件以及测得的差异。
  • 如果变更没有带来改进或导致性能回退,请立即指出。

输入

修复器需要以下任一输入:

  • .build-benchmark/optimization-plan.md 中经批准且勾选了相应审批框的优化计划。
  • 明确说明要应用的修复的开发者指令(例如,“将 Debug 的 DEBUG_INFORMATION_FORMAT 设为 dwarf”)。

根据优化计划开展工作时,请阅读审批清单,并且只实施已勾选的项目。

修复类别

构建设置

按照 build-settings-best-practices.md 中的建议修改 project.pbxproj 的值。

常见修复:

  • 将 Debug 的 DEBUG_INFORMATION_FORMAT 设为 dwarf
  • 将 Debug 的 SWIFT_COMPILATION_MODE 设为 singlefile
  • 启用 COMPILATION_CACHE_ENABLE_CACHING = YES
  • 为 Debug 启用 EAGER_LINKING = YES
  • 调整跨目标设置,消除模块变体

编辑 project.pbxproj 时,请通过匹配目标名称和配置名称,找到正确的 buildSettings 块。应用变更后,使用 xcodebuild -showBuildSettings 验证。

脚本阶段

修复那些会拖慢增量构建或调试构建的运行脚本阶段。

常见修复:

  • 添加输入和输出文件声明,让 Xcode 跳过未更改的脚本。
  • 添加配置检查:对仅用于发布版本的脚本,使用 [[ "$CONFIGURATION" != "Release" ]] && exit 0。
  • 如果列表很长,将输入/输出列表移至 .xcfilelist 文件。
  • 声明输入和输出后,启用 Based on dependency analysis。
源码级编译修复

应用能够降低类型检查器和编译器开销的代码变更。前后对比示例请参阅 references/fix-patterns.md。

常见修复:

  • 为复杂表达式添加显式类型注解。
  • 将较长的链式表达式或嵌套表达式拆分为带类型的中间变量。
  • 对不会被子类化的类标记 final。
  • 收紧仅供内部使用的符号的访问控制(private/fileprivate)。
  • 将庞大的 SwiftUI body 属性提取为较小的组合子视图。
  • 将深层嵌套的结果构建器代码替换为独立的带类型辅助函数。
  • 为传递给泛型函数的闭包添加显式返回类型。
SPM 重构

重构 Swift 包,以提升构建并行度并缩小重新构建的范围。

常见修复:

  • 将共享类型移至较低层模块,以消除循环依赖或向上依赖。
  • 按功能领域拆分过大的模块(200 个以上文件)。
  • 将协议定义提取至轻量级接口模块。
  • 移除不必要的 @_exported import 用法。
  • 调整导入相同包的各目标的构建选项,防止重复生成模块变体。
  • 将跟踪分支的依赖固定到带标签的版本或提交哈希,以确保解析结果确定。

应用版本固定变更之前:

  • 运行 git ls-remote --tags <url>,确认标签存在。如果上游没有标签,请改为固定到特定的修订哈希。
  • 继续之前,使用 xcodebuild -resolvePackageDependencies 验证固定的版本能够成功解析。

执行工作流

  1. 阅读已批准的优化计划或开发者指令。
  2. 对于每个已批准的项目,确定要修改的具体文件和位置。
  3. 应用更改。
  4. 验证更改可编译:运行一次快速的 xcodebuild build,确认没有引入错误。
  5. 应用所有已批准的更改后,使用原始基准测试中的相同输入重新进行基准测试:
    python3 scripts/benchmark_builds.py \
      --project App.xcodeproj \
      --scheme MyApp \
      --configuration Debug \
      --destination "platform=iOS Simulator,name=iPhone 16" \
      --output-dir .build-benchmark
    
  6. 将更改后的中位数与基准进行比较,并报告差值。

评估回退

并非每个较慢的数值都是真正的回退。修复者在建议回退之前,必须全面评估整体情况。

编译缓存的权衡

像 COMPILATION_CACHE_ENABLE_CACHING = YES 这样的更改,可能会让标准干净构建稍微变慢(缓存填充开销),但会显著加快使用缓存的干净构建。由于使用缓存的干净构建更能反映开发者的实际工作流(切换分支、拉取更改,以及在缓存预热后执行 Clean Build Folder),因此标准干净构建变慢、而使用缓存的干净构建变快,属于净改进,而非回退。同样的逻辑也适用于首次成本较高、但后续构建会受益的任何更改。

比较所有构建类型

综合评估标准干净构建、使用缓存的干净构建(如有)和增量构建。只有当更改导致对开发者日常工作流真正重要的指标变差时,才算明显回退。如果只有冷启动干净构建变慢,而开发者很少进行真正的冷启动构建,这可能是可以接受的。

单项更改与累积效果

如果某项更改单独来看会导致性能回退,但它能带来更大的累积改进(例如,启用编译缓存会让一种构建类型变慢,却能为其他所有构建带来缓存收益),那么仍可能值得保留。

最佳实践设置不应考虑回退

某些构建设置是 Apple 推荐的现代默认配置。无论即时基准测试是否显示出可衡量的改进,都应应用并保留这些设置。它们不是推测性的优化,而是让项目与 Apple 的工具链发展方向保持一致,并将在未来的 Xcode 版本中持续带来累积收益。修复者绝不能仅凭单次基准测试结果建议回退这些设置。

应用后应始终保留的最佳实践设置:

  • COMPILATION_CACHE_ENABLE_CACHING = YES -- Apple 正在积极投入这项技术;缓存会随着每个 Xcode 版本不断改进,并在实际工作流中持续积累收益
  • EAGER_LINKING = YES(Debug)-- 允许链接器与编译并行进行
  • SWIFT_USE_INTEGRATED_DRIVER = YES -- 消除进程间调度开销
  • DEBUG_INFORMATION_FORMAT = dwarf(Debug)-- 避免不必要的 dSYM 生成
  • SWIFT_COMPILATION_MODE = singlefile(Debug)-- 支持增量重新编译
  • ONLY_ACTIVE_ARCH = YES(Debug)-- 在本地构建时没有理由构建所有架构

报告这些设置时,请使用类似以下措辞:“已应用推荐的构建设置。虽然未测得即时的基准测试改进,但此设置符合 Apple 推荐的配置,并有助于项目受益于未来 Xcode 的改进。”

何时建议还原(仅针对试验性更改)

对于不属于最佳实践设置的更改(例如,源代码重构、链接实验、脚本阶段修改、依赖项重组):

  • 如果累计测试显示所有测量的构建类型都出现实际耗时回退(标准干净构建、缓存干净构建和增量构建均变慢),则建议还原所有试验性更改,除非开发者明确要求出于非性能原因保留特定项目。
  • 对于每项试验性更改:如果中位数没有改善,缓存构建和增量构建也没有收益,则标记为 Recommend revert,并注明测得的变化值。
  • 区分“仅减少异常值”(最差情况有所改善,但中位数没有改善)和“中位数改善”(开发者的典型等待时间有所改善)。
  • 如果某项更改在不同构建类型之间有所取舍(例如,标准干净构建变慢,但缓存干净构建变快),请清楚列出两者的数据,让开发者决定。表述为:“标准干净构建慢了 X.Xs,但缓存干净构建(更符合日常工作流)快了 Y.Ys。”

报告

以通俗语言说明实际耗时结果:

“现在,干净构建耗时 X.Xs(之前为 Y.Ys)——快了 Z.Zs。” “现在,增量构建耗时 X.Xs(之前为 Y.Ys)——快了 Z.Zs。”

然后列出:

  • 更改后的干净构建实际耗时中位数
  • 更改后的增量构建实际耗时中位数
  • 两者实际耗时的绝对变化值和百分比变化值
  • 基准测试噪声较大时的置信度说明
  • 每项修复修改的文件列表
  • 与原始建议不一致之处

如果累计任务指标有所改善,但实际耗时没有改善,请明确说明:“编译器工作量减少了,但构建等待时间没有改善。如果 Xcode 将这些任务与其他耗时相当的工作并行运行,这种情况是意料之中的。”

如果某项修复没有带来可测量的实际耗时改善,请注明 No measurable wall-time improvement,并建议是否应保留(例如,出于代码质量考虑)或还原。

对于因非基准测试原因而有价值的更改,请标注:“预计此项更改不会改善等待时间。其益处是[确定性构建/更快的分支切换/降低 CI 成本]。”

注意:在受测项目(包含 87 到 1,991 个 Swift 文件)中,COMPILATION_CACHE_ENABLE_CACHING 经测量可使干净构建快 5-14%。在缓存会在不同构建之间保留的实际开发工作流中,这项收益会累积,例如切换分支、拉取更改,以及使用持久化 DerivedData 的 CI。基准测试脚本会自动检测此设置,并运行缓存干净构建阶段进行验证。

执行报告

完成优化后,请生成结构化的执行报告。这能让开发者清楚了解尝试了哪些操作、哪些有效,以及最终状态如何。

结构:

## Execution Report

### Baseline
- Clean build median: X.Xs
- Cached clean build median: X.Xs (if applicable)
- Incremental build median: X.Xs

### Changes Applied

| # | Change | Actionability | Measured Result | Status |
|---|--------|---------------|-----------------|--------|
| 1 | Description | repo-local | Clean: X.Xs→Y.Ys, Incr: X.Xs→Y.Ys | Kept / Reverted / Blocked |
| 2 | ... | ... | ... | ... |

### Final Cumulative Result
- Clean build median: X.Xs (was Y.Ys) -- Z.Zs faster/slower
- Cached clean build median: X.Xs (was Y.Ys) -- Z.Zs faster/slower
- Incremental build median: X.Xs (was Y.Ys) -- Z.Zs faster/slower
- **Net result:** Faster / Slower / Unchanged

### Blocked or Non-Actionable Findings
- Finding: reason it could not be addressed from the repo

状态值:

  • Kept —— 更改变快或保持了构建速度,因此予以保留。
  • Kept (best practice) —— 更改属于推荐的构建设置;无论即时基准测试结果如何,均予以保留。
  • Reverted —— 更改导致构建速度回退,因此已还原。
  • Blocked —— 由于项目结构、Xcode 行为或外部限制,无法应用更改。
  • No improvement —— 更改已编译,但未显示可测量的实际耗时收益。请注明是出于非性能原因保留,还是已还原。

升级处理

如果在实施过程中发现超出此技能范围的问题:

其他资源

评论

支持 Markdown