Gcc编译流程分析
预处理、编译、汇编、链接
1、预处理阶段:该阶段编译器将上述代码中的stdio.h编译出来,并且用户可以使用Gcc的选项“-E”进行查看,该选项让Gcc在进行完预处理后停止下来。
.i 文件是已经过预处理的C的源程序
2、编译阶段:该阶段检查代码的规范性,是否有语法错误等,确定代码实际要做的工作,检查无误后,Gcc把代码翻译成汇编语言。可以用“-S”选项来查看,只进行编译不汇编,生成汇编代码。
3、汇编阶段:把编译阶段生成的“.s”文件转化为目标文件,可用“-c”选项查看,将汇编代码转化为.o的2进制目标代码。
4、链接阶段:设计到重要的概念函数库。Stdio.h中并没有printf()的实现,它的实现都被做到libc.so.6的库文件中去了,没有特别指定时,Gcc会在“/usr/lib”下面搜索,链接到libc.so.6,这样就实现了printf(),这就是链接的作用。
Gcc编译选项分析
Gcc有超过100个可用选项,主要包括总体选项,告警和出错选项,优化选项和体系结构选项。
一、总体选项(注意区分大小写)
-c 只编译不链接,生成目标文件“.o”。
-S 只编译不汇编,生成汇编代码。
-E 只进行预编译,不做其他处理。
-g 在可执行程序中包含标准调试信息。
-o file 把输出文件输出到file里。
-v 打印出编译器内部编译各过程的命令行信息和编译器的版本。
-I 在头文件搜索路径列表中添加dir目录 (只指定路径并没有加具体的文件名)
-L 在库文件的搜索路径列表中添加dir目录
-static 静态链接库
-librarry 链接名为library的库文件
注:在include 语句中 ”<> ”表示在标准路径中搜索头文件,””表示在本目录中搜索。头文件和库文件的关系:头文件不一定是系统提供的可以使用户自己编写的,而库文件都是系统提供的。
有一个特殊的选项“-l”,它指示Gcc去链接库文件libsunq.so由于在linux下的库文件命名时有一个规定:必须以l,i,b,3个字母开头,因此在用-l选项指定链接的库文件名时可以省去l,i,b,也就是说在对“-lsunq”进行处理时,会自动去链接Libsunq.so.
二、告警和出错选项
-ansi 支持符合ANSI标准的C的程序
-pedantic 允许发出ANSIC标准所列的全部警告信息
-pedantic -error 允许发出ANSIC标准所列的全部错误信息
-w 关闭所有告警
-wall 允许发出Gcc提供的所有有用的报警信息
-werror 把所有告警信息转化为错误信息,并在告警信息发生时,终止编译过程
三、优化选项
Gcc可以对代码进行优化,他通过编译选项“-On”来控制优化代码的生成,其中n代表优化级别,对于不同版本的Gcc来讲,n的取之范围及其对应的优化效果可能并不完全相同比较典型的是从0变化到2和3
-O 主要进行线程跳转和延迟退栈两种优化
-O2 出完成上述工作外,还进行一些额外的调整工作,如处理器指令调度
-O3 包括循环展开和其他一些与处理器特性相关的优化工作
在调试阶段最好不要进行任何优化,只有当程序最终发行时进行优化。
四、体系结构相关选项
-mcpu=type 针对不同cpu使用相应的cpu指令 i386 i486
-mieee-fp 使用IEEE标准进行浮点数的比较
-nmo-ieee-fp不使用IEEE标准进行浮点数的比较
-msoft-float输出包含浮点数库调用的目标代码
-mshort 把int类型作为16位处理,相当于short int
-mrtd 强行将函数参数个数固定的函数用 retNUM返回节省调用函数的一条指令
五、多个源文件的编译方法
1、多个源文件一起编译
用法:gcc testfun.c test.c -o test
作用:将 testfun.c test.c分别编译后连接成test可执行文件
2、分别编译各个源文件,对编译后输出的目标文件链接
gcc -c testfun,c
gcc -c test.c
gcc testfun.o test.o -o test