我也遇到了同样的问题,经过大量调查发现,无论它在做什么,都是基于你拥有的Swift源文件数量。
根本原因
在2018年关于Xcode构建系统的wwdc演讲中,演讲者说(可在视频的文本副本中搜索):
这意味着与Clang不同,编译一个Swift文件时,编译器将解析目标中的所有其他Swift文件。
因此,即使增量构建只需要重新编译一个单独的文件,它仍会解析每个其他Swift文件。
我们的项目有超过2000个Swift源文件,我们看到重新编译单个独立文件的增量构建时间为3分钟以上。
测试证明根本原因
因为仅在WWDC演讲中听到不足以验证,我进行了以下测试:
- 创建了一个新项目
- 测试了几乎空项目的增量构建时间,更改单个文件
- 使用脚本生成了2,000个Swift文件,每个文件包含一个简单的结构体,具有唯一的名称,2个变量和一个简单的函数。这些文件之间没有依赖关系。
- 将包含2,000个新Swift文件的目录添加到项目中并完成完整构建。
- 再次为单个文件测试增量构建时间
在我的测试中,附加的Swift文件的复杂性似乎并不重要,只有文件数量。
解决方案 - 模块化/框架
将应用程序分成较小的框架,以减少每个目标中Swift源文件的数量。
如果您还不知道如何操作,这是一个不错的指南,显示了如何进行此操作的步骤。
在上面的测试用例中,我创建了一个新的框架,并将2,000个Swift文件移动到该框架中,然后在原始项目中(导入框架)测试了增量构建时间,构建时间回到了小于1-2秒。当然,在框架内进行增量构建仍然很慢,但理想情况下,您应该将项目拆分为许多较小的框架,以便每个框架都具有更快的增量构建时间。
非解决方案 - 合并文件
如果问题是文件数量,为什么不合并一堆文件以减少数量?因为这很可能会导致增量构建变慢。
根据
2018 WWDC的Xcode更快构建:
Swift的依赖模型基于文件。
这与我们目前的问题有关,因为它意味着对文件的任何更改(除了仅更改函数体内容)都将导致重新编译依赖于已更改文件中的任何内容的任何文件。
如果您将许多类型合并到单个文件中,则会在增量构建时重新编译更多代码,如果更改触及大文件或其任何依赖项中的任何内容,则会增加大文件的依赖项数量,使得所有依赖项都会在大文件中的任何类型被修改时重新编译。