MacOS使用clang

clang是编译器前端,用来做预处理,词法分析,语法分析,它可以把结果转换为抽象语法树AST,然后交给LLVM编译器后端,最终生成可执行程序。

代码的编译过程可以分为预处理,词法分析,语法分析,语义分析,目标代码,链接,生成可执行程序,本文在MacOS平台结合clang命令完成一段C++代码的编译。

新建一个文件main.cpp,写入C++代码。

#include <iostream>

#define STR "Hello world"

int main(int argc, const char * argv[]) {
    
    
    std::string a = STR;
    std::cout << a << std::endl;
    return 0;
}

我们先使用clang命令查看这个段代码的编译过程,由于代码是C++,需要使用clang++

clang++ -ccc-print-phases main.cpp

终端输出了信息

               +- 0: input, "main.cpp", c++
            +- 1: preprocessor, {
    
    0}, 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

input指的是输入源码文件,preprocessor是预处理,compiler是编译器前端,compiler做词法分析,语法分析,语义分析。随后backend生成汇编,生成目标文件。linker是链接,生成image。最后bind-arch处理架构信息,生成架构相关的image文件。

1.查看preprocessor预处理过程

clang++ -E main.cpp -o main.i

生成的main.i文件很长,滑动到底部可以看到源码部分

int main(int argc, const char * argv[]) {
    
    
    std::string a = "Hello world";
    std::cout << a << std::endl;
    return 0;
}

可以看到预处理阶段,宏定义被展开,代码部分还未处理。

2.查看词法分析

clang++ -fmodules -E -Xclang -dump-tokens main.cpp

生成的词法分析结果很长,这里仅截取一小段

identifier 'std'	 [StartOfLine] [LeadingSpace]	Loc=<main.cpp:14:5>
coloncolon '::'		Loc=<main.cpp:14:8>
identifier 'cout'		Loc=<main.cpp:14:10>
lessless '<<'	 [LeadingSpace]	Loc=<main.cpp:14:15>
identifier 'a'	 [LeadingSpace]	Loc=<main.cpp:14:18>
lessless '<<'	 [LeadingSpace]	Loc=<main.cpp:14:20>
identifier 'std'	 [LeadingSpace]	Loc=<main.cpp:14:23>
coloncolon '::'		Loc=<main.cpp:14:26>
identifier 'endl'		Loc=<main.cpp:14:28>
semi ';'		Loc=<main.cpp:14:32>
return 'return'	 [StartOfLine] [LeadingSpace]	Loc=<main.cpp:15:5>
numeric_constant '0'	 [LeadingSpace]	Loc=<main.cpp:15:12>
semi ';'		Loc=<main.cpp:15:13>
r_brace '}'	 [StartOfLine]	Loc=<main.cpp:16:1>
eof ''		Loc=<main.cpp:16:2>

词法分析就是对源码进行解析,生成一个个token,从结果看std,::,cout,a等符号都被识别出来。左侧是token的类型,比如identifier标识符,semi分号,eof是文件末尾。右侧记录了每个符号在源码的中行号列号。

3.语法分析

clang++ -fmodules -fsyntax-only -Xclang -ast-dump main.cpp

4.语义分析

clang++ -S -emit-llvm main.cpp

当前目录会生成main.ll语法分析文件

5.汇编文件

clang++ -S main.cpp

当前目录会生成main.s的汇编文件

6.生成目标文件

clang++ -c main.s

当前目录会生成main.o目标文件,这个文件是二进制形式的。

7.生成可执行文件

 clang++  main.cpp -o main

当前目录生成main文件,在命令行中执行./main 即可运行程序,输出Hello world

猜你喜欢

转载自blog.csdn.net/u011608357/article/details/127707335