swift
swift copied to clipboard
Regression: Xcode 15 cannot build correctly for macOS versions older than 10.15
Description According to the documentation, Xcode is supposed to be able to build for macOS 10.13 and up. However, this does not seem to be the case in practice; my testers on 10.14.6 have reported random crashes when trying to test my app when built with Xcode 15 beta. I've isolated the code that crashes to a simple test case, and posted it on GitHub Issues, but it seems to have attracted no attention:
https://github.com/apple/swift/issues/67614
I've reproduced the bug in Xcode 15 beta 5, beta 6, and beta 7.
What's more, I decided to spin up a macOS 10.13 VM in UTM to see what would happen there. On 10.13 it doesn't even launch:
dyld: Library not loaded: @rpath/libswiftCore.dylib
Referenced from: /Users/csrstka/Desktop/crashtest
Reason: image not found
Abort trap: 6
It seems that Xcode 15 is not correctly including the embedded Swift libraries for use on macOS versions older than 10.15. On macOS 10.14.6, it seems there are embedded Swift libraries in /usr/lib/swift, but they are apparently buggy and not compatible with modern Swift code. The net result is that although it claims to be able to build for 10.13, the effective minimum target is 10.15, and this should either be fixed before release, or the documentation should be updated to reflect the change.
Steps to reproduce
Write this code to a file called crashexample.swift:
class MyObject {
var dict: [String : String] = [:]
}
print("creating object")
let obj = MyObject() // crashes here
print("created object") // will never be logged
print("object is \(obj)")
Then compile it with the following command:
swiftc -O -target x86_64-apple-macos10.13 crashexample.swift
Now copy the resulting binary to a Mac running an older macOS version. On 10.14.6 it will crash. On 10.13 it will not even start up.
Expected behavior Code should work, and not crash, or Xcode should be updated to reflect that its actual minimum target is 10.15.
Environment
- Swift compiler version info
$ swiftc -version
swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.106 clang-1500.0.40.1)
Target: arm64-apple-macosx13.0
- Xcode version info 15 beta 7 (15A5229h) but it has also happened in betas 5 and 6
- Deployment target: macOS 10.13
Thank you for the report. Both reports, that is, and sorry we missed the earlier one.
I believe there are two separate problems here. The dyld error on 10.13 is due to the runtime not being present on that OS. Xcode will copy the back-deployment runtime into a .app, but if you're building a bare executable, there's no place to put it. You can install this to allow bare Swift executables to work: https://support.apple.com/kb/DL1998?locale=en_US
The crash on 10.14.6 looks like a codegen problem. I was able to reproduce it here with your example. I'm fairly ignorant of compiler matters but I'll be sure this gets attention from the right folks.
I've filed a matching issue internally: rdar://114699006.
We have the similar problem on iOS sample project with the same code.
The iOS sample project's minimum deployments is set 10.0, build the app use XCode beta 8 with Release Configuration, then run the app in iOS 10、iOS 11、 iOS12 will crash.
This bug would also affect iOS 12, so you're presumably seeing the same problem.
I believe there are two separate problems here. The dyld error on 10.13 is due to the runtime not being present on that OS. Xcode will copy the back-deployment runtime into a .app, but if you're building a bare executable, there's no place to put it. You can install this to allow bare Swift executables to work: https://support.apple.com/kb/DL1998?locale=en_US
Unfortunately the linker errors occur on 10.13 even with an .app, although it is a little different. On 10.13 with an app, I get:
dyld: Library not loaded: @rpath/libswiftAppKit.dylib
Referenced from: /Users/_redacted_/Desktop/test.app/Contents/MacOS/test
Reason: Incompatible library version: test requires version 45.0.0 or later, but libswiftAppKit.dylib provides version 1.0.0
Abort trap: 6
I'm attaching the Xcode project for the test app, although there's nothing special about it—it's just a stock app built for 10.13.
Thanks, I'm able to replicate that problem as well. Filed this internally, and I'll get it to the right people: rdar://114820860
As a workaround, you can add $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/macosx/libswiftAppKit.dylib to your Other Linker Flags build setting in Xcode. You'll want to remove that if and when you increase your deployment target past 10.13.
Thanks @mikeash. Always enjoyed those "Let's Build" articles back in the day :)
Glad you liked them! And thanks again for the reports here.
On top of that Xcode 15 will fail to weak link libraries prior to macOS 11, so if you have a library whose symbols were not available prior to macOS 11 and you used those symbols with
if (@available(macOS 11.0, *)) {
or the Swift equivalent
if #available(macOS 11.0, *) {
then those symbols were weakly linked and as a result, the entire library was weakly linked. To provide an example, UniformTypeIdentifiers.framework was not available prior to macOS 11. But with Xcode 15, it is now strong linked and thus you'll also end up with dyld error when trying to start on an early system. The workaround for this issue is to pass -Wl,-ld_classic to the Other Linker Flags, the weak linking works correctly again.
As a workaround, you can add
$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/macosx/libswiftAppKit.dylibto your Other Linker Flags build setting in Xcode. You'll want to remove that if and when you increase your deployment target past 10.13.
I wonder how this workaround actually works. When I check libswiftAppKit.dylib, the system tells me that this is x86_64 only file, still the project builds fine for both, x86_64 and ARM and also runs fine on ARM. That's against my expectations, I would expect the linker to complain when linking for ARM.
Sometimes when making an Analyzer build, I get a warning that libswiftAppKit.dylib is not available for all build architectures and whether I want to build for Rosetta instead. This meats my expectations far better but what I don't get is why I would only sometimes see this dialog and not every time I run an Analyzer build and also not when doing an Archive (aka Release) build.
Now that you mention it, I'm also a little surprised the linker doesn't complain. I would expect it to only be a warning, at least, and be a no-op when targeting ARM. And it's OK for it to be a no-op on ARM, because ARM support only goes back to macOS 11.
I do get a warning when linking the ARM binary:
Ignoring file libswiftAppKit.dylib, building for macOS-arm64 but attempting to link with file built for macOS-x86_64
I can confirm that it still happens with Xcode 15.0. I got alerted after receiving a negative review for my App Store app after publishing an update built with Xcode 15.0, which I thought still supported macOS 10.13. Why does it take so long to fix this issue?
I can confirm that it still happens with Xcode 15.0. I got alerted after receiving a negative review for my App Store app after publishing an update built with Xcode 15.0, which I thought still supported macOS 10.13. Why does it take so long to fix this issue?
This is a new issue in Xcode 15.0.
Problem was not present in previous versions.
This is a new issue in Xcode 15.0. Problem was not present in previous versions.
I mean that it still happens after all the beta releases.
The release notes of Xcode 15.1 beta do not address this issue at all. It's neither listed as solved issue nor as a known issue.
The release notes of Xcode 15.0 at least list that as a known issue:
Swift apps built with Xcode 15.0 crash on launch on macOS 10.13. (114820860)
Workaround: Add $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/macosx/libswiftAppKit.dylib to the Other Linker Flags build setting in Xcode. This should be removed when the deployment target is increased to 10.14 or later.
https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes
Good news are that another issue is solved with 15.1:
Fixed: Binaries using symbols with a weak definition crash at runtime on iOS 14/macOS 12 or older. This impacts primarily C++ projects due to their extensive use of weak symbols. (114813650)
https://developer.apple.com/documentation/xcode-release-notes/xcode-15_1-release-notes
That is unless you use weak symbols with LTO, this can still fail and is still listed as a known issue:
Weak symbol imports are linked as non-weak imports, when used from LTO object files. (115521975)
Workaround: Add -Wl,-weak_reference_mismatches,weak or -Wl,-ld_classic options to the OTHER_LDFLAGS build setting.
Since other problems with Xcode 15 prevents me from making a testable release build at the moment, I cannot test myself if Xcode 15.1 might also address 114820860 already and it's just not in the release notes. I case it doesn't, at least there is hope that an upcoming beta might do so.
The release notes of Xcode 15.0 at least list that as a known issue:
Better than nothing. But if Xcode 15 officially supports macOS 10.13, then it shouldn't take so long to fix the issue. Since it was known from the beginning, Xcode 15 should have removed support for 10.13 at least as long as the issue wasn't fixed. Not everybody reads the release notes.
Solved in Xcode 15.1 beta
@michaeljtsai the issue was finally confirmed with a workaround in the Xcode 15.1 Beta 2 release notes: https://forums.swift.org/t/regression-xcode-15-cant-build-swift-for-macos-earlier-than-10-15/66986/8 The Beta 3 release notes state "Fixed: Swift apps built with Xcode 15.0 crash on launch on macOS 10.13. (114820860)"
Beta 3 release notes state "Fixed: Swift apps built with Xcode 15.0 crash on launch on macOS 10.13. (114820860)"
Just put it to the test ... and the answer is: Fixed! 🥳
Xcode 15.1 Beta 3 can make builds that run on macOS 10.13 and you neither have to explicitly use the legacy linker (-Wl,-ld_classic), nor do you need the Swift compatibility hack ($(TOOLCHAIN_DIR)/usr/lib/swift-5.0/macosx/libswiftAppKit.dylib).
Now I only need to figure out, why those builds still crash on 10.14. They run fine on 10.13 and 10.15, but still crash on 10.14 as the dynamic linker still tries to load a symbol that apparently is not there. It fails in dyld::fastBindLazySymbol(ImageLoader**, unsigned long) and the symbol it cannot find is _$s7Network13NWProtocolTCPC7OptionsCMa, which is expected to be found in /System/Library/Frameworks/Network.framework/Versions/A/Network. Building the same Xcode project with Xcode 14.3.1 results in a build that works just fine on macOS 10.14
I am using Xcode 15.1 to compile my project against macOS 13.1 SDK (targeting macOS 10.9).
The compiled app ridiculously asks for SwiftUI support on macOS 10.9 and macOS 10.13.6.
Process: vChewingInstallerLegacy [422]
Path: /Users/USER/Desktop/vChewingInstallerLegacy.app/Contents/MacOS/vChewingInstallerLegacy
Identifier: org.atelierInmu.vChewing.vChewingInstallerLegacy
Version: 3.6.3 (3631)
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: vChewingInstallerLegacy [422]
User ID: 501
Date/Time: 2023-12-26 21:57:28.868 +0800
OS Version: Mac OS X 10.13.6 (17G14042)
Report Version: 12
Anonymous UUID: C339FA0C-FB59-DEAA-8724-C5FE836A1F10
Time Awake Since Boot: 97 seconds
System Integrity Protection: disabled
Crashed Thread: 0
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: DYLD, [0x1] Library missing
Application Specific Information:
dyld: launch, loading dependent libraries
Dyld Error Message:
Library not loaded: /System/Library/Frameworks/SwiftUI.framework/Versions/A/SwiftUI
Referenced from: /Users/USER/Desktop/vChewingInstallerLegacy.app/Contents/MacOS/vChewingInstallerLegacy
Reason: image not found
Binary Images:
0x109173000 - 0x10919aff7 +org.atelierInmu.vChewing.vChewingInstallerLegacy (3.6.3 - 3631) <CD605A3A-57E2-3E3C-9DE4-8522F41A24E8> /Users/USER/Desktop/vChewingInstallerLegacy.app/Contents/MacOS/vChewingInstallerLegacy
0x114801000 - 0x11484badf dyld (551.5) <CB9BFB56-4511-36F1-A546-891FF770C01C> /usr/lib/dyld
0x7fff29298000 - 0x7fff2a0f6fff com.apple.AppKit (6.9 - 1561.61.100) <4E6EA3FA-8C2C-3B21-BFF9-6F8C458B7BE1> /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
0x7fff2aff8000 - 0x7fff2aff8fff com.apple.Carbon (158 - 158) <F8B370D9-2103-3276-821D-ACC756167F86> /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
0x7fff2bc58000 - 0x7fff2c0fbfe7 com.apple.CoreFoundation (6.9 - 1455.300) <CB44B892-64CD-3E32-A518-6D40B1A7033F> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
0x7fff2c0fd000 - 0x7fff2c70dfef com.apple.CoreGraphics (2.0 - 1161.21.5) <6451A561-3A83-37FB-AAA7-3FCE6D95C34C> /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics
0x7fff2ddbc000 - 0x7fff2e183ffb com.apple.Foundation (6.9 - 1455.300) <0479E072-1DD0-3881-A9A2-EDAD3EE58C23> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
0x7fff2e49a000 - 0x7fff2e535fff com.apple.framework.IOKit (2.0.2 - 1445.71.6) <4B5C715C-6A49-366B-9080-ABADE6A3B3BD> /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
0x7fff37ade000 - 0x7fff37e09fff com.apple.security (7.0 - 58286.70.19) <E118FC23-2E20-3999-826B-58488049A277> /System/Library/Frameworks/Security.framework/Versions/A/Security
0x7fff50c23000 - 0x7fff50c24ffb libSystem.B.dylib (1252.50.4) <5A02016C-8F9D-3F47-8C39-AD2CD4F9F11D> /usr/lib/libSystem.B.dylib
0x7fff522dc000 - 0x7fff526ca7e7 libobjc.A.dylib (723) <843EFB54-EFCC-3A7C-BE11-092B6A556262> /usr/lib/libobjc.A.dylib
Model: VMware7,1, BootROM VMW71.00V.21805430.B64.2305221826, 4 processors, 3.04 GHz, 8 GB, SMC 2.8f0
Graphics: Display, 128 MB
Memory Module: RAM slot #0/RAM slot #0, 8 GB, DRAM, 0 MHz, VMware Virtual RAM, VMW-8192MB
Bluetooth: Version 6.0.7f22, 3 services, 26 devices, 1 incoming serial ports
Network Service: Ethernet, Ethernet, en0
Serial ATA Device: VMware Virtual SATA Hard Drive, 42.95 GB
Serial ATA Device: VMware Virtual SATA CDRW Drive
USB Device: USB 2.0 Bus
USB Device: USB Bus
USB Device: VMware Virtual USB Hub
USB Device: Virtual Bluetooth Adapter
USB Device: VMware Virtual USB Keyboard
USB Device: VMware Virtual USB Mouse
Thunderbolt Bus:
I repeated this bug with Xcode 15.1 built-in SDK (targeting macOS 10.13).
It seems like an issue with Xcode itself. I am sending a DTS to Apple.
It seems like an issue with Xcode itself. I am sending a DTS to Apple.
Did you get any response from Apple?
@nickasd No. However, I found a workaround. It might not work with you, but it worths trying.
The workaround is: Disable "Generate asset symbols" for SwiftUI. This option generates symbols for SwiftUI which creates SwiftUI dependencies.
Same bug here with Xcode 15.2/15.3 - app crashing on customer systems with 10.13 and 10.14 due to SwiftUI being referenced.
The app uses AppKit, Obj-C, and Swift. No SwiftUI whatsoever. Referenced nowhere, imported nowhere, nothing in the build log… Still it's randomly referenced in the binary according to otool -L
The asset symbol workaround appears to work - so far…
Please be aware that a similar Xcode bug like the one discussed above has surfaced recently: Search for FB13820420 on https://mjtsai.com/blog/2024/05/13/xcode-15-4/#xcode-15-4-update-2024-06-12
@fedoco
Thanks for your precious intel. My decision of keeping my mac at Xcode 15.3 is right.
I do wonder why the bloody hell Xcode 15.4 got released without unit tests against macOS 10.13 target. // Not talking about runing Xcode on it but let the apps built by Xcode run on it.
Did I miss something? Did anyone left a message here 2 days ago?