iOS编译
- 编译器
- LLVM
编译器
一般编译器由三部分构成,从源码到机器码经过一下三部分:
- 编译器前端(FrontEnd):通过词法分析、语法分析、语义分析抽象为语法树AST,生成中间代码.IR 文件
- 优化器(Optimizer):优化.IR文件
- 编译器后端(BackEnd):将中间代码转换各平台的机器码,如x86,ARM。
LLVM
LLVM的一般是指LLVM的整个架构,但一般指LLVM的后端。
LLVM结构图.png如图所示,不同的前后端使用统一的IR文件,这样中间优化阶段都不需要修改,这样只要新增前后端就可以了。
Clang
Clang是LLVM项目的子项目,是C系列(C、C++、OC)的编译器前端。
主要流程
Clang执行的主要流程如图所示:
clang执行的主要流程.png
- 预处理(Preprocess):include扩展、标记化处理、去除注释、条件编译、宏替换、宏删除。对C输出.i,C++输出.ii,对 OC 输出 .mi,对Objective-C++ 输出 .mii;
- 词法分析(Lexical Analysis):将代码切成一个个token,比如大小括号、等于号、字符串等。是计算机科学中将字符序列转换为标记序列的过程;
- 语法分析(Semantic Analysis):验证语法是否正确,抽象成语法树AST。由 Clang 中 Parser 和 Sema 配合完成;
- 静态分析(Static Analysis):分析源代码以便自动发现错误;
- 中间代码代码生成(Code Generation):生成IR中间代码,CodeGen 会负责将语法树自顶向下遍历逐步翻译成 LLVM IR。
SwiftC
SwiftC是swift语言的编译器前端。
主要流程
SwiftC主要流程.png- Parse:词法分析组建,生成AST;
- Sema:对AST进行类型检查,转换成正确且完整的AST
- Clang Import,负责导入 Clang 模块,并将导出的 C 或 Objective-C API 映射到相应的 Swift API 中。最终导入的 AST 可以被语义分析引用;
- SILGen:将AST转换成RAW SIL;
- SIL保证转换:保证生成规范的SIL
- SIL优化:该阶段负责对程序执行额外的高级且专用于 Swift 的优化,包括(例如)自动引用计数优化、去虚拟化、以及通用的专业化
IR
LLVM IR 有三种表现形式:
- text:便于阅读的文本格式,类似于汇编语言,拓展名.ll
- bitcode:二进制格式,拓展名.bc
- memory:内存格式
LLVM后端主要流程
LLVM后端主要流程.png- 优化(Optimize):LLVM 会去做些优化工作;在 Xcode 的编译设置里也可以设置优化级别-01,-03,-0s;优化级参数位于参数位于Build Settings -> Apple Clang - Code Generation ->Optimization Level。是利用 LLVM 的 Pass 去处理的,我们可以自己去自定义 Pass;
- 生成目标文件(Assemble):生成 Target 相关 Object(Mach-o);
- 链接(Link):生成 Executable 可执行文件。
BitCode
BitCode 其实就是 IR 代码的一种编码形式。 BitCode 是以 section 形式保存在可执行文件中。当我们把携带 BitCode 的 App 提交到 AppStore 后,苹果会提取出可执行文件中的 BitCode 段,然后针对不同的 CPU 架构编译和链接成不同的可执行文件变体(Variant),不同 CPU 架构的设备会自动选择合适的架构的变体进行下载。而在 BitCode 之前,我们都是把所有需要的 CPU 架构集合打包成一个 Fat Binary,结果就是用户最终下载的安装包之中有很多冗余的 CPU 架构支持代码。开启BitCode之后,编译器后端(Backend)的工作都由 Apple 接管。
网友评论