Reputation: 8043
I have a project with includes custom frameworks, but these custom frameworks also include custom frameworks.
Here's a sample structure, where the bullets are the included frameworks:
App
FrameworkA
FrameworkB
FrameworkC
FrameworkA
FrameworkB
Since FrameworkA and FrameworkB link FrameworkC, along with my App using Frameworks A, B, and C; are they all linked together or is the framework copied in multiple places?
Does this increase the size of the app?
In this example FrameworkC has assets, if it's copied multiple times wouldn't that unnecessarily duplicate data? Or this there a better way?
Upvotes: 1
Views: 183
Reputation: 3484
iOS frameworks are a collection of header files and a fat static archive library. iOS does not support frameworks containing shared libraries.
A fat static archive library is a collection of multi-architecture object files, the object files can be extracted as needed by the linker to create an executable artifact. iOS executables are self contained executables (except for system libraries which are shared objects).
Fat archives can be examined with lipo.
cd FrameworkA.framework
lipo -info FrameworkA
Architectures in the fat file: FrameworkA are: armv7 armv7s i386 arm64
When you create a Framework, the linker tool is not used because the frameworks (in your case FrameworkA and FrameworkB) are not executable artifacts. The dependent framework is included in the framework project because the compiler requires the header files to create the Framework A and B object files. Any references to symbols in frameworkC remain unresolved.
If you inspect the contents of FrameworkA or FrameworkB using the "lipo" and "ar" tools and extract an object file, then dump the object file symbols using "nm", you will notice any references to symbols in FrameworkC remain unresolved.
Note: You need to install the Xcode commandline tools to do this.
cd FrameworkA.framework
lipo FrameworkA -thin armv7 -output FrameworkA_armv7.a
ar -t FrameworkA_armv7.a
objectA1.o
objectA2.o
objectA3.o
ar -x FrameworkA_armv7.a objectA1.o
xcrun --sdk iphoneos nm -p objectA1.o
...
00000188 T FrameworkAFunction
U FrameworkCFunction
...
This is why when you create an App, you need all three Frameworks (A,B and C) included in the project. When the linker reads an unresolved symbol in one of the App object files it will search framework A and B. When the symbol is resolved, it reads in the whole object file from the archive that contains that symbol. The linker must then resolve any unresolved dependent symbols in that object. If one of those unresolved symbols is in FrameworkC, it will pull in the object containing the dependent symbol from FrameworkC
So to answer your questions:
Frameworks A,B and C are linked when the App is linked, only the objects required to resolve all symbols are copied from the Frameworks into the app executable.
Yes, copying in objects increases the size of executables, but there are no multiple copies of any of the objects.
The assets in FrameworkC are only copied once, when the final App bundle is assembled by xcode.
Upvotes: 1