Improving Swift Debug Build Times

It’s well known that enabling Whole Module Optimization greatly reduces Swift build times, but did you know it’s possible to do this for debug builds without breaking the debugger? I didn’t.

Normally, one sets SWIFT_OPTIMIZATION_LEVEL to -Onone for development builds. Otherwise, the debugger will behave in ways that are expected but not helpful.

I wanted the build-time gains that come from enabling Whole Module Optimization without breaking the debugger. After some trial/error, I tried setting SWIFT_WHOLE_MODULE_OPTIMIZATION to YES and, to my surprise, it worked. And the debugger still worked in my testing.

This reduced debug build times by approximately 30% on a project I contribute to.

You might be run into an interesting compiler segmentation fault after enabling SWIFT_WHOLE_MODULE_OPTIMIZATION. If you do, check the build log for a stack trace that mentions SIL optimization. This’ll help you track down the function the compiler failed to optimize. You can try to rewrite it to avoid the failure or you can disable optimization for that function by annotating it like so:

func foo() {

Bonus tip: I ran into this dev forum thread, where an Apple engineer suggested setting HEADER_MAP_USES_VFS to YES. This apparently reduces the frequency of full-rebuilds in Xcode when incremental builds are expected.

Note that HEADER_MAP_USES_VFS won’t help in all situations and apparently does not work with some projects. Today, incremental builds in Swift are suboptimal in mixed-language targets. All Swift code and some Objective-C code will be recompiled if you change an Objective-C header that the compiler believes Swift code depends on. Still, I recommend setting HEADER_MAP_USES_VFS to YES.


Now read this

Resolving Conflict with Empathy

Note: I wrote the following note over a year ago, but only recently decided to send it to my newsletter. I’m not sure why I sat on it so long. Your [respectful] thoughts are welcome on Twitter. Empathy doesn’t always come easy, but it... Continue →