gcc简介

发展历史

创建阶段(1987年前):
1984年,Richard Stallman开始着手开发GNU计划,旨在创建一个完全自由的操作系统。
1985年,GNU计划公开宣布,并开始逐步实现各种工具和组件。

初期版本(1987-1990年代):
1987年:第一个GNU C编译器(GCC 1.0)发布。它支持C语言,并且是一个高度可移植的编译器,可以在多个平台上生成代码。
1988年:GCC 1.1发布,添加了对C++的支持。这是第一个支持C++的编译器之一。

1990年代初,GCC开始支持更多的编程语言,如C++、Fortran、Pascal等:
1990年:GCC 1.4发布,开始支持Fortran语言。随后的版本增加了对Ada、Objective-C等语言的支持。
1994年:GCC 2.0发布,带来了一系列重大改进,包括新的代码生成架构和更好的优化技术。
1997年:GCC 2.95发布,是一个重要的里程碑版本,提供了对C++标准的广泛支持,并且是许多操作系统的默认编译器。
2000年:GCC 3.0发布,引入了全新的C++编译器前端(g++),它提供了对C++标准的更好支持,并且是第一个能够完全支持ISO C99标准的版本。

2003年,GCC从原来的GNU General Public License(GPL)版本2转换为GPL版本3,以反映GPL的最新发展和意图。
同时,GCC在这一时期继续发展和改进,增加了对新的硬件平台和体系结构的支持,以及对新的语言标准的兼容性。
现代发展(2010年代至今):
2005年:GCC 4.0发布,引入了许多新的功能和优化,包括全新的中间表示(RTL),以及对多处理器支持的改进。

进入2010年代,GCC仍然是主流的编译器之一,被广泛应用于许多操作系统和平台上。
GCC继续通过不断更新和改进来适应新的编程语言标准和硬件体系结构。
2012年:GCC 4.7发布,引入了对C++11标准的支持,这是一个重要的版本,标志着GCC对最新C++标准的全面支持。
2015年:GCC 5.0发布,引入了对C++14标准的支持,并且改进了优化和错误检测功能。
2017年:GCC 7.1发布,引入了对C++17标准的支持,并且提供了一些新的优化和改进。
2019年:GCC 9.1发布,引入了对C++20标准的部分支持,并且改进了优化和错误检测功能。
2021年:GCC 11.1发布,引入了对C++20标准的完整支持,并且带来了许多新的优化和改进。

特点

1.跨平台性:GCC可在各种不同的硬件平台和操作系统上运行,提供了广泛的跨平台支持。gcc编译器不仅可以在本地平台上构建应用程序,还可以通过交叉编译的方式在一个平台上构建另一个平台的应用程序。 交叉编译在嵌入式开发和跨平台开发中非常常见,可以实现在不同操作系统和处理器架构之间构建应用程序。

2.支持多种编程语言:GCC编译系统支持众多的前端编程语言,主要包括C、C++、Ada、Fortran、Java、Objective-C、Objective-C++等语言的前端处理。

3.优化能力:GCC具有丰富的代码优化功能,可以提高程序的性能和效率。编译器根据其对程序的了解进行优化。将多个文件一次性编译为单个输出文件模式,使编译器在编译每个文件时能够使用从所有文件中获得的信息。gcc提供的代码优化功能非常强大,它通过参数-On来控制优化代码的生成,其中n为优化级别的整数,比较典型的范围是从0变化到2或3(与版本有关)。

4.社区支持:由于GCC是一个开源软件,拥有庞大的社区支持和活跃的开发团队,不断更新和改进。

5.工具丰富:除了编译器本身,GCC还提供了一系列相关的工具,如调试器(GDB)、性能分析工具等,方便开发者进行程序开发和调试。GCC不是一个孤立的编译工具,而是整个GNU工程中的一个组成部分。GNU工程中的其他软件,包括GNU C库glibc、GNU的调试工具gdb,以及GNU二进制工具链binutils等都与GCC关系密切,互相依赖。

编译过程

当使用GCC编译器编译一个 hello.c 时,编译过程通常包括以下详细步骤:

预处理(Preprocessing):

(1)预处理器首先扫描源代码文件(例如,hello.c)。它会处理以 # 符号开头的预处理指令,例如 #include、#define 等。所有被包含的头文件(例如标准库头文件 stdio.h)都会被插入到源代码中,扩展源文件。宏定义会被展开,例如,如果有 #define 定义了一个宏,那么它会被替换为宏的实际内容。预处理后的代码将被保存为一个中间文件(通常以 .i 或 .ii 为扩展名)。

(2)单独执行预处理的命令是 cpp(C Preprocessor),它会将源文件预处理并生成中间文件。可以执行以下命令:

cpp hello.c -o hello.i

hello.c 是C源文件。
-o hello.i 指定输出文件名为 hello.i。
这个命令会将预处理后的代码保存到 hello.i 中。

编译(Compiling):

(1)编译器接受预处理后的代码并进行词法分析、语法分析以及类型检查。它将C源代码翻译成汇编语言,生成一个汇编代码文件。这个汇编代码包含了计算机能够理解的低级指令,以及相关的注释。汇编代码文件通常具有 .s 扩展名。

(2)单独执行编译的命令是 gcc,它将中间文件编译成汇编代码并生成汇编文件。可以执行以下命令:

gcc -S hello.i -o hello.s

-S 选项告诉编译器生成汇编代码而不是目标文件。
hello.i 是中间文件的输入。
-o hello.s 指定生成的汇编文件名为 hello.s。
这个命令会将编译后的汇编代码保存到 hello.s 中。

汇编(Assembling):

(1)汇编器接受汇编代码文件并将其转化为机器码指令。它生成一个目标文件,其中包含了二进制表示的机器码以及一些元数据。目标文件通常具有 .o、.obj 或 .elf 扩展名。.bin .elf等文件对于初学者来说很抽象,在完成南大PA的ftrace后基础设施(2) · GitBook (nju-projectn.github.io),会加深elf文件的理解,但要深刻理解这些结构化的文件,以及计算机程序的执行过程,需要了解加载器、链接器等操作系统提供的程序,这些结构化的文件可以粗糙地理解为上述程序之间的协议。

(2)单独执行汇编的命令是 as(Assembler),它将汇编代码转化为目标文件。可以执行以下命令:

as hello.s -o hello.o

hello.s 是汇编代码文件的输入。
-o hello.o 指定生成的目标文件名为 hello.o。
这个命令会将汇编代码转换为二进制目标文件,并保存为 hello.o。

链接(Linking):

(1)链接器(Linker)将目标文件与其他目标文件和库文件链接在一起,创建最终的可执行文件。它会解析程序中使用的函数和符号,以确保它们都能正确地连接。标准库函数(如 printf)通常包含在C标准库中,链接器会将这些函数的实现与程序链接在一起。最终生成的可执行文件通常没有扩展名(或者在Windows上可能是 .exe)。

(2)单独执行链接的命令是 gcc,它将目标文件与其他目标文件和库文件链接在一起,生成最终的可执行文件。可以执行以下命令:

gcc hello.o -o hello

hello.o 是目标文件的输入。
-o hello 指定生成的可执行文件名为 hello。
这个命令会将目标文件与所需的库文件链接在一起,生成可执行文件 hello。

可执行文件生成(Executable File Generation):

(1)在生成可执行文件之前,链接器还可以执行额外的优化,例如删除未使用的代码和数据。最终的可执行文件包含了所有必要的信息,可以被操作系统加载和执行。

总结:上述步骤演示了如何单独执行GCC编译过程的各个阶段,并使用不同的命令来控制每个阶段的输出。通过单独执行这些步骤,你可以更详细地了解每个阶段的处理过程和生成的文件。然而,在实际开发中,通常会使用一个简单的命令来完成整个编译过程,例如:

gcc hello.c -o hello

这个命令会自动执行所有的步骤,生成最终的可执行文件 hello。

常用编译命令

假设源程序文件名为 hello.c
● 无选项
gcc hello.c
对源文件进行预处理,编译,汇编,链接生成可执行文件,默认为 a.out
● 选项 -o
gcc hello.c -o hello
对源文件进行预处理,编译,汇编,链接生成的可执行文件,指定名称为 hello
● 选项 -E
gcc -E hello.c -o hello.i
对源文件 hello.c 进行预处理,输出 hello.i
● 选项 -S
gcc -S hello.c
进行汇编,得到汇编代码 hello.s
● 选项 -c
gcc -c hello.c
进行编译,生成目标文件 hello.o
● 无选项
gcc hello.o -o hello
对目标文件 hello.o 进行链接,生成可执行文件 hello
● 选项 -O
gcc -O2 hello.c -o hello
编译链接,并指明优化级别 -O2
常见的一些优化选项:
● -O0 :关闭优化。编译速度快,生成的代码简单,适用于调试和开发阶段。
● -O1 :启用基本优化。进行一些简单的优化,以提高执行速度,适合用于一般应用程序的发布版本。
● -O2 :启用更多的优化。相比 -O1,会进行更多的优化操作,使得生成的代码更高效,但可能会增加编译时间。
● -O3 :启用更进一步的优化。进行更多更复杂的优化,可以提高程序的性能,但也可能增加编译时间和生成的代码大
小。
● -Os :优化代码大小。尽量减小生成的代码的大小,适用于对代码大小有要求的场景。
● -Ofast :启用快速优化。尽可能地提高执行速度,可能会牺牲一些精确度和标准性。
● -Og :针对调试的优化。生成易于调试的代码,同时也尽可能保留源代码结构。
● 选项 -g
gcc -g hello.c -o hello
在可执行文件中生成调试信息,便于调试程序
● 选项 -I
gcc -I/path/to/header hello.c -o hello
可以指定头文件的搜索路径
● 选项 -L
gcc -L/path/to/library hello.c -o hello
可以指定库文件的搜索路径
● 选项 -l
gcc hello.c -o hello -l<library>
可以指定链接的库,如-lm 表示链接 math 库
● 选项 -Wall
gcc -Wall hello.c -o hello
显示编译过程中的警告信息,有助于发现潜在问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值