基于clang插件的一种iOS包大小瘦身方案
引子
\包瘦身,包瘦身,包瘦身,重要的事情说三遍。 \
最近公司一款iOS APP(本文只讨论使用Objective C开发的iOS安装包)一直在瘦身,我们团队的APP也愈发庞大了。而要解决这个问题,思路主要集中在两个方向,资源和代码。资源主要在于图片,方法包括移除未被引用的图片,只使用一套图片(2x或3x),图片伸缩等;代码层面主要思路包括重构消除冗余,linkmap中selector引用分析等。除此之外,有没有别的路径呢? \
众所周知,代码之间存在调用关系。假设iOS APP的主入口为-[UIApplication main],则所有开发者的源代码(包括第三方库)可分为两类:存在一条调用路径,使得代码可以被主入口最终调用(称此类代码为被最终调用);不存在一条调用路径,使得代码最终不能被主入口调用(称此类代码为未被最终调用)。 \
假设有一个源代码级别的分析工具(或编译器),可以辅助分析代码间的调用关系,这样就使得分析最终被调用代码成为可能,剩下的就是未被最终调用的代码。 \
这种工具目前有成熟可用的吗?答案是肯定的,就是clang插件。除可用于分析未被最终调用代码外,clang还可辅助发现重复代码。 \
LLVM与clang插件
\LLVM工程包含了一组模块化,可复用的编辑器和工具链。同其名字原意(Low Level Virtual Machine)不同的是,LLVM不是一个首字母缩写,而是工程的名字。目前LLVM包含的主要子项目包括: \
作为LLVM提供的编译器前端,clang可将用户的源代码(C/C++/Objective-C)编译成语言/目标设备无关的IR(Intermediate Representation)实现。其可提供良好的插件支持,容许用户在编译时,运行额外的自定义动作。 \
我们的目标是使用clang插件减少包大小。其原理是,针对目标工程,基于clang的插件特性,开发者可以编写插件以分析所有源代码。编译过程中,将插件作为clang的参数载入并生成各种中间文件。编译完成后,还需编写一个工具去分析所有包含源码的方法(包括用户编写,以及引入的第三方库源代码),检查这些方法中哪些最终可被程序主入口调用,剩余即是疑似无用代码。简单的一个复查,移除那些确定无用的代码,重新编译,便可以有效去除无用的代码从而减少包大小。 \
本文相关内容如下: \
如何编写一个clang插件并集成到Xcode
\Clone clang源码并编译安装
cd /opt\sudo mkdir llvm\sudo chown `whoami` llvm\cd llvm\export LLVM_HOME=`pwd`\\git clone -b release_39 git@github.com:llvm-mirror/llvm.git llvm\git clone -b release_39 git@github.com:llvm-mirror/clang.git llvm/tools/clang\git clone -b release_39 git@github.com:llvm-mirror/clang-tools-extra.git llvm/tools/clang/tools/extra\git clone -b release_39 git@github.com:llvm-mirror/compiler-rt.git llvm/projects/compiler-rt\\mkdir llvm_build\cd llvm_build\cmake ../llvm -DCMAKE_BUILD_TYPE:STRING=Release\make -j`sysctl -n hw.logicalcpu`\编写clang插件
\要实现自定义的clang插件(以C++ API为例),应按照以下步骤: \
clang::PluginASTAction(基于consumer的抽象语法树(Abstract Syntax Tree/AST)前端Action抽象基类) \
clang::ASTConsumer(用于客户读取抽象语法树的抽象基类), \
clang::RecursiveASTVisitor(前序或后续地深度优先搜索整个抽象语法树,并访问每一个节点的基类)等基类。
\PluginASTAction::CreateASTConsumer \
PluginASTAction::ParseArgs \
ASTConsumer::HandleTranslationUnit \
RecursiveASTVisitor::VisitDecl \
RecursiveASTVisitor::VisitStmt \
等方法,实现自定义的分析逻辑。
\static FrontendPluginRegistry::Add\u0026lt;MyPlugin\u0026gt; X(\"my-plugin- name\
总结
以上是生活随笔为你收集整理的基于clang插件的一种iOS包大小瘦身方案的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: pxe+kickstart无人值守安装
- 下一篇: 原创经验:微信小程序开发总结