GNU编译器生成目标过程的阶段:预编译、编译、汇编和链接
阶段 | 输入 | 输出 | GCC示例 |
预编译 | *.c | *.i | gcc -E test.c -o test.i |
编译 | *.i | *.s | gcc -S test.i -o test.s |
汇编 | *.s | *.o | gcc -c test.s -o test.o |
链接 | *.o | * gcc test.o -o test.o |
GCC的格式
$ gcc test.c -o test
$ gcc -c test.c
$ gcc -o image first.c second.c third.c
有用的选项
1. 例:源程序保存在./src中,头文件保存在同一等级的./inc中。可以在./src中编译文件并告诉gcc相应的头文件保存在./inc,具体如下:
$ gcc test.c -I../inc -o test
可以重复使用I格式来包含多个目录,如下所示:
$ gcc test.c -I../inc -I../../inc2 -o test
2. 可以在编译时候指定符号常量,如在源程序中或者头文件定义了符号常量
#define TEST_CONFIGRATION
可以在命令行中使用-D选项来这样子定义:
$ gcc -D TEST_CONFIGRATION test.c -o test
它的有点在于不必修改源程序就可以改变程序的行为。
编译警告
1. 最经常使用的检查普通警告的选项是-Wall,这个选项打开所有类型的警告。
$ gcc -Wall test.c -o test
2. 大多数错误选项都有一个否定形式用来将他们关掉(如果他们已默认打开或者在-Wall选项的控制下打开了)。如想打开-Wall且想关闭unused警告集可以输入:
$ gcc -Wall -Wno -unused test.c -o test
3. 选项-Werror使得编译器将所有的警告当作错误来处理。即报告错误并退出编译过程。
gcc优化
优化工作有三个个不相容的方向,选择优化时之可以选择其一:
- 将速度更快,文件更小作为目标
- 将速度更快作为目标,允许文件变大
- 将文件更小作为目标,允许程序变慢
优化等级 | 说明 |
-O0 | 不进行优化,默认等级 |
-O, -O1 | 尝试同时缩短编码时间和减小映像文件 |
-O2 | 比-O1更多的优化,但只在不导致文件增大时进行加快速度的优化,只在不导致速度变慢时进行减小文件的优化 |
-Os | 以减小结果文件为优化目标。比-O2少一个可能导致文件增大选项。 |
-O3 | 比-O2多两个优化选项。 |
架构相关的优化
指定目标结构也是可以有效改进软件性能和大小。-mcpu选项告诉编译器生成针对特定cpu类型的指令。如:
$ gcc -mcpu=pentium2 test.c -o test
调试选项
如果想用符号调试器来调试代码,可以用-g标记来指定在映像中为GDB生成调试信息。-g可以带一个参数指定调试信息的格式。如:
$ gcc -gdwarf-2 test.c -o test
其他工具
1. size给出可执行映像或者中间目标文件的大小。给出text大小(指令数),data段,bss段。如:
$ gcc main.c -o main
$ size main
text data bss dec hex filename
1038 252 8 1298 512 main
$
2. objdump可以得到有关映像更加详尽的细节
$ objdump --syms test.o // 得到映像或者目标文件中的符号列表
$ objdump --disassemble test.o // 得到目标文件中找到的函数以及gcc为这些函数分别生成的指令。
3. nm可以有助于理解目标文件中出现的符号。它列出各个符号以及根据符号的类型列出相应的细节信息。