Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

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

  1. MSVC(Microsoft Visual C++)由微软开发,主要用于Windows平台应用程序的开发。
  2. Visual Studio系列IDE默认集成了该编译器,可以通过下载安装Visual Studio安装包来安装。
  3. MSVC只能在Windows下用,不支持跨平台。

1.1.1. Visual C++Visual Studio的版本对应关系

_MSC_VER: 是MSVC编译器内置的宏定义,可以在源代码中直接引用。其值代表了MSVC编译器的版本,如:1900表示Visual Studio 2015(MSVC++ 14.0)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
MSC    1.0   _MSC_VER == 100
MSC 2.0 _MSC_VER == 200
MSC 3.0 _MSC_VER == 300
MSC 4.0 _MSC_VER == 400
MSC 5.0 _MSC_VER == 500
MSC 6.0 _MSC_VER == 600
MSC 7.0 _MSC_VER == 700
MSVC++ 1.0 _MSC_VER == 800
MSVC++ 2.0 _MSC_VER == 900
MSVC++ 4.0 _MSC_VER == 1000 (Developer Studio 4.0)
MSVC++ 4.2 _MSC_VER == 1020 (Developer Studio 4.2)
MSVC++ 5.0 _MSC_VER == 1100 (Visual Studio 97 version 5.0)
MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0 version 6.0)
MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002 version 7.0)
MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003 version 7.1)
MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005 version 8.0)
MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008 version 9.0)
MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010 version 10.0)
MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012 version 11.0)
MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013 version 12.0)
MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015 version 14.0)
MSVC++ 14.1 _MSC_VER == 1910 (Visual Studio 2017 version 15.0)
MSVC++ 14.11 _MSC_VER == 1911 (Visual Studio 2017 version 15.3)
MSVC++ 14.12 _MSC_VER == 1912 (Visual Studio 2017 version 15.5)
MSVC++ 14.13 _MSC_VER == 1913 (Visual Studio 2017 version 15.6)
MSVC++ 14.14 _MSC_VER == 1914 (Visual Studio 2017 version 15.7)
MSVC++ 14.15 _MSC_VER == 1915 (Visual Studio 2017 version 15.8)
MSVC++ 14.16 _MSC_VER == 1916 (Visual Studio 2017 version 15.9)
MSVC++ 14.2 _MSC_VER == 1920 (Visual Studio 2019 Version 16.0)
MSVC++ 14.21 _MSC_VER == 1921 (Visual Studio 2019 Version 16.1)
MSVC++ 14.22 _MSC_VER == 1922 (Visual Studio 2019 Version 16.2)
MSVC++ 14.30 _MSC_VER == 1930 (Visual Studio 2022 Version 17.0)
MSVC++ 14.31 _MSC_VER == 1931 (Visual Studio 2022 Version 17.1)

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的主要特点包括:

  1. 快速编译和低内存使用: Clang 的设计目标之一是提供比 GCC 更快的编译速度和更低的内存占用。
  2. 高质量的错误和警告信息: Clang 提供了详细和易于理解的错误和警告信息,有助于开发者更快地找到和修复问题。
  3. 与 GCC 兼容: Clang 支持大多数 GCC 的编译器选项和工具链,使得从 GCC 迁移到 Clang 相对容易。
  4. 模块化设计: Clang 的架构是模块化的,易于扩展和集成到其他工具和流程中。
  5. 支持现代语言特性: 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安装

  1. 进入微软官网下载页面:https://visualstudio.microsoft.com/zh-hans/downloads/
  2. 选择要下载的最新版本安装包下载器:
    1. 如果要下载完整的Visual Studio IDE,选择:Visual Studio 2022 -> 版本类型(如果是个人开发使用,可以选择Visual Studio Community 2022
    2. 如果只需要下载MSVC编译器,选择: 用于Visual Studio的工具 -> Visual Studio 2022 生成工具。
    3. 我希望用VSCode(而不是Visual Studio)来开发C++, 所有我只需要下载MSVC编译器。
  3. 双击打开下载好的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
2
3
4
5
6
7
bin
Hostx64 # 主机是64位的编译器
x64 # 编译的目标文件是64位程序
x86 # 编译的目标文件是32位程序
Hostx86 # 主机是32位的编译器
x64 # 编译的目标文件是64位程序
x86 # 编译的目标文件是32位程序

根据自己的需求,选择对应的路径,如:我的主机是64位的,我希望用64位的编译器编译32位的目标程序,设置环境变量如下:

1
2
3
4
5
MSVC_DIR: C:\software\MicrosoftVisualStudio\2022\BuildTools\VC\Tools\MSVC\14.40.33807

include: %MSVC_DIR%\include
lib: %MSVC_DIR%\lib\x86;
path: %MSVC_DIR%\bin\Hostx64\x86;

2.2. Linux(Ubuntu)

2.2.1. 安装GCC/GDB

1. 安装:

1
2
3
4
# 更新软件源
sudo apt update
# 通过以下命令安装编译器和调试器
sudo apt install build-essential gdb

Ubuntu 默认情况下没有提供C/C++编译环境的,你可以单独安装gcc、g++等工具,但会比较麻烦。Ubuntu提供了一个build-essential软件包,安装了该软件包,编译c/c++所需要的软件包也都会被安装。

2. 校验:

1
2
3
4
5
# 执行以下命令确认每个软件是否安装成功
# 如果成功,则显示版本号
gcc --version
g++ --version
gdb --version

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。

  1. 在命令行中输入xcode-select --install,之后你会看到一个面板,要求你安装 Xcode 命令行工具。

  2. 点击 “Install”(安装),开始下载和安装过程。

  3. 当安装完成后,你会看到一个确认信息。

  4. 验证 XCode 是否安装成功
    输入 xcode-select -p,如果看到下面的内容说明安装成功:/Library/Developer/CommandLineTools

  5. 验证 Clang 是否安装成功
    输入 clang --version,如果看到下面的内容,说明安装成功:

    1
    2
    3
    4
    Apple 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
2
3
4
5
6
7
8
9
10
11
➜  ~ gcc --version
Apple 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

➜ ~ g++ --version
Apple 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

你有没有发现一个奇怪的现象:我们要查看的是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++,要如何操作?

  1. 用homebrew安装gcc(如果homebrew未安装请自行安装,这里不再讲解homebrew的安装方法)。
1
brew install gcc
  1. 安装完后,找到上述命令安装的GCC版本
1
2
3
4
5
6
7
8
9
➜  ~ ls -l /usr/local/bin | grep g++
lrwxr-xr-x 1 spencer admin 33 8 2 17:08 g++-14 -> ../Cellar/gcc/14.1.0_2/bin/g++-14
lrwxr-xr-x 1 spencer admin 55 8 2 17:08 x86_64-apple-darwin23-g++-14 -> ../Cellar/gcc/14.1.0_2/bin/x86_64-apple-darwin23-g++-14
➜ ~
➜ ~ g++-14 --version
g++-14 (Homebrew GCC 14.1.0_2) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

说明我们的GCC安装成功,安装的版本是:14.1.0。可以用同样的方式查找gcc。

  1. 修改配置

~/.bash_profile 文件添加如下内容:

1
2
3
4
alias gcc='gcc-14'
alias cc='gcc-14'
alias g++='g++-14'
alias c++='c++-14'

如果你用的是zsh,则在~/.zshrc文件中添加。

  1. 加载配置
1
2
3
4
# bash
source ~/.bash_profile
# zsh
source ~/.zshrc
  1. 再次验证版本号
1
2
3
4
5
6
7
8
9
10
11
➜  ~ gcc --version
gcc-14 (Homebrew GCC 14.1.0_2) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

➜ ~ g++ --version
g++-14 (Homebrew GCC 14.1.0_2) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

可以看到现在版本号不再显示Apple Clang version XXX了。

3. 验证编译器是否安装正常

3.1. 写一个测试Demo

  1. 创建一个目录,如test_demo,并进入该目录。
  2. 在该目录下创建一个test.cpp文件,并输入以下代码:
1
2
3
4
5
6
7
#include <iostream>

int main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}

3.2. 编译并运行

3.2.1. Windows

1
2
cl test.cpp
test.exe

3.2.2. Linux

1
2
g++ test.cpp
./a.out

3.2.3. macOS

1
2
clang++ test.cpp
./a.out

如何有正常输出Hello, world!则说明编译器安装成功。

推荐阅读
Linux C++ 开发2 - 编写、编译、执行第一个程序 Linux C++ 开发2 - 编写、编译、执行第一个程序 Linux C++ 开发1 - 搭建C++开发环境 Linux C++ 开发1 - 搭建C++开发环境 Linux C++ 开发3 - 你写的Hello world经过哪些过程才被计算机理解和执行? Linux C++ 开发3 - 你写的Hello world经过哪些过程才被计算机理解和执行?

评论