LLVM
LLVM是项目模块化,可重用的编译器及工具链技术的集合
传统编译器的架构
Front: 前端
词法分析、语法分析、语义分析、将不同语言生成中间代码
Optimizer: 优化器
中间代码优化
Backend: 后端
针对不同架构生成机器码
LLVM架构
前后端不耦合,不同的前端后端,使用同一的中间代码 LLVM Intermediate Representation (LLVM IR)
- 如果需要支持一种新的编程语言,那么只需要实现一个新的前端
- 如果需要支持一种新的硬件设备,那么只需要实现一个新的后端
- 优化阶段是一个通用的阶段,它针对的是统一的LLVM IR,不论是支持新的编程语言,还是支持新的硬件设备,都不需要对优化阶段做修改
- 相比之下,GCC的前端后端耦合,所以GCC为了支持一门新的语言或者新的设备,就变得特别困难
- LLVM现在被作为实现各种静态和运行时编译语言的通用基础结构(GCC家族、JAVA、.NET、Python、Ruby、Scheme、Haskell等)
什么是Clang
- LLVM项目的一个子项目
- 基于LLVM架构的C/C++/Objective-C编译器前端
相比于GCC, Clang具有如下优点
- 编译速度快: 在某些平台上
- Clang采用基于库的模块化设计,易于IDE集成及其他用途的重用
- 诊断信息可读性强:在编译过程中,Clang创建并保留了大量详细的元数据,有利于调试和错误分析
- 设计清晰简单,易于扩展增强
OC源文件的编译过程
命令行查看编译过程
1 | clang -ccc-print-phases main.m |
查看预处理结果
1 | clang -e main.m |
词法分析,生成token
1 | clang -fmodules -E -Xclang -dump-tokens main.m |
语法分析,生成语法书(AST, Abstract Syntax Tree)
1 | clang -fmodules -fsyntax-only -Xclang -ast-dump main.m |
生成中间代码
1 | LLVM IR 有3种格式 |
源码下载
- 下载LLVM
1 | git clone https://git.llvm.org/git/llvm.git/ |
- 下载clang
1 | cd llvm/tools |
源码编译
- 安装cmake和ninja(先安装brew, https://brew.sh/)
1 | brew install cmake |
ninja如果安装失败,可以直接从github获取release版放入
/usr/local/bin
在LLVM源码统计目录下新建一个llvm_build目录,最终在llvm_build目录下生成
build.ninja
1 | cd llvm_build |
- 依次执行编译、安装指令
1 | ninja # 在llvm_build 目录 |
LLVM 应用
libclang、libTooling
应用: 语法树分析、语言转换
Clang插件开发
应用:代码检查(命名规范、代码规范)等
https://clang.llvm.org/docs/ClangPlugins.html
https://clang.llvm.org/docs/ExternalClangExamples.html
https://clang.llvm.org/docs/RAVFrontendAction.htmlPass开发
应用: 代码优化、代码混淆
开发新的编程语言
https://llvm-tutorial-cn.readthedocs.io/en/latest/index.html
https://kaleidoscope-llvm-tutorial-zh-cn.readthedocs.io/zh_CN/latest/
clang插件开发
加载插件
在Xcode项目中指定加载插件动态库:Build Setting > OTHER_CFLAGS
1 | -Xclang -load -Xclang 动态库路径 -Xclang -add - plugin -Xclang 插件名称 |
- Hack Xcode