I have an app that links to two dynamic frameworks which both link to the same static library, as follows:
|--App
|--DynamicFramework1
|--StaticLibrary
|--DynamicFramework2
|--StaticLibrary <- the same library that DynamicFramework1 links to
The static library's symbols are included in each framework's binary because of the way dynamic frameworks are built by default. The app therefore finds duplicates of the static library's symbols at runtime.
Is it possible to link a dynamic framework to a static library (and to still be able to call on the classes and methods of the static library within the dynamic framework) in a manner that symbols from the static library are excluded from the dynamic framework's binary?
My hope in doing this is that the binary of each of the two dynamic frameworks will exclude the symbols of the static library. I will then make it the responsibility of the app to link to the static library directly.
Notes
- I have tried linking my dynamic framework with the static library in two different ways thus far: (1) I added the static library to my framework's "Link Binary with Libraries" Build Phase; and (2) I referenced the static library in my framework's "Other Linker Flags" Build Setting. Both result in the static library's symbols being included in the framework's binary.
- I am aware that changing a framework target's "Mach-O Type" from "Dynamic Framework" to "Static Library" will build the framework's binary without the symbols of the static libraries that it links to. I want to keep my frameworks as dynamic frameworks so that (1) I can benefit from how Xcode bundles together resources (strings, storyboards etc) automatically for dynamic frameworks; and (2) users of my framework can benefit from Mergeable Libraries in the near future.
- I am aware that I can solve this problem by changing the static library to a dynamic framework. I want to avoid this as much as possible since the static library is from a third-party. I want to avoid forking the static library's source code and messing with its build scripts if I can.
I am grateful to MobileTen and eskimo for their suggestions and advice in this thread 🙏
MobileTen's three suggestions didn't quite fit my setup but the first one gave me confidence in the solution that I had been converging towards.
The best solution that I have been able to come up with is as follows:
- Create a new dynamic framework
DF
. - Link
DF
toStaticLibrary
with the-all_load
linker flag. - Link
App
,DynamicFramework1
andDynamicFramework2
toDF
instead ofStaticLibrary
.
The linking structure, in pictorial form, of this solution is as follows:
App
|--> DF1 --> DF --> SL
|--> DF2 --> DF --> SL
|--> DF --> SL
For a minimal but concrete Xcode project that demonstrates this setup, see here.
If somebody can suggest a better solution which does not involve housing the static library's symbols within a dynamic framework, I am open to it.