Xcode 12.5 dyld issue with binary frameworks
Asked Answered
J

2

6

I have a binary Swift xcframework which references two other open-source Swift frameworks (built from source).

My framework along with its dependencies are built with the BUILD_LIBRARY_FOR_DISTRIBUTION option enabled (in order to support module stability).

This setup has worked fine for many years, but now when building my framework in Xcode 12.5 or above, I'm getting the following dyld error when an app using the framework is compiled in Xcode <12.5:

dyld: Symbol not found: __ZN5swift34swift50override_conformsToProtocolEPKNS_14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EEPFPKNS_18TargetWitnessTableIS1_EES4_S8_E

I do not seem to be the only one experiencing this problem. A look on Github provides a number of other frameworks experiencing the same issue in Xcode 12.5.

It is suggested here that this issue is being caused by the following warning apparently now causing this fatal error:

Using 'class' keyword for protocol inheritance is deprecated; use 'AnyObject' instead

I note that the affected dependency involved in my case (Starscream) has not yet changed the class keyword to AnyObject, however I have not (yet) verified this is definitely the cause.

Unfortunately there is very little documentation out there about this issue, but it seems like it could potentially be quite widespread and increasing in prevalence as people upgrade to Xcode 12.5+, and more binary frameworks are built against this new version.

Does anyone have any ideas about how this can be resolved/mitigated, other than downgrading to Xcode 12.4?

Janeljanela answered 3/8, 2021 at 21:17 Comment(1)
i am also facing same issue with my custom framework with dependencies. when i set BUILD_LIBRARY_FOR_DISTRIBUTION = "NO" my framework is working. but if i set BUILD_LIBRARY_FOR_DISTRIBUTION = "YES" i am getting same error with yours. btw i am using Xcode 13 did you find any solution or do i have to downgrade Xcode 12.4.Prevocalic
M
2

We ran into this issue as well when updating to Xcode 12.5. According to Apple, "module stability" only ensures that frameworks built in older versions of Xcode will work in newer versions of Xcode. Up until 12.5, it has conveniently worked the other way around as well, but it seems like they decided to make some breaking changes.

The workaround that we've been doing is using the xcodebuild system of 12.4 to compile our frameworks dependencies, while still using the 12.5 GUI for daily development. Switching to the older build is done by downloading the Xcode from the Developer Downloads and renaming it Xcode_12_4.

export DEVELOPER_DIR=/Applications/Xcode_12_4.app/Contents/Developer

Although, because of this definition of module stability, I would strongly advise building with the minimum version of Xcode that your framework officially supports. (which must be at least 12.0 to submit to the App Store) This would ensure that there would be no possible issues with anyone using your framework in an older Xcode version.

I know that's a pretty disappointing non-answer, but it can be a fairly sustainable process. Framework development on iOS seems to be moving in the direction of requiring the developers to use the minimum version of xcodebuild that they expect their implementers to be using.

Another work-around that is sometimes available:

This issue can be avoided by building your dependencies from source (assuming their license permits it). We built Starscream from source and it works quite well. (i.e. looking at the dependency GitHub if they post their source code, then copying it into a directory in your framework)

Megasporangium answered 17/8, 2021 at 0:14 Comment(2)
Thanks for the comprehensive answer, but do you have a source for the statement that '"module stability" only ensures that frameworks built in older versions of Xcode will work in newer versions of Xcode'? This is news to me!! The problem with building against older versions of Xcode is that we are unable to make use of newer language features, so not ideal. It also seems that Xcode <13 will not run on Monterey. The workaround you describe involves distributing the dependencies as pre-compiled binaries, which is also not ideal (and breaks the whole dependency management ecosystem) :(Janeljanela
I raised the question with DTS and was directed by Apple to the following forum post which supports what you're saying @Callum: developer.apple.com/forums/thread/… -- seems to be related to thisJaneljanela
E
1

We hit

dyld: Symbol not found: __ZN5swift34swift50override_conformsToProtocolEPKNS_14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EEPFPKNS_18TargetWitnessTableIS1_EES4_S8_E
  Referenced from: our.framework/our
  Expected in: .../PromiseKit/PromiseKit.framework/PromiseKit
 in .../Foo.app/Frameworks/our.framework/our

with our framework which we distribute as binary. We were still using an old version of PromiseKit (6.10) which contains

public protocol Thenable: class {}

Updating to a newer version which is changed to Thenable: AnyObject resolved the issue.

Ewer answered 19/4, 2022 at 14:51 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.