Xcode modern build system complaints

After years of using the legacy build system, I finally gave in and decided to convert my project so that it would build using the modern build system. I gave in because rather than being warned that the legacy build system was deprecated, Xcode 13 now treats it like an error.

My application is available for Windows and Linux too and uses common code written in C/C++ with the GUI written in objective-c (no Swift at all). There's also a console version and shared library version for Python support. There are multiple versions of my application (think lite, consumer, and pro) which I have as separate targets. The console and shared library versions are also separate targets. My application requires a bunch of support files that are contained outside of the main application in a separate directory so I have a custom build location Xcode project setting that places the application into that directory.

  • The modern build system is very slow. I can do a fresh build of the third party libraries, frameworks, and multiple Universal versions of my app using the legacy build system in 8 minutes. The modern build system takes 16 minutes.

  • After I do a fresh build, if I make no changes and build again, all my code (but not the third party libraries and frameworks for some reason) gets recompiled. After the second time though, selecting build again only recompiles changed files. This has been true for years though and is not unique to the modern build system. Although I used precompiled headers, it's not a PCH problem because I turned it off and still observed the same problem.

  • Because I have separate versions of my application in addition to console and share library versions, I put the console and shared library in MyApp.app/Contents/MacOS/ directory. With the legacy build system, I could use set that as the build location for the console and shared library versions but the modern build system now complains about multiple commands producing the MacOS directory. So now I have to use an aggregate target (that has the different targets as dependencies) that copy the executable and library to the correct location. And now I have the original console executable and shared library lying around.

  • Clean Build Folder no longer works due to the custom build location. I get error messages that the custom build directory can't be deleted. I now use make clean from a terminal with the -UseModernBuildSystem=NO option for xcodebuild in the makefile.

  • I used to be able to use a single Info.plist file that's macro'd up that's shared by my multiple targets. I have a build phase script that reads the version and build number from a file and injects it into the Info.plist and reverts the file after a target has been successfully built (reverted for source control reasons). But Xcode wants to do parallelized builds so I can no longer modify/revert the single Info.plist file. Each target now must have their own Info.plist file even though they're all identical. Not a problem, I'll copy the source Info.plist file to the target Info.plist file as a build phase and inject the version number into that. Nope, the modern build system doesn't like having files not existing when it's preparing to build even though the files will eventually exist when it gets to that build step.

The worse thing though is how slow the modern build system is.

I’m just another forum member here, but I wanted to comment. I personally appreciate you taking the time to detail this, because I have some older projects that will face some of these issues.

I should've pointed out that I don't distribute from the Mac App Store but outside of it. I use a Developer ID certificate to sign my app and an installer certificate to sign my app's installer.

I just noticed another annoying thing. The pro version of my app uses a shared library that's placed in the Resources folder of the app bundle. But now that I can't use the MacOS folder of the app bundle as a build location for my console and shared library versions, they don't have access to the necessary shared library from the Resources folder and Xcode is creating a separate Resources folder for them. All this because the modern build system treats shared folders being created by different targets as an error. I'm not sure Apple is putting too much effort in supporting those of us who don't wish to distribute via the Mac App Store in Xcode.

I can still use the legacy build system but I just want to be prepared for when it's no longer available.

Here's another annoyance. To prevent myself from mistakenly shipping a debug build of my app(s), I have different product names for the debug and release builds. But in the Products group of my Xcode project, rather than Xcode listing products A, B, and C, products A Debug, B Debug, and C Debug are listed instead. Even if I go into the project.pbxproj file and manually remove Debug from the product names under the Products group, Xcode insists on putting Debug right back in the names. Not a big deal. However, with the modern build system, I also end up with extra empty app bundles A Debug.app, B Debug.app, and C Debug.app even though I'm just building release builds. This didn't happen with the legacy build system.

A new annoyance with Xcode 13--while building, you no longer see the current target being built in the project status bar.

Xcode modern build system complaints
 
 
Q