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

### 关于 macOSClang 编译器的使用和配置 #### Clang 编译器概述 Clang 是一种现代化的 C/C++/Objective-C 编译器前端,基于 LLVM 构建。在 macOS 中,默认情况下使用的编译器是 Apple 提供的 Clang 版本[^1]。 #### 配置 VSCode 使用 Clang 进行 C++ 开发 为了在 MacOS 上利用 Visual Studio Code (VSCode) 来开发 C++ 应用程序并设置好 clang 的编译环境,可以按照如下方式来定义 `c_cpp_properties.json` 文件中的配置项: ```json { "configurations": [ { "name": "Mac", "includePath": ["${workspaceFolder}/**"], "macFrameworkPath": ["/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"], "compilerPath": "/usr/bin/clang", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "macos-clang-arm64" } ], "version": 4 } ``` 此 JSON 对象指定了项目的工作区文件夹内的所有头文件都将被包含进来;设置了框架路径以便能够访问 Mac SDK 下的标准库;设定了用于 IntelliSense 功能的语言服务器模式为 macos-clang-arm64,并选择了 `/usr/bin/clang` 作为默认编译器位置[^2]。 对于更复杂的构建需求,则可以通过创建或编辑 `.vscode/tasks.json` 文件来自定义任务执行命令,比如指定特定版本的 clang 或者传递额外选项给编译过程。 #### 更改默认编译器至 GCC(如果安装了多个编译器) 尽管建议保持原生支持的 Clang 作为主要工具链,但如果确实有需要切换到其他版本的 GCC 编译器,在终端里可通过设定别名的方式实现快速替换: ```bash alias gcc='gcc-11' alias cc='gcc-11' alias g++='g++-11' alias c++='c++-11' ``` 这些命令会使得每次输入 `gcc`, `cc`, `g++`, 或者 `c++` 命令时实际上调用了名为 `gcc-11` 及其对应变体的具体可执行文件[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值