基于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无人值守安装
- 下一篇: 原创经验:微信小程序开发总结