一、文件名后缀
常用文件名后缀及其表示的文件类型如下表:
文件名后缀 | 文件类型 |
---|---|
.c | C 源文件 |
.i | 预处理后的 C 源文件 |
.ii | 预处理后的 C++ 源文件 |
.h | C 或 C++ 头文件 |
.C .cc .cp .cpp .c++ .cxx | C++ 源文件 |
.s | 汇编程序文件 |
.S | 必须预处理的汇编程序文件 |
.o | 目标文件 |
.a | 静态链接库 |
.so | 动态链接库 |
二、程序的编译过程
2.1 预处理
在这一阶段,源码中的所有预处理语句得到处理。预处理之后源码中不再包含任何预处理语句。 例如:
-
#include
语句所包含的文件内容替换掉语句本身 -
所有已定义的宏被展开
-
根据
#ifdef
、#if
等语句的条件是否成立取舍相应的部分
GCC预处理阶段可以生成 .i
的文件,通过选项 -E
可以使编译器在预处理结束时就停止编译。 例如:
1 | gcc -E -o hello.i hello.c |
2.2 编译
这一阶段,编译器对源码进行词法分析、语法分析、优化等操作,最后生成汇编代码。这是整个过程中最重要的一步,因此也常把整个过程称为编译
。
可以通过选项 -S
使 GCC 在进行完编译后停止,生成 .s
的汇编程序。例如:
1 | gcc -S -o hello.s hello.c |
2.3 汇编
这一阶段使用汇编器对汇编代码进行处理,生成机器语言代码,保存在后缀为 .o
的目标文件中。当程序由多个代码文件构成时,每个文件都要先完成汇编工作,生成 .o 目标文件后,才能进入下一步的链接工作。
目标文件已经是最终程序的某一部分了,只是在链接之前还不能执行。可以通过 -c
选项生成目标文件。例如:
1 | gcc -c -o hello.o hello.c |
2.4 链接
经过汇编以后的机器代码还不能直接运行。为了使操作系统能够正确加载可执行文件,文件中必须包含固定格式的信息头,还必须与系统提供的启动代码链接
起来才能正常运行,这些工作都是由链接器来完成的。例如:
1 | gcc -o hello hello.c |
三、gcc 的基本用法
1 | gcc [-Wall] [-O1..3] [-g] [-o name] file... |
-
-Wall
: 打开所有警告项 -
-O
: 设置优化级别,O0 表示关闭优化功能 -
-g
: 将调试信息编译到目标文件中 -
-o name
: 指定输出文件的名称是 name -
file
: 被编译(链接)的文件
使用举例:
四、gcc 命令行选项
按照选项作用所对应的编译阶段,可将 gcc 的选项分为四组:预处理选项、编译选项、优化选项和连接选项。
4.1 预处理选项
选项格式 | 功能 |
---|---|
-C | 在预处理后的输出中保留源文件中的注释 |
-D name | 预定义一个宏 name,而且其值为 1 |
-D name=definition | 预定义一个宏 name,并指定其值为 definition 所指定的值。其作用等价于在源文件中使用宏定义指令:#define name definition。但 -D 选项比宏定义指令的优先级高,它可以覆盖源文件中的定义 |
-U name | 取消先前对 name 的任何定义,不管是内置的,还是由 -D 选项提供的 |
-I dir | 指定搜索头文件的路径 dir。先在指定的路径中搜索要包含的头文件,若找不到,则在标准路径(/usr/include, /usr/lib及当前工作目录)上搜索 |
-E | 只对指定的源文件进行预处理,不做编译,生成的结果送到标准输出 |
4.2 编译选项
选项格式 | 功能 |
---|---|
-c | 只生成目标文件,不进行连接。用于对源文件的分别编译 |
-S | 只进行编译,不做汇编,生成汇编代码文件格式,其名与源文件相同,但扩展名为 .s |
-o file | 将输出放在文件file中。如果未使用该选项,则可执行文件放在 a.out 中 |
-g | 指示编译程序在目标代码中加入供调试程序 gdb 使用的附加信息 |
-v | 在标准出错输出上显示编译阶段所执行的命令,即编译驱动程序及预处理程序的版本号 |
4.3 优化选项
优化分为对中间代码的优化和针对目标码生成的优化。
4.4 连接选项
选项格式 | 功能 |
---|---|
object-file-name | 不以专用后缀结尾的文件名就认为是目标文件名或库名。连接程序可以根据文件内容来区分目标文件和库 |
-c -S -E | 如果使用其中任何一个选项,那么都不运行连接程序,而且目标文件名不应该用做参数 |
-llibrary | 连接时搜索由 library 命名的库。连接程序按照在命令行上给定的顺序搜索和处理库及目标文件。实际的库名是 liblibrary.a |
-static | 在支持动态连接的系统中,它强制使用静态链接库,而阻止连接动态库;而在其他系统中不起作用.把指定的目录 dir 加到连接程序搜索库文件的路径表中,即在搜索-l后面 |
-L dir | 列举的库文件时,首先到 dir 下搜索,找不到再到标准位置下搜索 |
-Bprefix | 该选项规定在什么地方查找可执行文件、库文件、包含文件和编译程序本身数据文件 |
-o file | 指定连接程序最后生成的可执行文件名称为 file,不是默认的 a.out |
评论