gcc编译过程可以分为四个过程:
预处理:对各种预处理命令进行处理,包括头文件的包含,宏定义,条件编译等预处理指令;
编译:对预处理完的文件进行编译,每个文件生成对应的汇编代码;
汇编:将汇编代码转换为机器代码;
链接:将所有生成的机器代码以及依赖库进行链接,生成可执行文件。
预处理
使用gcc -E 源文件
对源文件进行预处理,-E
参数表示gcc在预处理之后停止编译,为了方便查看预处理的文件,使用-o 生成的文件名
指明生成的文件名,所以使用命令:gcc -E hello.c -o hello.i
执行指令后可以看到hello.c
源文件进行了预处理,查看hello.i
,第一行#include <stdio.h>
被替换为stdio.h
文件中的内容,其它内容没有变,也没有生成别的文件。
编译预处理的文件,生成汇编文件
使用gcc -S 预处理后的文件
对预处理后的文件进行编译,并生成汇编文件hello.s
,-S
参数表示只进行编译而不进行汇编,只生成汇编文件,所以使用命令:gcc -S hello.i -o hello.s
汇编生成的汇编文件,生成目标文件
使用参数-c
将汇编代码进行汇编编译,生成二进制目标文件,使用命令gcc -c hello.s -o hello.o
链接所有的文件及库文件,生成可执行程序
注意上一步中生成的二进制目标文件只是单个源文件对应的目标文件,不是可执行程序,这个文件中还使用了标准库stdio
,所以还需要将库依赖文件进行链接,生成可执行程序(默认文件名a.out),使用命令gcc hello.o -o hello
执行可执行程序(注意main参数)
因为之前编写程序的时候我们是将 main函数传入的第一个字符串参数打印,所以在执行的时候要传入参数,使用命令./hello hello,world
参数 | 描述 |
---|---|
-E | 对源文件进行预处理 |
-S | 对预处理文件生成汇编文件 |
-c | 对汇编文件进行汇编编译,生成目标文件 |
-o | 指定输出文件名 |
使用gcc编译 —— 常用编译选项
gcc有超过100个可用选项,主要有:
- 总体选项
- 告警和出错选项
- 优化选项
- 体系结构相关选项
总体选项
参数 描述 -E
对源文件进行预处理(.i) -S 对预处理文件生成汇编文件(.s) -c 只编译不链接(或者对汇编文件进行汇编编译),生成目标文件(.o) -o 指定输出文件名 -v 打印出编译器内部编译各过程的信息以及编译器版本 -g 在可执行程序中包含调试信息
告警和出错选项
参数 | 描述 |
---|---|
-w | 关闭所有告警 |
-Wall | 允许gcc提供所有有用的报警信息 |
-Werror | 把所有告警信息转化为错误信息 |
参考链接:https://blog.youkuaiyun.com/Mculover666/article/details/84839258