GCC编译器

GCC是一个交叉平台编译器,可以在当前CPU平台上为多种不同体系结构的硬件平台开发软件。

GCC指令的一般格式

gcc [选项] 要编译的文件名.文件类型 [选项] [目标文件]
  • 格式中 目标文件 可缺省。
  • GCC默认生成的可执行文件将命名为:要编译的文件名.out

GCC支持编译的文件类型

| 文件后缀名 | 解释 |
| :-: | - |
| .c | C语言编写的源代码文件 |
| .h | C程序所包含的头文件 |
| .i | 经编译器预处理后的C程序文件 |
| .s | 汇编语言源代码文件 |
| .o | 目标文件,内为二进制机器码 |

GCC选项分析

gcc [选项1] 文件 [选项2] [目标文件]

选项1

总体选项

| 选 项 1 | 解释 |
| :- | - |
| -E | 仅做预处理,不做编译、汇编和链接处理 |
| -S | 只进行到编译阶段,不做汇编和链接处理 |
| -c | 只进行到汇编阶段,不做链接处理 |
| -static | 使用静态库进行链接处理。编译出来的文件一般很大,不需要动态链接库即可运行。 |
| -share | 使用动态库进行链接处理。编译出来的文件较小,但是需要系统有动态库。 |
| -I dir | 预处理阶段,在头文件的搜索路径列表中添加dir目录,dir目录中可以放自己写的头文件。 |
| -L dir | 链接阶段,在库文件的搜索路径列表中添加dir目录。 |
| -g | 在编译出的可执行代码中加入调试信息,才能进行GDB调试 |

警告和出错选项

| 选 项 1 | 解释 |
| - | - |
| -Wall | 打开所有类型语法警告 |
| -w | 禁止所有警告信息 |

优化选项

| 选项1 | 解释 |
| - | - |
| -O | 减小目标文件大小、减少执行时间、不会使编译时间明显增加的优化。在编译大型程序时会明显增加编译时内存的使用。 |
| -O1 | 减小目标文件大小、减少执行时间、不会使编译时间明显增加的优化。在编译大型程序时会明显增加编译时内存的使用。 |
| -O2 | 包含-O1的优化,并增加了不需要在目标文件和执行速度上进行折衷优化。增加编译时间和目标文件的执行性能。 |

选项2

| 选 项 2 | 解释 |
| - | - |
| -o | 后面跟编译输出的文件 |

GCC编译流程

定义一个hello.c文件

#includ <stdio.h>
int main()
{
    printf("Hello World\n");
    return 0;
}

一步编译

gcc hello.c

默认生成一个a.out可执行文件。运行: ./a.out

gcc hello.c -o hello

生成一个hello可执行文件。运行:./hello

分步编译

预处理

gcc -E hello.c -o hello.i
  • 对.c文件中#预处理操作符的内容进行:头文件插入展开、宏替换、条件编译替换、去注释。不进行语法检查。
  • 标准头文件库位置:/usr/include

编译

gcc -S hello.i -o hello.s

首先进行代码的语法、词法的检查,若出现语法错误则结束编译并报错;若没有语法错误则生成汇编语言的源代码文件。

汇编

gcc -c hello.s -o hello.o

将汇编文件转换成二进制目标文件。还没有链接到库,不可执行。

链接

gcc hello.o -o hello
  • 在预处理中包含进头文件的内容,但头文件里的内容只有函数的声明,没有函数的定义,例如printf函数。在链接这一阶段要做的就是将二进制文件链接到函数库来实现函数。
  • 函数库位置:/usr/lib。分为静态库和动态库。
  • 静态库:编译链接时,将库文件的代码全部加入到可执行文件中。因此生成的可执行文件较大,但运行时不再需要库文件。后缀名:.a
  • 动态库:编译链接时没有把库文件加入到可执行文件中,而是在程序运行时由运行时链接文件加载相应的函数库。后缀名:.so
  • GCC在编译链接时默认使用动态库。
Last modification:2021 年 03 月 17 日 23 : 27 : 07