iOS版编译器
㈠ 百度APP iOS端包体积50M优化实践(七)编译器优化
网络APP iOS端包体积优化系列文章深入探讨了包体积优化的整体方案、图片优化、资源优化、代码优化、无用类优化、HEIC图片优化实践以及无用方法清理。本篇将着重于编译器优化在网络APP实践中的应用。
编译器优化
编译器优化包括GCC语言编译优化、Swift编译优化、LTO优化、剥离调试符号、剥离符号表、剔除未引用的代码、Asset优化、C++虚函数优化和三方SDK编译器方向瘦身。
2.1 方案综述
2.2 GCC语言编译优化
2.2.1 综述
通过GCC编译优化,可以生成体积更小的二进制产物,对Objective C、C、C++均有效。
2.2.2 Objective C++编译优化
在XCode中编辑和编译Objective C++代码时,优化配置路径为:Build Settings -> Apple Clang -> Code Generation。可选参数包括:
默认优化等级为-Os,但我们使用-Oz优化方式。WWDC 2019《What's New in Clang and LLVM》详细解释了这种优化原理,它通过识别跨函数的相同代码序列减少代码大小。重复的连续机器指令被外联为函数,原始代码序列被替换为外联函数,虽然增加函数调用栈深度,但在当前高配置的iPhone设备上,这种性能损失是可以接受的。
实践表明,编译优化参数 -Oz对Objective C++代码有10%体积收益,对C和C++代码有30%收益。
2.2.3 C/C++编译优化
对于底层模块(如网络库、播放内核、视觉处理和端智能),常使用C和C++实现。这些模块支持跨平台,采用Cmake和GN编译。对于C++语言,cppFlags选项设置为'-Oz';对于C语言,cFlags选项设置为"-Oz"。
2.3 Swift编译优化
Swift优化包括Optimization Level和Compilation Mode,配置路径为:Build Settings -> Swift Compiler -> Code Generation。
Optimization Level可选参数值有:Optimize for Size,其核心原理与GCC语言编译优化类似,通过外联和复用重复的连续机器指令降低大小。Compliation Mode可选参数值有:Optimize for Size[-Osize]和Whole Mole,同时开启可减少10%的Swift包体积大小。
2.4 LTO优化
LTO是苹果官方提出的一种优化策略,通过在链接阶段进行跨模块优化,减少代码大小和提高执行效率。配置路径为:Build Settings -> Apple Clang -> Code Generation -> Link-Time Optimization,设置为Incremental。
LTO优化体现在:函数内联化、去除无用代码、全局优化。但负面影响包括:降低Link Map的可读性、增加编译和链接时间。
2.5 剥离调试符号
默认设置Symbols Hidden by Default为YES,可减少包大小。动态库设置为NO,否则会引发链接错误。
2.6 剥离符号表
配置路径为:Build Settings -> Strip Linked Proct。选择属性值为YES。
Strip Linked Proct用于去除不必要的符号信息,去除后只能使用dSYM文件进行符号化,因此需将"Debug Information Format"修改为"DWARF with dSYM file"。
2.7 剔除未引用的代码
配置路径为:Build Settings -> Dead Code Stripping。选择属性值为YES。
该优化主要在链接时剔除C、C++、Swift等静态语言的无用代码,但在处理Objective-C时无效,因其基于Runtime机制编译。
2.8 Asset优化
配置路径为:Build Settings -> Asset Catalog Compiler -> Optimization。选择Space以优化包大小,收益较小。
2.9 C++减少虚函数的使用
减少虚函数使用可减少虚函数表占用空间,最终减小程序包大小。
2.10 三方SDK编译器瘦身
需对每个框架进行优化配置和微调,确保库和依赖项也正确配置,以确保与编译器优化兼容。
网络APP内部集成了众多第三方SDK,需优化SDK以实现应用瘦身。
指令集架构优化
支持arm64和x86_64架构,通过优化指令集架构减小上传到AppStore的包体积。
3.2 指令集架构设置
使用lipo命令从旧的framework中拆分指定架构的二进制文件,合并后替换老的framework的mach-o文件。
3.3 去除无用架构
通过验证AbcArm64和AbcArmX86_64架构信息。
XCode升级优化
苹果Xcode版本持续优化,如Xcode 14,提供更强大的并行编译能力,显着提高构建速度,优化包体积。
Swift内置动态库优化
自2014年发布以来,Swift语言发展迅速,成为iOS开发的首选语言。优化Swift内置动态库,只需将APP支持的最低版本修改为12.2。
优化后,网络APP包体积减少30M+,提交AppStore后,有显着收益。
编译器优化在网络APP包体积优化中的ROI最高,但影响范围广泛。通过实践,成功减少了30M的包体积,实现了自身库的全部收益,同时优化了前15个三方SDK。
总结了网络APP的编译器优化方案,包括多种优化手段,后续将继续深入探讨其他优化方法。
㈡ iOS: FFmpeg编译和使用问题总结
经过一周多的努力,我终于解决了FFmpeg库的编译问题,并将整个过程中遇到的坑全部整理出来。如需快速解决问题,直接参考第二部分关于最新版本FFmpeg库的编译指南;若需编译较老版本的FFmpeg库(如0.7.x),请跳至第七部分查看相应编译脚本,并记得阅读全文以获取更多知识。
背景
网上关于FFmpeg编译配置的资料大多针对的是较新版本(如2.0),当我试图使用最新版本时,遇到了无法快进、无声音等问题,且代码中出现大量警告,原因在于版本过新导致接口变动。最终,我了解到项目使用的是0.7.x版本的FFmpeg库,但这只是问题的开始,经过一系列困难,我终于解决了编译问题。
最新版本的FFmpeg库编译
最新版本的FFmpeg库为2.1,历史版本详情请参阅http://www.ffmpeg.org/releases/。FFmpeg是一个跨平台、用C语言编写的库,包含编码、解码、色彩空间转换等功能。编译需要命令行支持,对于后台或Linux开发知识缺乏的人来说,这是一大挑战。幸运的是,网络资源丰富,遇到问题可直接在Google搜索解决。网上广泛推荐一个适用于Xcode5的自动化编译FFmpeg库的脚本,脚本地址为:gist.github.com/m1entus...,且需要依赖Perl编写的脚本:github.com/mansr/gas-pr...。完成脚本下载并设置权限后,通过命令行执行脚本即可完成FFmpeg库的编译工作。
编译较早期版本的FFmpeg本库
尝试将脚本中的版本号改为0.7,运行脚本后,发现编译时出现错误提示。通过./configure命令查看所有可用选项,发现缺少--disable-iconv选项。通过查阅配置文件,了解到0.7版本的FFmpeg库确实没有该选项。为了解决问题,我精简并修改了脚本,去除了下载部分的代码,以适应0.7版本的库编译需求。
如何使用以及编译链接中可能遇到的问题
使用经过修改的脚本build-ffmpeg0.7.sh可一键完成FFmpeg 0.7版本库的编译工作。编译完成后,获取静态库和头文件,只需将这些文件添加至项目中即可使用。在实际使用过程中,可能会遇到各种问题,如时间头文件冲突、编译器错误等,我会在遇到问题时进行详细解答,提供解决办法。
总结
通过解决FFmpeg库编译问题,我学习到了FFmpeg配置的基本知识,对库的裁剪、指定编译环境、静态库安装路径等有了深入了解。虽然过程充满挑战,但最终收获颇丰,我理解了编译过程背后的原理,对FFmpeg库有了更深入的认识。建议在使用技术时,不仅要会用,还要了解其工作原理,这样在遇到问题时能更好地解决问题。