Xcode 10 iOS应用程序构建,“隐藏”的任务占用大部分构建时间

9
在大型项目中更改单行代码并执行Xcode 10.1增量构建后,Xcode在完成所有列出的任务(编译更改的文件和合并swiftmodule都已完成)后,大部分构建时间都花费在“编译swift源文件”阶段。 任务列表截图:https://imgur.com/a/JoVI0zB 虽然编译和合并Swift模块只需要不到一秒钟,但整个阶段在我的项目(300k LOC)中可能需要长达2分钟。
Xcode在这段时间内做了什么?有没有办法加速这个过程?
写成Obj-C的类似项目在更改1行代码后只需要几秒钟即可启动。

我们在项目中看到完全相同的行为。由于这个隐藏的工作新构建系统以增量编译模式运行,结果是遗留的构建系统+ WMO更快。 - swasta
1个回答

11

我也遇到了同样的问题,经过大量调查发现,无论它在做什么,都是基于你拥有的Swift源文件数量。

根本原因

2018年关于Xcode构建系统的wwdc演讲中,演讲者说(可在视频的文本副本中搜索):

这意味着与Clang不同,编译一个Swift文件时,编译器将解析目标中的所有其他Swift文件。

因此,即使增量构建只需要重新编译一个单独的文件,它仍会解析每个其他Swift文件。

我们的项目有超过2000个Swift源文件,我们看到重新编译单个独立文件的增量构建时间为3分钟以上。

测试证明根本原因

因为仅在WWDC演讲中听到不足以验证,我进行了以下测试:

  1. 创建了一个新项目
  2. 测试了几乎空项目的增量构建时间,更改单个文件
    • 增量构建几乎瞬间完成(小于1-2秒)
  3. 使用脚本生成了2,000个Swift文件,每个文件包含一个简单的结构体,具有唯一的名称,2个变量和一个简单的函数。这些文件之间没有依赖关系。
  4. 将包含2,000个新Swift文件的目录添加到项目中并完成完整构建。
  5. 再次为单个文件测试增量构建时间
    • 增量构建时间超过1分钟

在我的测试中,附加的Swift文件的复杂性似乎并不重要,只有文件数量。

解决方案 - 模块化/框架

将应用程序分成较小的框架,以减少每个目标中Swift源文件的数量。

如果您还不知道如何操作,这是一个不错的指南,显示了如何进行此操作的步骤。

在上面的测试用例中,我创建了一个新的框架,并将2,000个Swift文件移动到该框架中,然后在原始项目中(导入框架)测试了增量构建时间,构建时间回到了小于1-2秒。当然,在框架内进行增量构建仍然很慢,但理想情况下,您应该将项目拆分为许多较小的框架,以便每个框架都具有更快的增量构建时间。

非解决方案 - 合并文件

如果问题是文件数量,为什么不合并一堆文件以减少数量?因为这很可能会导致增量构建变慢。
根据2018 WWDC的Xcode更快构建
Swift的依赖模型基于文件。
这与我们目前的问题有关,因为它意味着对文件的任何更改(除了仅更改函数体内容)都将导致重新编译依赖于已更改文件中的任何内容的任何文件。
如果您将许多类型合并到单个文件中,则会在增量构建时重新编译更多代码,如果更改触及大文件或其任何依赖项中的任何内容,则会增加大文件的依赖项数量,使得所有依赖项都会在大文件中的任何类型被修改时重新编译。

我还应该提到,在我描述的项目和测试项目中,我看到了你提到的完全相同的问题,即“编译Swift源代码”阶段的各个任务显示为已完成,但在显示整个阶段完成之前仍然停留更长时间。您可以通过按照我列出的类似步骤,在新项目上自行重现此问题。 - Helam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接