减小静态库体积

2018-12-04  本文已影响38人  偶是星爷

我们的iOS SDK采用静态库形式分发,不知不觉SDK已经增大到几百M,而实际安装包增量不过几M,有必要反思一下为何SDK体积如此之大。

什么是静态库

静态库简单的理解是多个目标文件(.o)的打包集合。静态库在unix系统上后缀一般是.a,苹果上既可以用.a,也可以封装成Framework形式。

静态库的好处是提供的是目标文件,所以不需要重新编译,只需要链接即可,相比动态库,加载速度更快。在链接的时候,链接器会保留用到的代码,没有用到的代码最终会被删掉(Dead code),这就是为什么静态库很大,编出来的app却很小。从这点看,静态库在体积上相比动态库会有一点优势。

如何减小静态库体积

1. 关闭Debug Symbols

在"Build Settings",将"Generate Debug Symbols"设置NO。这是最快、最直接的方法,立马可以节省20%的体积。

注意:设置为NO只能去除当前工程的符号,引用的第三方还是没处理。建议将对第三方的静态库做一下strip。

2. 不重复link静态库

我们的SDK分为多个子模块,子模块相互独立,但可能使用相同第三方库。

SDK.framework  ++----->  Module A (A.a) +----->  Third.a
                |
                +----->  Module B (B.a) +----->  Third.a

静态库的生成实质就是一个打包过程,并且打包相同文件不做去重。所以SDK中包含了两份Third.a目标文件。包依赖改为下面形式就能减少重复依赖。

SDK.framework  ++----->  Module A (A.a)
                |
                +----->  Module B (B.a)
                |
                +----->  Third.a

我们SDK有一些很大的第三方静态库,通过这一步减少了上百M。

3. 去除无用目标文件

SDK很多第三方库,包括自身代码,很多文件至始至终都没有被使用,这部分文件其实可以不编译。
如何找到那些目标文件被使用?这时需要求助link map文件。在测试demo中打开link map生成,打开文件后可以看到如下:

# Arch: arm64
# Object files:
[  0] linker synthesized
[  1] /Users/annidy/Library/Developer/Xcode/DerivedData/TXLiteAVDemo-ctawhuyhhsutohfizsupuzlyqmki/Build/Intermediates.noindex/TXLiteAVDemo.build/Release-iphoneos/TXLiteAVDemo_Player.build/Objects-normal/arm64/TXCAudioCustomRecorder.o
[  2] /Users/annidy/Library/Developer/Xcode/DerivedData/TXLiteAVDemo-ctawhuyhhsutohfizsupuzlyqmki/Build/Intermediates.noindex/TXLiteAVDemo.build/Release-iphoneos/TXLiteAVDemo_Player.build/Objects-normal/arm64/AFAutoPurgingImageCache.o

...

[212] /Users/annidy/Library/Developer/Xcode/DerivedData/TXLiteAVDemo-ctawhuyhhsutohfizsupuzlyqmki/Build/Products/Release-iphoneos/TXLiteAVDemo_Player.framework/TXLiteAVDemo_Player(TXCAVRoomConfig.o)
[213] /Users/annidy/Library/Developer/Xcode/DerivedData/TXLiteAVDemo-ctawhuyhhsutohfizsupuzlyqmki/Build/Products/Release-iphoneos/TXLiteAVDemo_Player.framework/TXLiteAVDemo_Player(TXUGCSign.o)

SDK和Demo用的的文件都列了出来,没在里面的文件就是不需要的目标文件。

link map文件比较大,可以通过下面脚本提取出文件名

#!/bin/sh
grep -oE '[^\/\(]+(\.o)' $1 | grep -v ' '

接下来可以在工程里进行搜索,去掉不需要的文件。

4. 关闭bitcode

bitcode在编译的时候embed到目标文件中,通常比代码段还大。如果不需要支持bitcode,去掉还是能省至少50%的大小。
xcode提供了一个bitcode_strip工具,可以很方便的来去除。

通过以上步骤,将静态库减小到原先的1/5,可谓巨大进步。

上一篇 下一篇

猜你喜欢

热点阅读