gcc/g++是编译系统的驱动程序,负责解析输入的参数。
依次调用预处理器(cpp)、编译器(ccl/cclplus)、汇编器(as)、链接器(ld),
执行四个阶段,最终生成可执行文件。
gcc把 .c程序文件当C代码处理(ccl编译)。
g++把 .c程序文件当作 C++ 处理(cclplus编译)。
对于 .cpp程序文件,gcc和 g++ 处理过程没有区别。
gcc不能直接编译 C++ 程序的,需要加上-lstdc++。
g++可以直接编译C++程序,g++相当于是对gcc的封装。
工具:预处理器 cpp
将源代码转换为预处理文件,生成.i或者.ii文件
工具:编译器 ccl/cclplus
将预处理文件转换为汇编文件,生成.s文件
工具:汇编器 as
将汇编文件转换为目标文件,生成.o文件(二进制文件)
工具: 链接器 ld
将目标目标文件链接为可执行文件,生成.out文件
源文件 预处理文件 汇编文件 目标文件 可执行文件
.c /.cpp ===> .i/.ii ===> .s ===> .o ===> .out预处理 编译 汇编 链接预处理器cpp 编译器ccl/cclplus 汇编器as 链接器ld
GCC编译过程
在介绍GCC编译步骤之前,首先需要了解GCC支持的后缀文件类型。
.c 是C程序文件。
.c/.cc/.cxx是C++程序文件。
.i 预处理后的C程序文件,.ii 预处理后的C++程序文件。
.s/.S 是汇编语言程序。
.h 是头文件。
.o 是目标文件。
.a 是静态库文件
.so 是动态库文件。
GCC编译流程分为四个步骤:
预处理(生成.i/.ii文件)、编译(生成.s/.S文件)、汇编(生成.o文件)、链接(生成.out文件)。
gcc指令的一般格式为:
gcc [选项] 要编译的文件 [选项] [目标文件]
其中,目标文件可缺省,gcc默认生成可执行的文件为a.out
#include
int main()
{printf("Hello World\n");return 0;
}
对于该阶段,gcc将stdio.h文件中的代码包含进这段程序,
我们可以利用
gcc -E test.c -o test.i
命令来生成预处理过的.i文件。
-E选项代表让gcc在预处理阶段后停止编译。
test.i文件中的内容如下所示,可以看出stdio.h文件中的内容被展开。
extern int fprintf (FILE *__restrict __stream,__const char *__restrict __format, ...);......# 8 "test.c" 2
int main()
{printf("Hello World\n");return 0;
}
该阶段主要是对预编译后的.i文件编译,生成汇编文件(.s文件)。
gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作。
在检查无误后,gcc把代码翻译成汇编语言。
我们可以使用-S选项来进行查看,该选项只进行编译而不进行汇编过程,生成汇编代码。
我们可以利用
gcc -S test.i -o test.s
命令进行编译过程。
test.s文件中的内容如下所示。
.file "test.c".section .rodata
.LC0:.string "Hello World".text
.globl main.type main, @function
main:pushl %ebpmovl %esp, %ebpandl $-16, %espsubl $16, %espmovl $.LC0, (%esp)call putsmovl $0, %eaxleaveret.size main, .-main.ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-16)".section .note.GNU-stack,"",@progbits
该阶段是将编译后的.s文件转化成二进制文件.o的过程
利用-c选项就可以生成二进制.o文件。
我们可以利用
gcc -c test.s -o test.o
命令生成二进制代码。
该阶段主要将成功编译的二进制文件进行链接操作,生成可执行文件。
利用
gcc test.o -o test.out
命令生成可执行文件test.out。
运行./test.out即可打印出hello world。
总结一下:
gcc -E test.c -o test.i 把原代码交给cpp预处理器生成预处理文件(test.i文件)
gcc -S test.i -o test.s 把经过预处理之后的test.i文件交给编译器cc1生成汇编文件(test.s文件)
gcc -c test.s -o test.o 把经过编译后汇编文件test.s交给as进行汇编,生成目标文件(test.o文件)
gcc test.o -o test 把as汇编之后的目标文件test.o交给ld链接成一个可执行文件(test.out文件)