If your incremental (i.e. Debug) builds seem to be too slow, here some things to try (in no particular order):
In Xcode, go into the Report Navigator and examine your build log to see what's going on and where the time might be going.
See if some stage of your build is always replacing an imported file,
In "Other Swift Flags", add -driver-show-incremental and -driver-show-job-lifecycle. Then expand the build log portions of the "Compile Swift Source Files" build log entry. These options will cause the compiler to emit "remarks" explaining why the compiler decided to compile files.
If you are making lots of changes to top-level types, the incremental system won't be able to be as selective as possible. If you wrap one or more top-level types in an enclosing type, protocol, or extension, the compiler can be more selective.
In the build log, click on the hamburger all the way on the right of an "CompileSwiftSources" line, to expose the command-line-invocation of the compiler. Copy and paste the long invocation line into a text editor, and look for any of the following: -incremental (you want), -enable-batch-mode (you want), -disable-batch-mode (you don't want), -wmo (you don't want), and -whole-module-optimization (you don't want).
If you see any problems, there's an issue with your build settings.
When looking at the build log, make sure you have "Recent" and "All Messages" selected, as shown below. (It seems obvious, but when tired, I have made this mistake myself.)
Sorry for bumping this topic but I'm just trying these ideas, thanks for the post!
What kind of remarks? What should I be looking for? Can't see anything special with those flags.
I've tried these as well and don't see anything extra in the build logs when compiling Swift source. Even the exported raw build logs don't show any special output. What are these extra messages supposed to look like?
In Xcode, I had shown the build, selected All and All Messages, and clicked on the line: "Compile Swift Source files (arm64)" to expand the desired build log.
Are those supposed to appear before the rest of the content in the build log? In my builds I see various notes at the start but no remark lines.
Here's a log. As you can see, the flags are there in the driver invocations but there's no remark output.
An incremental Alamofire build log.
```
Showing Recent Messages
Prepare build
note: Using new build system
note: Planning
note: Build preparation complete
note: Building targets in dependency order
note: Swift build system integration enabled.
Analyze workspace
Build target Alamofire macOS of project Alamofire with configuration Debug
It looks like the build log you're looking at has been processed. Either what Xcode is showing you is different--maybe someone after me has made a change somewhere--or you're not seeing the output of the swiftc command. Hmmm....
Here's another experiment: copy the swiftc invocation out of the log, remove the -parsable-output flag, and run it from a shell.
[Which version of Xcode are you using, and are you looking at the build log in Xcode? Can you post a screen shot?]
This is the Xcode 13.2RC, though I also tried this on 13.1 before.
Copying the swiftc command (though there's no -parsable-output to remove) does result in the proper remarks. For example:
remark: Incremental compilation: Incremental compilation has been disabled, because different arguments were passed to the compiler
remark: Incremental compilation: Disabling incremental build: different arguments were passed to the compiler
remark: Incremental compilation: Read dependency graph '/Users/jshier/Library/Developer/Xcode/DerivedData/Alamofire-gqexvpxfnitcltctvgfmsnsdspgw/Build/Intermediates.noindex/Alamofire.build/Debug/Alamofire macOS.build/Objects-normal/x86_64/Alamofire macOS-master.priors'
Could be; builtin-Swift-Compilation could well be something added later. I wonder if there's some option somewhere causing it to be set? I'll see if I can get the same version of Xcode you're using.
My Xcode is not prepending that "builtin" thing. I even tried an xcodebuild from the shell and got the remarks in the output. At this point, I'm afraid I don't know, sorry.
I may have found the workaround. The new default, EnableSwiftBuildSystemIntegration seems to make the remarks disappear from the build log when it is enabled. You can try defaults write com.apple.dt.XCBuild EnableSwiftBuildSystemIntegration 0 to get them back.
What worked for me was quitting Xcode, setting the pref to 0, and restarting Xcode, then rebuilding with the Other Swift Options as above, and then looking at the "Compile Swift Sources" entry in the log.
Good luck!
We have project setup where we have a few frameworks and we use CocoaPods. We have Framework A, and Framework B depends on Framework A, and Framework B depends on some Cocoapods.
As a simple test scenario, I'm just modifying the body of a method, not a type name or signature. I see that the incremental build in Framework A is working well and only rebuilding that one file.
Framework B always triggers a complete re-compile though. There are a number of repeated remarks:
remark: Incremental compilation: Changed: RxDataSources-umbrella.h -> implementation of source file StringLocalizable.swiftdeps in StringLocalizable.swiftdeps
This repeats for every file that has an import RxDataSources
remark: Incremental compilation: Changed: HOPUtilities.h -> implementation of source file RxInlineAnimatedCollectionViewDataSource.swiftdeps in RxInlineAnimatedCollectionViewDataSource.swiftdeps
This repeats for every every file that has import FrameworkA
remark: Incremental compilation: Changed: module.modulemap -> implementation of source file UIColor+extensions.swiftdeps in UIColor+extensions.swiftdeps
This repeats for about everything it appears. Some of the files only have an import UIKit and only have top level declarations involving UIKit types.
Seems like there's something incorrectly triggering the change, as the .h files and module.modulemap from what appears to be UIKit is triggering recompliation – or I'm interpreting this output incorrectly!
Is there anywhere that documents the expected incremental build behavior? I was assuming that only changes to public signatures or public inlined bodies would trigger re-compilation but realize there's a lot of nuance. Is it expected to rebuild every file that imports Framework A if Framework A is re-built for any reason? That certainly would change our framework strategy substantially.
Thanks for this debug flag, it's great to have some ways to see how things are behaving.