optional (weak-link) framework in UB app with only intel arch present?

I'm working getting a large app to Universal Binary, which uses a number of libraries and frameworks with third-party dependencies, a few of which are not yet available as arm64.

If a framework is marked as Optional in the app's build settings, the app will still link when it is absent.

I expected that if the framework only had one architecture needed for UB (e.g. just x86_64), we should be able to optionally link it successfully, and it would not matter if one architecture was missing.

However this isn't how Xcode handles it, we get a linker error for the missing architecture even if the framework is optional.

Is there a way to do what I'm expecting? Include an optional framework with only one architecture in a UB app, with the app taking responsibility for correct handling of the framework at runtime (just as it would for a missing optional framework in a single-architecture app)?

Answered by DTS Engineer in 682135022

You can change the value of the VALIDATE_WORKSPACE build setting to No on the app target. The client code that calls into the framework needs to be appropriately guarded with macros so that there are no symbols to link for Apple silicon pointing at the framework that's not yet available as a Universal Binary.

After experimenting a bit I'm concluding that this just isn't really a use case supported by the weak-linking mechanism. It looks to me like any time you're embedding a framework in your bundle, the Xcode build sequence is going to try and link its symbols, and if it's a universal app this will mean for both architectures. There's no workaround here even if you're doing things like setting different search paths and bundle locations for x86 vs. arm64. I think to make this work we would need a 'stub library' implementation of the framework for arm64 to get us past the link errors, but I'm still not confident the right thing would happen at runtime (which is, x86 would link with the x86 framework, arm64 would behave as if the optional framework is missing).

If anyone from Apple or with expertise can confirm this conclusion, that would be appreciated! And this question then becomes, more generally, what's the approach to have a universal app make use of a library/framework only available for one architecture - is XPC the only way?

Accepted Answer

You can change the value of the VALIDATE_WORKSPACE build setting to No on the app target. The client code that calls into the framework needs to be appropriately guarded with macros so that there are no symbols to link for Apple silicon pointing at the framework that's not yet available as a Universal Binary.

Thanks @edford for the answer - I was able to get it working as expected with my existing project by just adding the guards you mention to my source, so the symbols were not referenced for the not-yet-supported arm64 architecture - I used #if defined(__x86_64__)

optional (weak-link) framework in UB app with only intel arch present?
 
 
Q