我们通过终端中输入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 //绑定
得到了7步操作的简要说明,分别是:
- 0:导入文件:是为了找到源文件。
- 1:预处理阶段:这个过程处理包括宏的替换,头文件的导入,会生成 main.i 文件,其中 objective-c-cpp-output 中的 cpp 不是指 C++ 语言,而是 c preprocessor 的缩写。
- 2:编译阶段:进行词法分析、语法分析、检测语法是否正确,最终生成IR。
- 3:后端:这里
LLVM会通过一个一个的Pass去优化,每个Pass做一些事情,最终生成汇编代码,生成一个 main.s 文件。 - 4:汇编:生成目标文件,即为 main.o。
- 5:链接:链接需要的动态库和静态库,生成可执行文件,最终生成 image。
- 6:绑定:通过不同的架构,生成对应的可执行文件,默认生成x86_64平台。
- 下面我们一步一步拆解:
1、预处理阶段
是通过预处理器执行一系列的文本转换与文本处理。预处理器是在真正的编译开始之前由编译器调用的独立程序。
在终端中输入:clang -E main.m 会生成预编译结果。
下面我们来把预编译结果生成到文件中,输入命令:clang -E main.m -o main.mi ,会把预编译结果生成一个main.mi文件,里面的内容如下:
# 1 "main.m"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 380 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.m" 2
/*
*在 main 函数中输入
int main(int argc, char * argv[]) {
int a = 1;
int b = 2;
re

本文详细介绍了C/C++编译过程中的预处理阶段,包括宏定义的处理、头文件导入的影响以及预编译指令的作用。通过实例展示了预处理器如何处理宏和头文件,强调了正确使用宏和避免无谓头文件导入的重要性。同时,提到了预编译过程中行标记的作用和静态内联函数作为宏替代的解决方案。
最低0.47元/天 解锁文章
2547

被折叠的 条评论
为什么被折叠?



