Long story short, SPM dependencies are built in Xcode with code coverage flags for a release build. For this to happen there should be a Unit Testing Bundle within the project; the default test plan configuration has code coverage enabled (which is auto created once there is a test) and this option overrides the overall project level setting for code coverage... resulting in Xcode projects with 14.3(and maybe older) - 15.1 shipping with slower dependencies than need be, and probably affecting quite a few projects.
The workaround is to disable code coverage in the test plan configurations:
Hello I was unable to reproduce the issue from the minimal example you provided. I was able to build the application with and without test coverage (observing the mentioned compiler flags in the build logs). However the times for performing the calculations were the same in both cases. I tried to reproduce it on Xcode 15.0 and macOS 14.1.
I was also not able to observe the compiler flags from the minimal example in the build logs of our application which meets all the requirements that you have provided (have spm dependencies and testing targets defined, no test plan though).
We also observe a “weird” performance slowdown. Building our application in Release without “Debug executable” enabled leads to immense performance benefits. Swipe killing the application and starting it again leads to the performance as if we built it with “Debug executable” enabled (around 2 times worse performance on the tested devices). Starting the application from Instruments for cpu profiling also leads to the increased performance (regardless of how you built it). Downloading the app from the app store/installing a release binary built from CI and starting it manually leads to the worse performance. Our application is in background while doing the intensive work. Would be glad to know if the details I mentioned also apply to your case. Also any information on the topic is greatly appreciated.
You can pass any build setting to xcodebuild, and it will override what’s in the xcodeproj. In this case, @NeoNacho is suggesting to pass EXCLUDED_ARCHS=x86_64. An alternative would be passing ONLY_ACTIVE_ARCH=YES.
Correct, the time calculation here is the same since the sample calculation code is within Xcode project and does not include the code coverage flags. It is all projects from SPM that are build with code coverage and thus are slowed down.
What is important is that you have been able to observe compiler flag coverage flags in the logs.
Strange as the scheme should show an auto created test plan like:
Fixed: Schemes provide a new “Override Architectures” build option, which controls the set of architectures that will be built for all targets in the workspace, including Swift packages. The recommended option (and default for new schemes) is “Match Run Destination”. Full details are available by clicking the information icon next to the “Override Architectures” setting on the scheme build options sheet in Xcode. (66146584)
Match Run Destination - Build only the most appropriate architecture for each target, based on the selected run destination. Use this option to reduce build times for iterative development.
Universal - Build all compatible architectures for each target. Use this option when you want to verify all architectures build successfully, at the cost of slower build times.
Use Target Settings - For targets with the ONLY_ACTIVE_ARCH build setting set to YES, build only the most appropriate compatible architecture based on the selected run destination. For targets with the ONLY_ACTIVE_ARCH build setting set to NO, build all compatible architectures.
When using a build-only run destination and/or performing an Archive build, each target always builds for all available architectures regardless of the selected option.
Unfortunately this setting doesn't seem to work for me, as I still see x86_64 items being built when targeting the iOS simulator when either building "Match Run Destination" or "Use Target Settings" which is set to always only build the active arch. swift-syntax and compiler plugins still build universally. And Xcode 15.3 still has the overall build performance regression I reported for beta 1. So I'm afraid it won't help at all.
We have a macOS Apple-silicon only app that we (for reasons) primarily build in optimized mode - which so far has been building basically everything for x86/64 + arm. We have tried to get rid of the x86 builds as we don’t even have such a machine (and none of our users do either), but up until now even though we tried all the settings for the Xcode project to only build for arm, it only worked for debug builds - optimized builds would always build universally. Just checking the build log and you could see all source files build for both (and flipping back the new setting would regress the behavior so it’d build for both again).
With the new setting each source file is only built for arm as expected, which is fantastic - not sure why it doesn’t seem to work for you, can you see both arch’s being built in the log?