Centos升级GCC

升级GCC

第一步,下载你需要的gcc源码,https://mirror.sergal.org/gnu/gcc/ 到这个地址去找就可以了。这里我们假设安装的是gcc-5.5.0.tar.gz。国内源为 https://mirrors.ustc.edu.cn/gnu/gcc/

第二步,tar -xzvf gcc-5.5.0.tar.gz然后cd gcc-5.5.0

第三步,找到./contrib/download_prerequisites文件,这里面放着所需的依赖,由于是国内的网站可能会在线安装不了(如果在线安装成功,直接进入第四步),这里讲下手动安装,其实就是三个依赖gmp-4.3.2.tar.gz,mpfr-3.1.4.tar.bz2,mpc-1.0.1.tar.gz,不同版本的gcc可能需要不同的版的,如果出现错误,根据错误提示更换需要的版本即可,这三个依赖最好按照顺序安装,因为它们之间也是有依赖关系的。

  1. 安装gmp-4.3.2.tar.gz,到这里找你要的版本http://ftp.gnu.org/pub/gnu/gmp/,然后解压`tar -xzvf gmp-4.3.2.tar.gz,然后进入目录cd gmp-4.3.2,再依次执行./configure —prefix=/data4/zhaodali/usr && make -j 8 && make install`
  2. 安装`mpfr-3.1.4.tar.bz2,到这里找你要的版本https://www.mpfr.org/history.html,然后解压`tar -jxvf mpfr-3.1.4.tar.bz2,然后进入目录cd mpfr-3.1.4,再依次执行./configure —prefix=/data4/zhaodali/usr && make -j 8&& make install`
  3. 安装mpc-1.0.1.tar.gz,到这里找你要的版本http://ftp.gnu.org/gnu/mpc/ 或者 https://gcc.gnu.org/pub/gcc/infrastructure/,然后解压`tar -xzvf mpc-1.0.1.tar.gz,然后进入目录cd mpc-1.0.1,再依次执行./configure —prefix=/data4/zhaodali/usr && make -j 8 && make install`

需要注意的是,这里安装的时候是没有sudo权限的,所以将这些都安装到了/data4/zhaodali/usr目录下面。

另外,解压tar.gz命令是tar -zxvf xx.tar.gz;解压tar.bz2的命令是tar -jxvf xx.tar.bz2

接着,编译和安装gcc

1
2
3
4
5
6
cd gcc-5.5.0/../
mkdir objdir
cd objdir
$PWD/../gcc-5.5.0/configure --prefix=/data4/zhaodali/usr/GCC-5.5.0 --enable-languages=c,c++,fortran,go
make -j 16
make install

最后,给当前用户添加环境变量:

1
2
3
export PATH=/data4/zhaodali/usr/GCC-5.5.0/bin:$PATH
export LD_LIBRARY_PATH=/data4/zhaodali/usr/GCC-5.5.0/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/data4/zhaodali/usr/GCC-5.5.0/lib64:$LD_LIBRARY_PATH

GCC与-std编译标准

C 语言为例,发展至今该编程语言已经迭代了诸多个版本,例如 C89(偶尔又称为 C90)、C94(C89 的修订版)、C99、C11、C17,以及当下正在开发的 C2X 新标准。甚至于在这些标准的基础上,GCC 编译器本身还对 C 语言的语法进行了扩展,先后产生了 GNU90、GNU99、GNU11 以及 GNU17 这 4 个版本。

有趣的是,GCC 编译器对 C 语言的很多扩展,往往会被 C 语言标准委员会所采纳,并添加到新的 C 语言标准中。例如,GNU90 中对 C 语言的一些扩展,就融入到了新的 C99 标准中;GNU90、GNU99 中对 C 语言的一些扩展,被融入到了新的 C11 标准中。

C++ 语言的发展也历经了很多个版本,包括 C++98、C++03(C++98 的修订版)、C++11(有时又称为 C++0x)、C++14、C++17,以及即将要发布的 C++20 新标准。和 C 语言类似,GCC 编译器本身也对不同的 C++ 标准做了相应的扩展,比如 GNU++98、GNU++11、GNU++14、GNU++17。

不同版本的 GCC 编译器,默认使用的标准版本也不尽相同。以当前最新的 GCC 10.1.0 版本为例,默认情况下 GCC 编译器会以 GNU11 标准(C11 标准的扩展版)编译 C 语言程序,以 GNU++14 标准(C++14 标准的扩展版)编译 C++ 程序。关于这可以在 GCC 手册中查找。

对于编译 C、C++ 程序来说,借助 -std 选项即可手动控制 GCC 编译程序时所使用的编译标准。也就是说,当使用 gcc 指令编译 C 语言程序时,我们可以借助 -std 选项指定要使用的编译标准;同样,当使用 g++ 指令编译 C++ 程序时,也可以借助 -std 选项指定要使用的编译标准。

1
gcc/g++ -std=编译标准

注意,不同版本的 GCC 编译器,所支持使用的 C/C++ 编译标准也是不同的。

下表罗列了常用的 GCC 版本对 C 语言编译标准的支持程度。

image-20210728194405433

注意,表头表示的是各个编译标准的名称,而表格内部的则为 -std 可用的值,例如 -std=c89、-std=c11、-std=gnu90 等(表 2 也是如此)。

下表罗列了常用的 GCC 版本对 C++ 程序编译标准的支持程度。

image-20210728194502988

上面两个表中,有些版本对应的同一编译标准有 2 种表示方式,例如对于 8.4~10.1 版本的 GCC 编译器来说,-std=c89 和 -std=c90 是一样的,使用的都是 C89/C90 标准。另外,GCC 编译器还有其他版本,读者可查阅 GCC文档获得相关信息。

GCC与clang

编译器一般构成

传统的编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd)。

前端解析源码,检查错误,然后编译成指定语言的抽象语法树(Abstract Syntax Tree)。可以选择性地将 AST 转换为新的中间码以进行优化,优化器和后端生成机器码。

优化器负责做各种转化尝试提高代码的执行效率,如消除冗余的计算,优化器通常或多或少地独立于语言和目标机器。后端(也叫代码生成器)负责将代码映射到目标指令集。除了生成正确的代码,它还负责利用目标架构的特殊功能生成性能更好的代码。编译器后端的通用功能包括指令选择、寄存器分配和指令调度。

该模型同样适用于解释器和JIT 编译器。Java 虚拟机(JVM)也是实践了该模型,它使用Java 字节码作为前端和优化器之间的接口。

该设计的优点

当编译器决定支持多语言或多目标架构时,这种经典设计的优势就很明显了。如果编译器在优化时使用一种通用的中间码,那么前端可以用任意的可编译语言编写,且后端可以编译成任何目标机器码。如下图所示。

img

GCC

GCC(GNU Compiler Collection,GNU编译器套装),是一套由 GNU 开发的编程语言编译器。GCC 原名为 GNU C 语言编译器,因为它原本只能处理 C语言。GCC 快速演进,变得可处理 C++、Fortran、Pascal、Objective-C、Java, 以及 Ada 等他语言。

GCC缺点:GCC的三段式模块必须配套使用,很难做到部分重用。

LLVM

LLVM的提出是为了解决编译器代码重用的问题。LLVM是三段式编译器优化器+后端的SDK集合,提供了一系列对外接口供开发者调用

(1)前端:支持各种组件的前端(Clang、llvm-gcc、GHC),需要遵守LLVM的规则,输出中间代码LLVM IR

(2)优化器:LLVM IR通过一系列分析和优化从而改进代码,然后输入代码生成器生成目标机器码

(3)后端:将优化器优化后的中间代码转换为目标机器的代码

img

Clang

  1. Clang是一个C、C++、Objective-C和Objective-C++编程语言的编译器前端,底层是由LLVM作为后端。

  2. Clang项目包括Clang前端和Clang静态分析器等,目的是输出代码对应的抽象语法树并将代码编译成LLVM bitcode。接着后端使用LLVM编译成平台相关的机器语言

LLVM/Clang/GCC之间的关系

  • Clang + LLVM = GCC

  • 开源软件——众所周知,GCC 和 Clang 都是免费的开源软件。但是他们的许可授权很不一样。GCC 是参照 GPL(GNU 公共许可证)授权的,而 Clang/LLVM 是 Apache 许可授权的。比较 GCC 和 Clang 的许可授权,最专业的是律师。

  • 支持平台—— GCC 和 Clang 都支持几乎所有的平台。Clang/LLVM 可在 Windows 本机上进行编译,而 GCC 则需要 MinGW 这样的子系统,才能与 Windows 兼容。这样比较 Clang 和 GCC 是不公平的,因为 GCC 没有在本地支持Windows 的计划。
  • 代码复杂度—— GCC 是一个非常复杂的软件,有超过 1500 万行代码,耦合很重,很难小粒度复用代码。尽管其前/后端定义清晰明了,但软件在本质上更为单一。对比 GCC,Clang 更多的是模块化架构,将编译后端的算法封装成为了一个个独立的模块并提供对外接口,具有定义良好的扩展点。
  • 高效代码生成—— Clang 和 GCC 的代码生成,在空间和时间的复杂度旗鼓相当。因此这种比较毫无意义,因为这两个编译优化工具都基于一种严密的静态分配形式。
  • 语言独立的类型系统——在这个标题下对比 Clang 与 GCC 很有意义。由于 Clang/LLVM 对所有兼容语言都使用语言独立的类型系统,因此可以确定指令的确切语义。GCC 则没有语言独立类型系统的设计目标。
  • 前端解析器—— GCC 以前有基于 Bison的 LR 解析器,后来转向了手写递归下降解析器。Clang 一直使用手写的确定性递归下降解析器,且可回溯。
  • 后端链接器—— GCC 与 Clang 的差异在这个层面最为明显。GCC 使用 ld 作为链接器,支持 ld-gold。Clang 使用 lld 作为链接器。通过一些基准测试,可以看出 lld 比 ld甚至最新的 ld-gold 都快。
  • 构建工具—— Clang 与 GCC 的另一个大的区别。GCC 使用 Autotools 和 Make 作为构建工具,而 Clang/LLVM 使用 CMake。
  • 调试支持—— GCC 有一个优秀的 GDB 调试器。GDB 历经时间考验,性能优异。Clang 则将 LLDB 调试器构建为 LLVM 上的一组可重用组件。
类别GCCClang/LLVM
许可证GNU GPLApache 2.0
代码模块化一体化架构模块化
支持平台*inx, Windows (MinGW)*inx, Natively in Windows
代码生成高效,有很多编译器选项可以使用高效,LLVM 后端使用了 SSA 表单
语言独立类型系统没有有(LLVM的设计初衷)
构建工具基于 MakeCMake
解析器最早采用 Bison LR,现在改为递归下解析器手写的递归下降解析器
链接器LDlld
调试器GDBLLDB

MinGW/MinGW-w64

GCC本身是Linux上的编译器套件,不能在windows上运行,而mingw则是gcc在windows上的移植。

最早的mingw项目只支持编译32位程序,后来分支出的mingw-w64项目则同时支持编译32/64位程序。

mingw-w64项目目前的状况比较复杂,有多个发行分支,具体可以参看官网的下载页。目前windows上最新、最靠谱的发行分支就是MSYS2

MSYS2

MSYS2(Minimal SYStem 2,下载地址)是与mingw-w64配套的命令行环境,它为windows提供了类似linux的命令和包管理器pacman,可以直接在命令行查找、安装和卸载各种第三方库和开发工具。

1
2
# 比如你想要安装opencv库
pacman -Syy mingw-w64-ucrt-x86_64-opencv
  • pacman同时是ArchLinux的包管理器(就像MacOS上的homebrew和Ubuntu上的apt一样),具体使用办法可以查阅ArchWiki(中文))
  • 实际上MinGW也有一个配套的MSYS,但它没有包管理器
  • git bash实际上是一个删减版的MSYS2,在安装文件夹下可以看到MSYS2的目录结构,但它也没有包管理
  • pacman本地安装使用pacman -U + 路径

安装gcc、gdb、cmake

以64为例,32位需要将x86_64替换为-i686

1
2
3
4
5
6
7
8
9
pacman -S mingw-w64-x86_64-toolchain
pacman -S mingw-w64-x86_64-gcc
pacman -S mingw-w64-x86_64-gdb
pacman -S mingw-w64-x86_64-cmake

# 检查版本
gcc --version
g++ --version
gdb --version

安装完毕之后,需要添加环境变量,这里以windows系统为例,MSYS2的安装路径为C:\Program Files\msys64 ,需要在系统PATH变量中添加C:\Program Files\msys64\mingw64\bin

参考

centOS系统gcc升级步骤(亲自测试成功)
tar.gz和tar.bz2解压命令
GCC 安装到自定义目录
GCC -std编译标准一览表
【编译原理】GCC/Clang/LLVM的区别与联系
「LLVM」开源软件架构之 LLVM
GCC vs Clang: 两大编译器巨头的龙争虎斗

------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道