前言
GCC 编译一共分4个阶段:预处理、编译、汇编、链接
gcc 指令一般格式
gcc 【选项】要编译的文件【选项】【输出文件】
选项 | 说明 |
---|---|
-E | 控制GCC编译器仅对源码做预处理操作 |
-S | 控制GCC编译器仅对指定文件处理之编译阶段 |
-c | 控制GCC编译器仅对制定文件处理至汇编阶段,并生成相应的目标文件 |
-o outfile | 指定输出文件的文件名 |
eg:下面是一段很简单的hello.c代码,以这段代码为例
#include <stdio.h>
#define NAME "mao"
void main()
{
printf("hello:%s\n",NAME);
}
一、预处理阶段
预处理
阶段主要工作是删除程序中所有的注释、处理以#
开头的命令。如:头文件的展开、宏定义的替换。
对于上面的代码#include <stdio.h>
表示引入头文件,在预处理阶段stdio.h
文件就会被加载到我的hello.c
中,而对于在代码中使用到的NAME
,就会被替换成该宏所定义的真实内容mao
,可以使用下面的命令执行预处理:生成.i
文件,linux 系统中预处理后所得文件的后缀名通常是.i
gcc -E hello.c -o hello.i
二、编译阶段
gcc
在编译阶段会对预处理后的代码进行各种检查(词法分析,语法分析,语义分析),来判断我们的代码是否符合规范,如果通过生成汇编代码(.s
结尾的文件)
注意:gcc -S
不是只能编译经过预处理后的.i
文件,它的含义是控制GCC编译器仅对指定文件处理至编译阶段
- 如果需要编译的文件是经过预处理后的
.i
文件,则GCC
编译器只需编译此文件。 - 如果需要编译的文件是
.c
或者.cpp
源文件,则GCC
编译器会对其进行预处理和编译(两步)。
gcc -S hello.i -o hello.s
三、汇编阶段
把.s
文件翻译成二进制.o
文件(目标文件)
注意:gcc -c
不是只能编处理.s
文件,它的涵义是控制GCC
编译器仅对指定文件处理至汇编阶段
- 如果指定文件为
.c
文件,则gcc -c
指令会对该文件执行预处理、编译、汇编 。 - 如果指定文件为经过预处理后的
.i
文件,则gcc -c
指令对该文件执行编译和汇编。 - 如果指定文件为经过编译后的文件,则
gcc -c
指令只对该文件执行汇编操作。
gcc -c hello.s -o hello.o
四、链接阶段
汇编阶段将代码编译成了二进制文件,还需要和系统其他组件(比如标准库、动态链接库等)结合起来才能正常运行,比如调用print函数打印,在预处理阶段也只是将“stdio.h”头文件中的申明引入进来,没有函数的实现,那怎么调用它的呢?
这就是链接的工作,链接之前都是对文件的处理,而链接是对多个文件进行打包的过程,他将所有目标文件以及系统组件组合成一个可执行文件。
gcc hello.o -o hello