前言
本系列文章会通过对 clang
源码进行拆解的方式,逐步对 clang
内部的各种逻辑进行介绍。
我们对 clang 的误解
我们经常会说给 clang
加个 ***
参数,但是这种说法非常模糊,经常会产生误导。
在不同的场景下,clang
可能具有不同的含义:
clang driver
:编译器驱动程序,负责根据简单的参数生成更加负杂的参数- 编译器前端(在 clang 库实现):专指编译器生成中间代码的过程(
preprocessor
和compiler
) - 实际的编译器(在
clang -cc1
中实现):clang -cc1
通过 LLVM 库和其它工具实现了编译前端、后端、汇编等工作
以下面的原始命令为例:
代码语言:javascript复制xcrun --sdk iphoneos clang -arch arm64 main.m -v
clang
先会以 clang driver
模式运行,随后组装 clang -cc1
和 ld
两个命令行,并进行下一步处理
image
注意:
clang driver
自身不负责对源码进行编译
为了方便对后面的源码进行分析,我们下面再介绍一些其它必要的基础知识
诊断
不同的前端阶段具有不同种类的诊断信息。
比如,
clang/include/clang/Basic/DiagnosticDriverKinds.td
维护了Driver
相关的诊断信息
image
并且,Clang
根据问题的严重性对诊断进行了分类
clang/lib/Basic/DiagnosticIDs.h
文件维护了五种类型:NOTE、REMARK、WARNING、EXTENSION、ERROR
image
llvm:Triple
llvm:Triple
是 llvm
整套工具一个非常基础的概念,并且非常容易理解。
以 aarch64-apple-ios11.1
为例,我们可以通过该字符串得到以下信息
- cpu 架构是
arm64
- cpu 子架构是
armv8
- 厂家是
Apple
- 编译任务产出的目标系统是
iOS
- 产出的对象文件格式是
MachO
(通过OS
推导得到)
image
不同参数对 triple
的影响
很多命令行参数都可能影响 Triple
的生成,比如 -arch arm64
、 -target -target arm64-apple-ios11.1
等 拼写 clang
命令时,需要注意不同参数的优先级,比如,-arch
对架构的优先级高于 -target
下面的示例显示最后产出的文件不包含 -target
的 x86_64
架构
image
image
ToolChain
ToolChain
可以理解为 编译工具链;GNU 的 MinGW
,微软的 MSVC
都属于工具链。
举个例子,当我们需要在 mac 系统上生成一个运行在 iPhone 上面的 APP 时,就会依赖 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
进行链接任务
image
本文总结
本文主要对以下知识进行了介绍:
- 不同场景下,clang 的含义
- 三个基础知识点:诊断、
llvm:Triple
、ToolChain