用途
该技能面向 Kotlin Multiplatform 项目中针对 iOS 的 Kotlin/Native 构建性能问题,帮助把“iOS 构建很慢”这一模糊抱怨转化为可测量的诊断和一组安全的小修复。
贯穿始终的两条规则:
- 绝不牺牲发布所需的行为。更快的本地循环不得改变 CI 发布的内容。
- 修复前后必须用相同命令和相同构建状态测量。未测量的修复只是猜测。
主要能力
第 0 步:对慢场景分类
在修改任何内容前先确认四个事实:位置(本地还是 CI)、对象(调试反馈循环还是发布/分发产物)、状态(首次构建、clean、warm 还是 no-op)、阶段(日志中哪些任务占主导)。然后匹配主要症状:
- 本地开发循环中出现 linkRelease* 或 *ReleaseXCFramework 任务:为开发构建了分发产物。
- 每次 CI 运行都下载 Kotlin/Native 编译器发行版:~/.konan 未在运行间保留。
- 第一个任务开始前有长时间停顿:配置阶段,未启用配置缓存。
- 只需要一个模拟器却构建了所有 iOS 目标:任务过宽(build、assemble、assemble*XCFramework)或存在未使用目标。
- ksp* 任务排在 compileKotlinIos* 之前:原生路径上存在生成代码工作。
- 小的源码改动导致全部重新编译和重新链接:编译器缓存被禁用,或缺少增量性。
- 多个 link* 任务同时运行时机器过载:并行原生链接。
第 1 步:审计与测量
从项目根目录运行静态审计:
scripts/audit-native-build.sh /path/to/project
该脚本只读,输出 file:line 形式的发现(禁用的缓存、过宽的本地任务、transitiveExport、过宽的 KSP 配置、缺失的 CI .konan 缓存),每条都指向带修复方法的参考文件。发现只是线索而非结论,需对照项目策略确认。
找到用户实际等待的命令:脚本、CI 步骤或 Xcode 构建阶段内的 Gradle 调用。优化那个命令,而不是自己挑选的任务。
条件允许时运行两次。首次构建会下载 Kotlin/Native 组件并填充缓存,只有第二次及之后的运行才有代表性。在归咎编译器前先按任务归因时间:
kotlin.build.report.output=file # writes build/reports/kotlin-build/
Gradle 的 --scan 或 --profile 也可用。
如果无法运行构建(没有 macOS 主机、没有 Xcode),则改为分析日志、构建扫描或已提交的指标,并明确说明结论是静态的。
第 2 步:按安全顺序修复
一次应用一个修复,边做边重新测量:
- 恢复健康默认值——移除缓存/守护进程的变通做法,启用 Gradle 构建缓存和配置缓存,在 CI 中保持 ~/.konan 预热,更新 Kotlin。参考 references/caching-and-gradle.md。
- 只构建反馈循环所需内容——每个循环一个具体任务,正确的集成方式,合理的目标矩阵。参考 references/artifacts-and-targets.md。
- 削减导出与生成代码成本——去掉 transitiveExport,收窄 export(...),将 KSP 工作限定到需要它的原生编译。参考 references/exports-and-generated-code.md。
- 实验性开关最后,且需用户同意。参考 references/experimental.md。
使用方式:一个完整示例
一位使用 Apple Silicon Mac 的开发者抱怨“每次共享模块改动要花 12 分钟”。其循环运行 ./gradlew :shared:assembleXCFramework。第二次(warm)运行的构建扫描显示:
- :shared:linkReleaseFrameworkIosArm64 348s
- :shared:linkReleaseFrameworkIosX64 341s
- :shared:compileKotlinIosX64 96s
- :shared:linkDebugFrameworkIosSimulatorArm64 41s
- :shared:compileKotlinIosSimulatorArm64 38s
- 配置阶段 64s
推理链:
- 该循环是本地 + 调试 + warm,但约 690s 花在 linkRelease* 上——发布链接比调试慢一个数量级,且只有 CI 需要它。将本地命令替换为 :shared:linkDebugFrameworkIosSimulatorArm64(或由 Xcode 驱动构建时的 Xcode 嵌入任务)。
- 所有 iosX64 工作服务于 Intel 模拟器;在移除该目标前先询问团队是否仍支持它们。
- 每次运行 64s 的配置在试用 org.gradle.configuration-cache=true 后消失。
改动后的预期循环:warm 构建下约 40s 编译 + 约 40s 链接——通过重新运行新命令两次并比较来确认。CI 保持 assembleXCFramework 不变;在报告中明确说明这一点。
验证
- 重新运行完全相同的基线命令;warm 构建与 warm 构建比较,而非 warm 与 cold 比较。
- 第二次运行启用配置缓存时报告其正在被复用。
- 本地开发日志不再包含 linkRelease*、*ReleaseXCFramework 或被移除的生成器任务。
- CI 仍产出所有必需的发布产物,保持不变。
- 测试通过,应用仍能从 Xcode 运行。
- scripts/audit-native-build.sh 不再报告你未有意接受并记录的发现。
报告改动
以简短性能说明收尾:
- 慢场景(本地/CI、调试/发布、cold/warm)及测量证据——或说明分析是静态的。
- 每项改动,以及为何它对发布行为是安全的。
- 用户可运行以确认收益的前后命令。
- 剩余权衡:启用的实验性标志、基于策略假设移除的目标、worker 限制或推迟的生成代码工作。
适用场景
适用于 Kotlin Multiplatform 项目中面向 iOS 的 Kotlin/Native 编译与链接缓慢的诊断与修复,尤其是本地开发反馈循环慢、CI 构建慢、发布产物构建耗时过长等场景。
限制
- 需要 macOS 主机与 Xcode 才能实际运行构建;否则只能做静态分析。
- 静态审计脚本的发现只是线索,需对照项目策略确认。
- 实验性开关需用户同意后才可使用。
- 移除目标等改动需先确认团队是否仍支持相关平台。
官方文档
- Improving Kotlin/Native compilation time:https://kotlinlang.org/docs/native-improving-compilation-time.html
- Kotlin Gradle plugin compilation and caches:https://kotlinlang.org/docs/gradle-compilation-and-caches.html
- iOS integration methods:https://kotlinlang.org/docs/multiplatform-ios-integration-overview.html
- Direct integration with Xcode:https://kotlinlang.org/docs/multiplatform/multiplatform-direct-integration.html
- Building final native binaries and XCFrameworks:https://kotlinlang.org/docs/multiplatform/multiplatform-build-native-binaries.html
- Kotlin/Native binary options:https://kotlinlang.org/docs/native-binary-options.html
- KSP with Kotlin Multiplatform:https://kotlinlang.org/docs/ksp-multiplatform.html