1. C++ 编译器介绍
MSVC,GCC和Clang是业界三种最主流的C/C++编译器,下面粗劣比较一下他们的差异:
C++编译器 | 编译器全称 | 支持的平台 | 备注 |
---|---|---|---|
MSVC | Microsoft Visual C++ | Windows | 由微软开发,主要用于Windows平台应用程序的开发。Visual Studio系列IDE默认集成了该编译器 |
GCC | GNU Compiler Collection | Windows, Linux, macOS | 开源编译器,支持多种平台,Linux下C++开发一般默认会使用此编译器 |
Clang | Clang / Low Level Virtual Machine | Windows, Linux, macOS | LLVM项目的一部分,提供高效的编译性能。macOS的XCode工具默认集成了此编译器 |
1.1. MSVC
- MSVC(Microsoft Visual C++)由微软开发,主要用于Windows平台应用程序的开发。
- Visual Studio系列IDE默认集成了该编译器,可以通过下载安装Visual Studio安装包来安装。
- MSVC只能在Windows下用,不支持跨平台。
1.1.1. Visual C++
与Visual Studio
的版本对应关系
_MSC_VER
: 是MSVC编译器内置的宏定义,可以在源代码中直接引用。其值代表了MSVC编译器的版本,如:1900表示Visual Studio 2015(MSVC++ 14.0)。
1 | MSC 1.0 _MSC_VER == 100 |
1.1.2. 工具链的主要工具
工具 | 功能描述 |
---|---|
cl.exe | 编译程序 |
link.exe | 链接程序 |
lib.exe | 加载lib库的程序 |
nmake.exe | 用makefile进行构建、编译的工具 |
备注: 用户只需要调用cl.exe,即可完成编译-链接全过程。因为cl.exe程序在编译时自己会去调用link.exe、lib.exe等程序。
1.2. GCC
GCC
最开始的原名是GNU C Compiler
,是GNU项目的C语言编译器。后来逐步拓展支持了更多的语言,支持编译C、C++、Fortran、Pascal、Objective-C、Java、Ada、Go等,所以变成了GNU Compiler Collection
(GNU编译器套装),是一套由GNU项目开发的支持多种编程语言的编译器工具链。
GCC支持多种平台和操作系统,包括Linux、Windows、macOS等,并且是许多开源项目和操作系统的标准编译器,如Linux内核。GCC还支持多种CPU指令集架构,如:X86、ARM等。
1.2.1. GCC的主要优点
- 支持多语言: 支持多种编程语言,如C、C++、Fortran、Pascal、Objective-C、Java、Ada、Go等。
- 跨平台性: GCC编译器能够在不同的操作系统和硬件平台上编译和运行代码,确保了代码的高度可移植性。
- 性能优化: GCC编译器内置了多种优化策略,可以根据不同的编译选项进行代码优化,从而提升程序的运行效率。
- 功能丰富: 编译时可生成调试信息,便于开发者进行调试。并提供了广泛的编译选项和扩展功能,以满足不同开发者的需求。
1.2.2. GCC的常用工具
工具 | 描述 |
---|---|
gcc | GCC的主要编译器,用于将源代码编译为可执行文件或库。支持多种语言(如C、C++、Fortran等),并提供丰富的编译选项。 |
g++ | GCC的C++编译器,用于将C++源代码编译为可执行文件或库。与gcc共享许多相同的编译选项,同时支持针对C++的特定选项。 |
gdb | GCC附带的调试器,用于调试程序。允许在程序运行时设置断点、单步执行代码、查看变量值等。支持多种编程语言,提供强大的调试功能。 |
objdump | 用于反汇编目标文件或可执行文件,显示二进制文件的汇编代码。还可显示符号表信息、重定位表等相关信息。 |
nm | 用于列出目标文件或可执行文件中的符号表。显示函数、变量以及其他符号的名称和地址。 |
ar | 用于创建、修改和提取静态库文件。允许将多个目标文件打包成一个库文件,以便在编译时链接使用。 |
size | 用于查看目标文件或可执行文件的大小信息。显示代码段、数据段和符号表等各部分的大小统计。 |
readelf | 用于显示ELF(Executable and Linkable Format)格式的二进制文件的详细信息。显示段表、符号表、动态链接信息等。 |
1.2.3. MinGW
MinGW(Minimalist GNU for Windows)是一个用于Windows平台的开发环境,它提供了GNU编译器集合(GCC)的Windows版本。MinGW允许开发者在Windows上使用GCC编译器来编译C、C++和其他支持的语言。MinGw只支持32位Widnows系统,MinGW-w64 支持32位和64位。所以现在说MinGW时,一般默认指的MinGW-w64,见 MinGW官网。
主要特点:
- GCC编译器: MinGW包含了GCC编译器,支持C、C++、Fortran等语言。
- 跨平台开发: 开发者可以使用MinGW编译的程序在Windows上运行,同时保持与Linux和其他Unix-like系统的兼容性。
- 开源: MinGW是开源的,遵循GNU通用公共许可证(GPL)。
- 轻量级: MinGW提供了一个轻量级的开发环境,不需要复杂的安装和配置。
1.3. Clang/LLVM
1.3.1. Clang介绍
Clang
是一个由 LLVM 项目开发的 C、C++、Objective-C 等编程语言的编译器前端。它旨在提供更快的编译速度、更好的错误报告及与GCC兼容的编译器驱动程序。Clang 是 LLVM 编译器基础设施的一部分,通常与 LLVM 后端一起使用来生成机器代码。
Clang的主要特点包括:
- 快速编译和低内存使用: Clang 的设计目标之一是提供比 GCC 更快的编译速度和更低的内存占用。
- 高质量的错误和警告信息: Clang 提供了详细和易于理解的错误和警告信息,有助于开发者更快地找到和修复问题。
- 与 GCC 兼容: Clang 支持大多数 GCC 的编译器选项和工具链,使得从 GCC 迁移到 Clang 相对容易。
- 模块化设计: Clang 的架构是模块化的,易于扩展和集成到其他工具和流程中。
- 支持现代语言特性: Clang 支持最新的 C++ 标准和其他语言特性,使得开发者可以使用最新的编程技术。
Clang 不仅是一个编译器前端,还是一个强大的工具集,包括静态分析工具(clang-tidy)、代码格式化工具(clang-format)、重构工具等,这些工具可以帮助开发者提高代码质量和开发效率。
1.3.2. Clang与LLVM的关系
编译器的组成:
一个完整的编译器通常由三部分组成。
前端(FrontEnd): 主要负责词法和语法分析,将源代码转化为抽象语法树;
优化器(Optimizer): 则是在前端的基础上,对得到的中间代码进行优化,使代码更加高效;
后端(BackEnd): 后端则是将已经优化的中间代码转化为针对各自平台的机器代码。
Clang与LLVM的关系:
更粗粒度的划分是把优化器
和后端
统称为后端
,整个编译器就由前端和后端两部分组成。Clang就是编译器的前端,负责词法和语法分析;LLVM就是编译器的后端,负责优化和生成机器代码。
Clang/llvm的编译过程如下图:
LLVM 包括了两个概念:
- 广义的 LLVM: 指的是一个完整的 LLVM 编译器框架系统,包括了前端、优化器、后端、众多的库函数以及很多的模块。
- 狭义的 LLVM: 则是聚焦于编译器后端功能的一系列模块和库,包括代码优化、代码生成、JIT 等。
1.3.3. Clang/LLVM与GCC
GCC和LLVM是竞争对手,都是编译器框架系统。GCC包含前端和后端,LLVM也包含前端和后端,只是他的前端通常是Clang,所以Clang是LLVM 编译器框架系统 的前端。
他们可能的组合如下:
眼尖的同学可能会问:为什么没有“Clang前端、GCC后端”的组合?
个人理解: GCC发展的时间非常早,带有很大的历史包袱。GCC后端的接口设计没有那么灵活,不能提供Clang足够的接口支撑(这也是LLVM架构最开始设计就考虑到的问题)。
LLVM Compiler
发展过程的早期就经历了LLVM-GCC
这种过渡期的组合(GCC前端+LLVM后端)。
2. C++ 编译器的安装
2.1. Windows
2.1.1. MSVC安装
- 进入微软官网下载页面:https://visualstudio.microsoft.com/zh-hans/downloads/
- 选择要下载的最新版本安装包下载器:
- 如果要下载完整的Visual Studio IDE,选择:Visual Studio 2022 -> 版本类型(如果是个人开发使用,可以选择
Visual Studio Community 2022
) - 如果只需要下载MSVC编译器,选择: 用于Visual Studio的工具 -> Visual Studio 2022 生成工具。
- 我希望用VSCode(而不是Visual Studio)来开发C++, 所有我只需要下载MSVC编译器。
- 如果要下载完整的Visual Studio IDE,选择:Visual Studio 2022 -> 版本类型(如果是个人开发使用,可以选择
- 双击打开下载好的
vs_BuildTools.exe
,一路点击“继续”,到安装包选择页面时,选择“C++桌面开发”。
2.1.2. 环境变量配置
方法一 指定的命令行:
MSVC安装后会生成特定命令行工具,可以在“开始 -> 搜索”查找一下命令行:
Developer Command Prompt for VS 2022
: 用 32位x86编译器 构建 32位x86 的目标程序。x86 Native Tools Command Prompt for VS 2022
: 用 32位x86编译器 构建 32位x86 的目标程序。x64 Native Tools Command Prompt for VS 2022
: 用 64位x64编译器 构建 64位x64 的目标程序。x86_x64 Cross Tools Command Prompt for VS 2022
: 用 86位x32编译器 构建 64位x64 的目标程序。x64_x86 Cross Tools Command Prompt for VS 2022
: 用 64位x64编译器 构建 32位x86 的目标程序。
打开对于的命令行,然后在此命令行下执行cl xx.cpp
等相关编译命令。
方法二 bat脚本设置:
C:\software\MicrosoftVisualStudio\2022\BuildTools\VC\Auxiliary\Build
下存在多个批处理文件,这些批处理文件可以初始化相应构建需求的环境变量:
vcvars32.bat
: 使用 32位x86 编译器构建 32位x86 代码。vcvars64.bat
: 使用 64位x64 编译器构建 64位x64 代码。vcvarsx86_amd64.bat
: 使用 32位x86 本机兼容工具生成 64位x64 代码。vcvarsamd64_x86.bat
: 使用 64位x64 本机兼容工具生成 32位x86 代码。vcvarsx86_arm.bat
: 使用 32位x86 本机兼容工具生成 ARM 代码。vcvarsamd64_arm.bat
: 使用 64位x64 本机兼容工具生成 ARM 代码。vcvarsx86_arm64.bat
: 使用 32位x86 本机兼容工具生成 ARM64 代码。vcvarsamd64_arm64.bat
: 使用 64位x64 本机兼容工具生成 ARM64 代码。
打开cmd命令行
或者power shell
, 然后执行相应的.bat
脚本然,再执行cl xx.cpp
等相关编译命令。
方法三 手动配置:
MSVC编辑器的默认安装在C:\Program Files (x86)\Microsoft Visual Studio
,安装时可以自定义安装路径。在安装目录下的2022\BuildTools\VC\Tools\MSVC\14.40.33807\bin
路径下,其中有两个文件夹,分别是hostx64和hostx86,这两个文件夹下又分别有x64和x86,他们的含义如下:
1 | bin |
根据自己的需求,选择对应的路径,如:我的主机是64位的,我希望用64位的编译器编译32位的目标程序,设置环境变量如下:
1 | MSVC_DIR: C:\software\MicrosoftVisualStudio\2022\BuildTools\VC\Tools\MSVC\14.40.33807 |
2.2. Linux(Ubuntu)
2.2.1. 安装GCC/GDB
1. 安装:
1 | # 更新软件源 |
Ubuntu 默认情况下没有提供C/C++编译环境的,你可以单独安装gcc、g++等工具,但会比较麻烦。Ubuntu提供了一个build-essential软件包,安装了该软件包,编译c/c++所需要的软件包也都会被安装。
2. 校验:
1 | # 执行以下命令确认每个软件是否安装成功 |
2.2.2. 安装CMake
1. 安装:
1 | sudo apt install cmake |
1. 校验:
1 | cmake --version |
2.3. macOS
2.3.1. clang的安装
macOS下,我们可以通过安装Xcode命令行工具
来安装clang,因为Xcode命令行工具
中包含了clang。
在命令行中输入
xcode-select --install
,之后你会看到一个面板,要求你安装 Xcode 命令行工具。点击 “Install”(安装),开始下载和安装过程。
当安装完成后,你会看到一个确认信息。
验证 XCode 是否安装成功
输入xcode-select -p
,如果看到下面的内容说明安装成功:/Library/Developer/CommandLineTools
验证 Clang 是否安装成功
输入clang --version
,如果看到下面的内容,说明安装成功:1
2
3
4Apple Clang version 15.0.0 (Clang-1500.3.9.4)
Target: x86_64-apple-darwin23.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
2.3.2. 为什么gcc的版本号显示的是Clang version
?
Xcode命令行工具
安装完后,就已经包含gcc/g++工具了,我们可以查看一下其版本号
1 | ➜ ~ gcc --version |
你有没有发现一个奇怪的现象:我们要查看的是gcc/g++的版本号,这里显示的版本号为什么是Apple Clang version XXX
?
个人的理解: 这里的gcc/g++已经不是GNU Compiler Collection
中的gcc/g++了, 某种意义上讲,他可能是 Clang/clang++ 的一个别名,底层的实现可能都换了,只是在接口上他做到了与GCC兼容。因为 Clang 设计的初衷就是为了超越和取代GCC的。
2.3.3. gcc的安装
如果你想独立安装GNU Compiler Collection
,而不是XCode自带的gcc/g++,要如何操作?
- 用homebrew安装gcc(如果homebrew未安装请自行安装,这里不再讲解homebrew的安装方法)。
1 | brew install gcc |
- 安装完后,找到上述命令安装的GCC版本
1 | ➜ ~ ls -l /usr/local/bin | grep g++ |
说明我们的GCC安装成功,安装的版本是:14.1.0。可以用同样的方式查找gcc。
- 修改配置
在~/.bash_profile
文件添加如下内容:
1 | alias gcc='gcc-14' |
如果你用的是zsh,则在~/.zshrc
文件中添加。
- 加载配置
1 | # bash |
- 再次验证版本号
1 | ➜ ~ gcc --version |
可以看到现在版本号不再显示Apple Clang version XXX
了。
3. 验证编译器是否安装正常
3.1. 写一个测试Demo
- 创建一个目录,如
test_demo
,并进入该目录。 - 在该目录下创建一个
test.cpp
文件,并输入以下代码:
1 |
|
3.2. 编译并运行
3.2.1. Windows
1 | cl test.cpp |
3.2.2. Linux
1 | g++ test.cpp |
3.2.3. macOS
1 | clang++ test.cpp |
如何有正常输出Hello, world!
则说明编译器安装成功。