LLVM编译一个源文件的过程:
预处理 -> 词法分析 -> Token -> 语法分析 - > AST树 -> 代码生成 -> LLVM IR -> 优化 -> 生成汇编代码 -> Link -> 目标文件
基于LLVM, 我们可以做什么
a. 做语法树分析, 实现语言转换, 入如OC转Swift, JS 或 其他语言
b. 编写ClangPlugin, 用于代码的命名规范, 编写规范
c. 编写Pass, 代码混淆优化.
作者:Lin__Chuan
链接:https://www.jianshu.com/p/7e35380b0666
来源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
LLVM构成
首先解决了一个很大的问题:假如有N种语言(C、OC、C++、Swift...)的前端,同时也有M个架构(模拟器、arm64、x86...)的Target,是否就需要 N × M 个编译器?
三相架构的价值就体现出来了,通过共享优化器的中转,很好的解决了这个问题。
假如你需要增加一种语言,只需要增加一种前端;假如你需要增加一种处理器架构,也只需要增加一种后端,而其他的地方都不需要改动。这复用思想很牛逼吧。
2.2 LLVM编译器的组成
LLVM项目是模块化和可重用的编译器和工具链技术的集合。LLVM主要的子项目有一下几个:
1.LLVM核心库:
LLVM提供一个独立的链接代码优化器为许多流行CPU(以及一些不太常见的CPU)的代码生成支持。这些库是围绕一个指定良好的代码表示构建的,称为LLVM中间表示(“LLVM IR”)。LLVM还可以充当JIT编译器 - 它支持x86 / x86_64和PPC / PPC64程序集生成,并具有针对编译速度的快速代码优化。。
2.LLVM IR 生成器Clang:
Clang是一个“LLVM原生”C / C ++ / Objective-C编译器,旨在提供惊人的快速编译(例如,在调试配置中编译Objective-C代码时比GCC快3倍),非常有用的错误和警告消息以及提供构建优秀源代码工具的平台。
3.LLDB项目:
LLDB项目以LLVM和Clang提供的库为基础,提供了一个出色的本机调试器。它使用Clang AST和表达式解析器,LLVM JIT,LLVM反汇编程序等,以便提供“正常工作”的体验。在加载符号时,它也比GDB快速且内存效率更高。
4.libc ++和libc++:
libc ++和libc++ ABI项目提供了C ++标准库的标准符合性和高性能实现,包括对C ++ 11的完全支持。
5.lld项目:
lld项目旨在成为clang / llvm的内置链接器。目前,clang必须调用系统链接器来生成可执行文件。
其他的就不再详细介绍了,详情可以参考(LLVM和Clang)
总之,LLVM是Apple主导的开源框架,并提供一套使用于Apple平台的LLVM编译器,同时提供优秀的性能,所以Apple采用LLVM的方式进行编译
应用场景
Clang是LLVM的一个前端,在Xcode编译iOS项目的时候,都是使用的LLVM,其实在编写代码以及调试的时候都在接触LLVM提供的功能,例如:代码的亮度(Clang)、实时代码检查(Clang)、代码提示(Clang)、debug断点调试(LLDB)。
iOS 项目的编译过程
- 写入辅助文件:
将项目的文件结构对应表、将要执行的脚本、项目依赖库的文件结构对应表写成文件,方便后面使用;并且创建一个.app包,后面编译后的文件都会被放入包中; - 运行预设脚本:
Cocoapods会预设一些脚本,当然你也可以自己预设一些脚本来运行。这些脚本都在BuildPhases中可以看到; - 编译文件:
针对每一个文件进行编译,生成可执行文件Mach-O,这过程LLVM的完整流程,前端、优化器、后端; - 链接文件:
将项目中的多个可执行文件合并成一个文件; - 拷贝资源文件:
将项目中的资源文件拷贝到目标包; - 编译storyboard文件:
storyboard文件也是会被编译的; - 链接storyboard文件:
将编译后的storyboard文件链接成一个文件; - 编译Asset文件:
我们的图片如果使用Assets.xcassets来管理图片,那么这些图片将会被编译成机器码,除了icon和launchImage; - 运行Cocoapods脚本:
将在编译项目之前已经编译好的依赖库和相关资源拷贝到包中。 - 生成.app包
- 将Swift标准库拷贝到包中
- 对包进行签名
- 完成打包
Swift的编译过程
在Swift 编译器结构的官方文档中描述了 Swift 编译器是如何工作的,分为如下步骤:
解析:解析器是一个简单的递归下降解析器(在lib / Parse中实现),带有集成的手动编码词法分析器。解析器负责生成没有任何语义或类型信息的抽象语法树(AST),并针对输入源的语法问题发出警告或错误。
语意分析:语义分析(在lib / Sema中实现)负责解析 AST 并将其转换为格式良好的完全检查形式的 AST,并在源代码中发出语义问题的警告或错误。语义分析包括类型推断,如果成功,则所得到的代码是类型检查安全的 AST 。
Clang导入器:Clang导入器(在lib / ClangImporter中实现)导入Clang模块,并将它们导出的 C 或 Objective-C API 映射到相应的 Swift API中。结果导入的 AST 可以通过语义分析来引用。
SIL生成:Swift中间语言(Swift Intermediate Language,简称SIL)是一种高级的,Swift特有的中间语言,适用于 Swift 代码的进一步分析和优化。SIL 生成阶段(在lib / SILGen中实现)将类型检查的 AST 降低到所谓的 “原始” SIL。SIL的设计描述在docs/ SIL.rst中可以看到。
SIL优化:在SIL优化(在lib/Analysis,lib/ ARC,lib/LoopTransforms,和lib/Transforms中实现)执行额外的高级别,Swift 特有的优化的程序,包括(例如)自动引用计数优化,虚拟化和通用专业化。
LLVM IR生成:IR生成(在lib/IRGen中实现)将 SIL 降到 LLVM IR,此时LLVM可以继续对其进行优化并生成机器码。
作者:素还真人
链接:https://www.jianshu.com/p/222c8d4a8335
来源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Objective-C源文件编译过程
查看编译过程命令
clang -ccc-print-phases main.m
0: input, "main.m", objective-c
1: preprocessor, {0}, objective-c-cpp-output
2: compiler, {1}, ir
3: backend, {2}, assembler
4: assembler, {3}, object
5: linker, {4}, image
6: bind-arch, "x86_64", {5}, image
编译过程先后是读取源文件、预处理、编译生成中间表示、生成汇编码、链接生成image、绑定架构生成对应机器码