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在编译链接时默认使用动态库。
本文链接:https://shengto.top/linux/100.html
转载时须注明出处及本声明