关注公众号 “融码一生”,领取全套 PDF / 电子书
1、gcc 介绍
- 谈到 GCC,就不得不提由理查德·斯托曼于 1983 年发起的 GNU 计划(GNU's Not UNIX,“革奴计划”)。GNU 计划的最终目标是打造出一套完全自由(自由使用、自由更改、自由发布)、开源的操作系统,并初步将其命名为 GNU 操作系统。
- GNU 计划的实施可谓一波三折,最重要的一点是,虽然该计划为 GNU 操作系统量身定做了名为 Thr Hurd 的系统内核,但由于其性能比不上同时期诞生的 Linux 内核,最终 GNU 计划放弃 The Hurd 而选用 Linux 作为 GNU 操作系统的内核。
- 在 Linux 内核的基础上,GNU 计划开发了很多系统部件,GCC 就是其中之一(除此之外,还有 Emacs 等非常实用的软件)。
- 早期 GCC 的全拼为 GNU C Compiler,即 GUN 计划诞生的 C 语言编译器,显然最初 GCC 的定位确实只用于编译 C 语言。但经过这些年不断的迭代,GCC 的功能得到了很大的扩展,它不仅可以用来编译 C 语言程序,还可以处理 C++、Go、Objective-C 等多种编译语言编写的程序。与此同时,由于之前的 GNU C Compiler 已经无法完美诠释 GCC 的含义,所以其英文全称被重新定义为 GNU Compiler Collection(GNU 编译器套件)。
-
- 编译器可以简单地将其理解为 “翻译器”。计算机只认识二进制指令(0 和 1 组成的指令),C 语言代码、C++ 代码、Go 代码等计算机根本无法识别,只有将程序中的每条语句翻译成对应的二进制指令,计算机才能执行。
- GCC 编译器从未停止过改进。截止 2020 年 5 月,GCC 已经从最初的 1.0 版本发展到了 10.1 版本,期间历经了上百个版本的迭代。作为一款最受欢迎的编译器,GCC 被移植到数以千计的软/硬件平台上,几乎所有的 Linux 发行版也都默认安装有 GCC 编译器。
- 示例:使用 gcc 命令将 C 语言代码编译成一个可执行文件
#include <stdio.h>
int main(){
puts("hello, world.");
return 0;
}
# jy: 将 demo.c 编译成可执行文件
gcc demo.c -o demo.exe
# jy: 编译完成后即可执行 demo.exe(执行结果输出:hello, world.)
./demo.exe
2、安装
(1)yum 命令快速安装
yum -y install gcc
yum -y install gcc-c++
# 查看版本号
gcc --version
- 通过执行这 2 条指令,就可以在 CentOS 系统中利用 gcc 命令来执行 C 语言程序,利用 g++ 命令来执行 C++ 程序。
- 注意:采用此方式安装的 GCC 编译器,版本通常较低。如果想编译 C++ 11 标准下的 C++ 程序,则至少要安装 4.8 版本的 GCC 编译器,低版本的 GCC 编译器不支持 C++ 11 标准。
(2)源码安装
- 适用于安装/升级至指定版本(此方式较为耗时);需提前到 GCC 官网下载指定版本的 GCC 源码安装包(每个版本中都包含 2 种格式的压缩包,分别为
tar.gz
和tar.xz
,仅仅是压缩格式不同)
- 1)需要当前系统中存在一个可用的编译器,可以用旧版本的 GCC 编译器来编译安装新版本的 GCC 编译器。安装旧版 gcc 编译器(如已安装,可忽略):
# jy: 安装编译 C 和 C++ 代码所需的静态链接库
yum install -y glibc-static libstdc++-static
# jy: 安装编译 C 和 C++ 代码的 gcc 和 g++ 指令
yum install -y gcc gcc-c++
- 2)下载
gcc-10.1.0.tar.gz
安装包并将其解压至/usr/local/
目录(会在该目录下生成gcc-10.1.0
文件夹)
tar -xf gcc-10.1.0.tar.gz -C /usr/local/
- 3)下载安装 GCC 所需要的依赖包(如
gmp
、mpfr
、mpc
等)
cd /usr/local/gcc-10.1.0
# jy: 观察确保 gmp、mpfr、mpc 等依赖包成功下载后才能继续执行下面的安装步骤
./contrib/download_prerequisites
- 4)创建一个目录,用于存放编译 GCC 源码包生成的文件、编译、安装
mkdir /usr/local/gcc-build-10.1.0
cd /usr/local/gcc-build-10.1.0
# jy: 由于 GCC 编译器支持多种编程语言的编译,而实际应用中可能只需要编译 1~2 种编程语言,因此
# 需要对其进行必要的配置。以下配置 GCC 支持编译 C 和 C++ 语言
# --enable-languages 用于设定 GCC 编译器支持编译的编程语言,如 c、c++、java、objc、
# obj-c++、go 等。
../gcc-10.1.0/configure --enable-checking=release --enable-languages=c,c++ --disable-multilib
# jy: 以上指令会在当前目录下创建 makefile 文件, 随后即可使用 make 命令来编译 GCC 源程序
# 注意,编译过程是非常耗时的(本机耗时 6 小时完成编译)
make
# jy: 安装 gcc
make install
# jy: 安装成功后查看 gcc 版本仍会显示之前安装的版本。需在操作系统重启之后才会更新。
gcc --version
3、gcc 的组成部分
- 以下列出了 GCC 的各个部分并不总是出现的。有些和语言相关(如果没有安装某种特定语言,系统中就不会出现相关的文件)。
部分 |
描述 |
c++ |
gcc 的一个版木,默认语言设置为 C++,会在连接时自动包含标准 C++ 库(和 g++ 一样) |
ccl |
实际的 C 编译程序 |
cclplus |
实际的 C++ 编泽程序 |
collect2 |
在不使用 GNU 连接程序的系统上,有必要运行 collect2 来产生特定的全局初始化代码(如 C++ 的构造函数和析构函数) |
configure |
GCC 源代码树根目录中的一个脚木,用于设置配置值和创建 GCC 编译程序必需的 make 程序的描述文件 |
crt0.o |
这个初始化和结束代码是为每个系统定制的,而且也被编译进该文件,该文件然后会被连接到每个可执行文件中来执行必要的启动和终止程序 |
cygwin1.dll |
Windows 的共享库提供的 API,模拟 UNIX 系统调用 |
f77 |
该驱动程序可用于编译 Fortran |
f771 |
实际的 Fortran 编译程序 |
g++ |
gcc 的一个版木,默认语言设置为 C++,在连接的时候自动包含标准 C++ 库(和 c++ 一样) |
gcc |
该驱动程序等同于执行编译程序和连接程序以产生需要的输出 |
gcj |
该驱动程序用于编译 Java |
gnat1 |
实际的 Ada 编译程序 |
gnatbind |
一种工具,用于执行 Ada 语言绑定 |
gnatlink |
一种工具,用于执行 Ada 语言连接 |
jc1 |
实际的 Java 编译程序 |
libgcc |
该库包含的例程被作为编泽程序的一部分,是因为它们可被连接到实际的可执行程序中。 它们是特殊的例程,连接到可执行程序,来执行基木的任务,例如浮点运算。这些库中的例程通常都是平台相关的 |
libgcj |
运行时库包含所有的核心 Java 类 |
libobjc |
对所有 Objective-C 程序都必须的运行时库 |
libstdc++ |
运行时库,包括定义为标准语言一部分的所有的 C++ 类和函数 |
4、GCC 协同工作软件
- 以下列出的软件和 GCC 协同工作、实现编译过程。有些很基本(如 as 和 Id),有些则非常有用但不是严格需要。尽管这些工具中的很多都是各种 UNIX 系统的本地工具,但还是能够通过 GNU 包 binutils 得到大多数工具。
工具 |
描述 |
addr2line |
给出一个可执行文件的内部地址,addr2line 使用文件中的调试信息将地址翻泽成源代码文件名和行号。该程序是 binutils 包的一部分 |
ar |
这是一个程序,可通过从文档中增加、删除和析取文件来维护库文件。通常使用该工具是为了创建和管理连接程序使用的目标库文档。该程序是 binutils 包的一部分 |
as |
GNU 汇编器。实际上它是一族汇编器,因为它可以被编泽或能够在各种不同平台上工作。 该程序是 binutils 包的一部分 |
autoconf |
产生的 shell 脚木自动配置源代码包去编泽某个特定版木的 UNIX |
c++filt |
程序接受被 C++ 编泽程序转换过的名字(不是被重载的),而且将该名字翻泽成初始形式。 该程序是 binutils 包的一部分 |
f2c |
是 Fortran 到C的翻译程序。不是 GCC 的一部分 |
gcov |
gprof 使用的配置工具,用来确定程序运行的时候哪一部分耗时最大 |
gdb |
GNU 调试器,可用于检查程序运行时的值和行为 |
GNATS |
GNU 的调试跟踪系统(GNU Bug Tracking System)。一个跟踪 GCC 和其他 GNU 软件问题的在线系统 |
gprof |
该程序会监督编泽程序的执行过程,并报告程序中各个函数的运行时间,可以根据所提供 的配置文件来优化程序。该程序是 binutils 包的一部分 |
ld |
GNU 连接程序。该程序将目标文件的集合组合成可执行程序。该程序是 binutils 包的一部 |
libtool |
一个基本库,支持 make 程序的描述文件使用的简化共享库用法的脚木 |
make |
一个工具程序,它会读 makefile 脚木来确定程序中的哪个部分需要编泽和连接,然后发布 必要的命令。它读出的脚木(叫做 makefile 或 Makefile)定义了文件关系和依赖关系 |
nlmconv |
将可重定位的目标文件转换成 NetWare 可加载模块(NetWare Loadable Module, NLM)。该 程序是 binutils 的一部分 |
nm |
列出目标文件中定义的符号。该程序是 binutils 包的一部分 |
objcopy |
将目标文件从一种二进制格式复制和翻译到另外一种。该程序是 binutils 包的一部分 |
objdump |
显示一个或多个目标文件中保存的多种不同信息。该程序是 binutils 包的一部分 |
ranlib |
创建和添加到 ar 文档的索引。该索引被 Id 使用来定位库中的模块。该程序是 binutils 包的一部分 |
ratfor |
Ratfor 预处理程序可由 GCC 激活,但不是标准 GCC 发布版的一部分 |
readelf |
从 ELF 格式的目标文件显示信息。该程序是 binutils 包的一部分 |
size |
列出目标文件中每个部分的名字和尺寸。该程序是 binutils 包的一部分 |
strings |
浏览所有类型的文件,析取出用于显示的字符串。该程序是 binutils 包的一部分 |
strip |
从目标文件或文档库中去掉符号表,以及其他调试所需的信息。该程序是 binutils 包的一部 |
vcg |
Ratfor 浏览器从文木文件中读取信息,并以图表形式显示它们。而 vcg 工具并不是 GCC 发布中的一部分,但 -dv 选项可被用来产生 vcg 可以理解的优化数据的格式 |
windres |
Window 资源文件编泽程序。该程序是 binutils 包的一部分 |
关注公众号 “融码一生”,领取全套 PDF / 电子书