Problem description:
I have an Xcode workspace that references two Xcode projects. The first Xcode project (lib.xcodeproj) builds an iOS static library while the second project (app.xcodeproj) builds an iOS app that consumes the static library. app.xcodeproj references lib.xcodeproj, i.e. lib.xcodeproj is listed in app.xcodeprojs Link Binary With Libraries build phase.
So, the setup is as follows:
Code Block MyApp.xcworkspace | +-app.xcodeproj---+ | | Referenced via build phase +-lib.xcodeproj <-+
If I open this workspace in Xcode and build an archive out of it (Productmenu -> Archive) everything compiles as expected and I end up with an .xcarchive. The same applies if I build via command line (xcodebuild archive -workspace MyApp.xcworkspace ...).
However, dumping the content of the dSYM file that is generated as part of the archive reveals that it does not contain the debugging symbols of the static library (lib.xcodeproj). To be more specific, executing the command
Code Block dwarfdump MyApp.xcarchive\dSYMs\MyApp.app.dSYM\Contents\Resources\DWARF\MyApp > dwarfdump.txt
generates a text file that confirms that all debugging symbols of the app itself are there but the debugging symbols of the static library are not.This only happens when creating archives. Producing a build via Product menu -> Build produces a dSYM file containing all debugging symbols of the app AND the static library.
Now, this isn't exactly new. That behavior was already observed ages ago and I found three different SO posts describing the same behavior (here, here, and here). However, these posts are more than 7 years ago!
What I would like to know:
How do other people create archives of apps that are using static libraries created in the same workspace?
Seems that without scripting and just with Xcode itself this is an unsolvable problem.
Analysis:
I've analyzed this issue and strongly suspect it is a long lasting Xcode issue. Here's what I found:
Building the workspace via xcodebuild build -workspace MyApp.xcworkspace ... produces the following sequence of log entries:
Code Block CompileC <static library file 1> CompileC <static library file 2> ... Libtool <instructions to create the static library> ... CompileC <app file 1> CompileC <app file 2> ... GenerateDSYMFile <instructions to create the dSYM file> ... CodeSign <instructions to sign the app>
Building the workspace via xcodebuild archive -workspace MyApp.xcworkspace ... produces the following sequence of log entries:
Code Block CompileC <static library file 1> CompileC <static library file 2> ... Libtool <instructions to create the static library> Strip <instructions to strip the debugging symbols from the static library> ... CompileC <app file 1> CompileC <app file 2> ... GenerateDSYMFile <instructions to create the dSYM file> Strip <instructions to strip the debugging symbols from the app> ... CodeSign <instructions to sign the app>
From these two sequences we see that when an archive is created we get calls to the strip tool. This tool strips out the debugging symbols from a binary. So, when the dSYM file gets created the static library simply does not contain any debugging symbols anymore.
When GenerateDSYMFile is executed, all that is left are the debugging symbols within the app. These symbols are then also stripped. BUT they are stripped after the dSYM file already exists and not before as is the case with the static library.
Now, there are build settings designed to influence that behavior. I found the following and tested whether they have an effect:
Strip Debug Symbols During Copy (COPY_PHASE_STRIP): Made no difference, the sequence is unchanged
Strip Linked Product (STRIP_INSTALLED_PRODUCT): Made no difference, the sequence is unchanged
Strip Style (STRIP_STYLE): Changes the argument that is passed to the strip tool. But I cannot prevent the information from being stripped nonetheless.