一、文件名后缀

常用文件名后缀及其表示的文件类型如下表:

文件名后缀 文件类型
.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 可以使编译器在预处理结束时就停止编译。 例如:

gcc -E -o hello.i hello.c     

2.2 编译

这一阶段,编译器对源码进行词法分析、语法分析、优化等操作,最后生成汇编代码。这是整个过程中最重要的一步,因此也常把整个过程称为编译

可以通过选项 -S 使 GCC 在进行完编译后停止,生成 .s 的汇编程序。例如:

gcc -S -o hello.s hello.c     

2.3 汇编

这一阶段使用汇编器对汇编代码进行处理,生成机器语言代码,保存在后缀为 .o 的目标文件中。当程序由多个代码文件构成时,每个文件都要先完成汇编工作,生成 .o 目标文件后,才能进入下一步的链接工作。

目标文件已经是最终程序的某一部分了,只是在链接之前还不能执行。可以通过 -c 选项生成目标文件。例如:

gcc -c -o hello.o hello.c    

2.4 链接

经过汇编以后的机器代码还不能直接运行。为了使操作系统能够正确加载可执行文件,文件中必须包含固定格式的信息头,还必须与系统提供的启动代码链接起来才能正常运行,这些工作都是由链接器来完成的。例如:

gcc -o hello hello.c     

三、gcc 的基本用法

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

评论