After some investigation the issue boils down to "CLI apps that use async/await crash on pre-macOS12"
Attached is a package that demonstrates the issue: hello-cli.zip
I have a command line server built using Vapor (pinned to version 4.0.0) (the server is an SPM package).
Using Xcode 13 / Swift 5.5 it built and ran fine on my macOS 11.5.2
I downloaded Xcode 13.2 beta / Swift 5.5.2 and it seems the new compiler tries to backport the new Concurrency module and fails:
marin@Marins-MacBook server % swift --version
swift-driver version: 1.26.18 Apple Swift version 5.5.2 (swiftlang-1300.0.40.106 clang-1300.0.29.21)
Target: x86_64-apple-macosx11.0
marin@Marins-MacBook server % swift run
[0/0] Build complete!
dyld: Library not loaded: @rpath/libswift_Concurrency.dylib
Referenced from: /server/.build/x86_64-apple-macosx/debug/Run
Reason: image not found
zsh: abort swift run
The package targets macOS 10.15 and newer, I'm just cd-ing into the package folder and running swift run.
Is that a beta bug or is it supposed to not work with 5.5.2, I'm not quite sure.
Update 1: I get the same crash if I just create a new vapor app:
vapor new hello
cd hello & swift run dyld: Library not loaded: @rpath/libswift_Concurrency.dylib
Update 2: swift package init --type=executable && swift run spits a few warnings from the linker but the binary runs without crashing...
@icanzilb We experience the same issue with Apodini when running swift test
Merging module ApodiniTests
Linking ApodiniPackageTests
Build complete!
xctest[14418:40935] The bundle “ApodiniPackageTests.xctest” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
xctest[14418:40935] (dlopen_preflight(/Users/runner/work/Apodini/Apodini/.build/x86_64-apple-macosx/debug/ApodiniPackageTests.xctest/Contents/MacOS/ApodiniPackageTests): Library not loaded: @rpath/libswift_Concurrency.dylib
Referenced from: /Users/runner/work/Apodini/Apodini/.build/x86_64-apple-macosx/debug/ApodiniPackageTests.xctest/Contents/MacOS/ApodiniPackageTests
Reason: image not found)
Unfortunately the workaround detailed in your "Update 2" doesn't work for us as we need to run tests.
I get this error on one machine but the exact same code/command works for me on another. The most obvious difference between the two is that the working one running macOS 11.6 and the non-working one is running 11.4.
I'm seeing it with a deployment target of macOS 11. We have code which uses the concurrency features which is guarded by @available(macOS 12), so I'm expecting none of it to be hit currently.
For anyone needing this now, and can't wait for a new version of Xcode, this linker path seems to work: swift test --configuration debug -Xlinker -rpath -Xlinker "$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.5/macosx"
Note that you may need to add the -Xlinker -rpath -Xlinker "$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.5/macosx" bit to your swift build commands as well, as the tests may run without re-building in some circumstances.
I've tried to run the package with Xcode 13 Beta 2 on macOS 11 (11.6.1) and it fails for me with a different error:
❯ swift --version
swift-driver version: 1.26.21 Apple Swift version 5.5.2 (swiftlang-1300.0.47.2 clang-1300.0.29.30)
Target: x86_64-apple-macosx11.0
❯ swift run
[0/0] Build complete!
fish: Job 1, 'swift run' terminated by signal SIGSEGV (Address boundary error)
Are you running on iOS < 13 and does one of your dependencies or other libraries offer async APIs? If so, the concurrency library is added, even if you never call the code. For example, anyone updating to Alamofire 5.5 will hit this since I added various async APIs for iOS 13 and above. It seems like it should just be stripped when deploying to older OSes, but I don't know if the solution is that simple.
No they do not. I've tried the work-around posted for Xcode 13.2 (on Xcode 13.2.1) but it does not work either. I've also tried adding libswift_Concurrency as an optional dependency under Build Settings manually but that also causes the app to crash for macOS 10.13 and below. We've now had to revert to Xcode 13.1 as we can no longer rely on 13.2.x to produce a working build for older macOS versions.
libswift_Concurrencymissing when using Xcode 13.2 and deploying to the back deployment targets like iOS 13 and 14. This is exacerbated on App Store Connect by using bitcode, which was recompiled with newer tools that expected the concurrency library. This has a workaround in the Xcode release notes (manually set up the linking).
libswift_Concurrencyexisting when using Xcode 13.2.1 and deploying back to OS versions which predate concurrency back deployment, like iOS 12. That fails with the linking error since it's built for a newer OS and uses symbols that don't exist. As far as I know there's no workaround for this issue, but it only occurs if the app includes any concurrency code at all, even if it's behind availability checks. So removing all concurrency code may help, or going back to older Xcode versions.
We're not using any concurrency related code whatsoever as far as I can see. At least none of the code we have direct control over. I've checked all the various modules we rely on - none of them seem to be using concurrency. I could of course be very wrong as there may be some module using concurrency (behind availability checks) but none that I could find at first glance. Either way, we've downgraded to Xcode 13.1 for now.
Update: okay I found the culprit. We're using Crashlystics. Firebase seems to have a unit test (in StorageAsyncAwait.swift) that uses async behind an availability check. That is causing this! What's funny is how it's just a unit test - we're not even building / including that target / code. Why should it still add this dependency?