Swift 5.5.2 (Xcode 13.2 beta) fails to link libswift_Concurrency.dylib

Executive Summary:

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:

  1. vapor new hello
  2. 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...

2 Likes

@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 have also created an issue on [SR-15445] swift test fails on 5.5.2: Library not loaded: @rpath/libswift_Concurrency.dylib - Swift

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 see that the Apodini repository sets the macOS deployment target to12.0, so it's expected that the binary crashes on earlier versions of macOS.

Have you tried this with an earlier deployment target, e.g., macOS 11 or 10.15? And are you using concurrency features or not?

Doug

Thanks a lot for the response! Sorry about the inconvenience of not being clear enough in the bug report.
We have been using macOS 12 until now as we were using async/await without any availability checks so far. I have updated the deployment target to macOS 11 in the branch that the build error in the bug report originated from which is associated with the following PR: Update GitHub Actions and Set the Platform Requirement to macOS 11 by PSchmiedmayer · Pull Request #374 · Apodini/Apodini · GitHub. I have also updated [SR-15445] swift test fails on 5.5.2: Library not loaded: @rpath/libswift_Concurrency.dylib - Swift with that information.

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.

5 Likes

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)

still having this issue with the Xcode 13.2 GM release (running on Big Sur)

Still happening on Xcode 13.2.1 here. We're not using async await - why is this dependency being added?

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.

Edit: Actually, you're likely seeing a different issue that the original one described here: Swift Concurrency back-deploy issue

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.

Yes possibly seeing another issue, but all our users are reporting the same thing - crash at launch with libswift_Concurrency missing.

There are two issues:

  • libswift_Concurrency missing 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_Concurrency existing 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?