Find Size Contributed by Each External Library on iOS

Find size contributed by each external library on iOS

All of this information is contained in the link map, if you have the patience for sifting through it (for large apps, it can be quite large). The link map has a listing of all the libraries, their object files, and all symbols that were packaged into your app, all in human-readable text. Normally, projects aren't configured to generate them by default, so you'll have to make a quick project file change.

From within Xcode:

  1. Under 'Build Settings' for your target, search for "map"
  2. In the results below, under the 'Linking' section, set 'Write Link Map File' to "Yes"
  3. Make sure to make note of the full path and file name listed under 'Path to Link Map File'

The next time you build your app you'll get a link map dumped to that file path. Note that the path is relative to your app's location in the DerivedData folder (usually ~/Library/Developer/Xcode/DerivedData/<your-app-name>-<random-string-of-letters-and-numbers>/Build/Intermediates/..., but YMMV). Since it's just a text file, you can read it with any text editor.

The contents of the link map are divided into 3 sections, of which 2 will be relevant to what you're looking for:

  1. Object Files: this section contains a listing of all of the object files included in your final app, including your own code and that of any third-party libraries you've included. Importantly, each object file also lists the library where it came from;
  2. Sections: this section, not relevant to your question, contains a list of the processor segments and their sections;
  3. Symbols: this section contains the raw data that you're interested in: a list of all symbols/methods with their absolute location (i.e. address in the processor's memory map), size, and most important of all, a cross-reference to their containing object module (under the 'File' column).

From this raw data, you have everything you need to do the required size calculation. From #1, you see that, for every library, there are N possible constituent object modules; from #2, you see that, for every object module, there are M possible symbols, each occupying size S. For any given library, then, your rough order of size will be something like O(N * M * S). That's only to give you an indication of the components that would go into your actual calculations, it's not any sort of a useful formula. To perform the calculation itself, I'm sorry to say that I'm not aware of any existing tools that will do the requisite processing for you, but given that the link map is just a text file, with a little script magic and ingenuity you can construct a script to do the heavy lifting.

For example, I have a little sample project that links to the following library: https://github.com/ColinEberhardt/LinqToObjectiveC (the sample project itself is from a nice tutorial on ReactiveCocoa, here: http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1), and I want to know how much space it occupies. I've generated a link map, TwitterInstant-LinkMap-normal-x86_64.txt (it runs in the simulator). In order to find all object modules included by the library, I do this:

$ grep -i "libLinqToObjectiveC.a" TwitterInstant-LinkMap-normal-x86_64.txt

which gives me this:

[  8] /Users/XXX/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(LinqToObjectiveC-dummy.o)
[ 9] /Users/XXX/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSArray+LinqExtensions.o)
[ 10] /Users/XXX/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSDictionary+LinqExtensions.o)

The first column contains the cross-references to the symbol table that I need, so I can search for those:

$ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[  8\]"

which gives me:

0x100087161 0x0000001B  [  8] literal string: PodsDummy_LinqToObjectiveC
0x1000920B8 0x00000008 [ 8] anon
0x100093658 0x00000048 [ 8] l_OBJC_METACLASS_RO_$_PodsDummy_LinqToObjectiveC
0x1000936A0 0x00000048 [ 8] l_OBJC_CLASS_RO_$_PodsDummy_LinqToObjectiveC
0x10009F0A8 0x00000028 [ 8] _OBJC_METACLASS_$_PodsDummy_LinqToObjectiveC
0x10009F0D0 0x00000028 [ 8] _OBJC_CLASS_$_PodsDummy_LinqToObjectiveC

The second column contains the size of the symbol in question (in hexadecimal), so if I add them all up, I get 0x103, or 259 bytes.

Even better, I can do a bit of stream hacking to whittle it down to the essential elements and do the addition for me:

$ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[  8\]" | grep -e "0x" | awk '{print $2}' | xargs printf "%d\n" | paste -sd+ - | bc

which gives me the number straight up:

259

Doing the same for "\[ 9\]" (13016 bytes) and "\[ 10\]" (5503 bytes), and adding them to the previous 259 bytes, gives me 18778 bytes.

You can certainly improve upon the stream hacking I've done here to make it a bit more robust (in this implementation, you have to make sure you get the exact number of spaces right and quote the brackets), but you at least get the idea.

static library has big size

Also make sure that you set Generate Debug Symbols to NO in your build settings. This can reduce the size of your static library by about 30%.

How to find out how many lines of code there are in an Xcode project?

Check out CLOC.

cloc counts blank lines, comment lines, and physical lines of source code in many programming languages.

(Legacy builds are archived on SourceForge.)

Iphone Release Compile: how to trim down external library size?

You can download the source for the library, remove the files you don't need and aren't needed for compilation, then compile yourself.

How do I see if the size of my iOS 14 app clip is below 10MB?

I disagree with the current previous accepted answer. It is certainly wrong since it includes the code for all architectures, maybe the bitcode and does not have the final compression from the app store. You should refer to Apple's guide on how to estimate the app size. Look here for "Create the App Size Report".

tl;dr Find the clip size like this:

  1. Archive your app in Xcode.
  2. Export your archived app as an Ad Hoc, Development, or Enterprise build.
  3. In the sheet for setting the development distribution options, choose “All compatible device variants” for app thinning, and enable Rebuild from Bitcode.
  4. Sign your app and export it to your Mac.

In the exported folder you will find a file called App Thinning Size Report.txt

It now has 2 entries. One for your main app and one for your app clip. Look for a line like:

App size: 6.7 MB compressed, 18.6 MB uncompressed

I assume the 10MB limit refers to the compressed size of the app since network traffic should be the limiting factor. Seems like my assumption was wrong, the 10MB limit refers to the uncompressed size according to an Apple Developer Technical Support Engineer. Refer to kanekins comment below for more details.



Related Topics



Leave a reply



Submit