gcc,一个神奇的编译器

gcc是“GNU Compiler Collection”的缩写,从字面意思可以知道它是一个编译器集。gcc不止可以编译器c语言,还能用于c++,java,object-C等语言程序。但是在这里,我们的嵌入式学习中,目前只去关注gcc在C语言方面的编译功能。

 

.什么是交叉编译器

  在嵌入式系统开发中,经常用到与交叉编译相关的术语,例如:交叉编译器,交叉连接器,交叉编译环境等。

  嵌入式产品的资源往往有限,如果它的资源和我们平时用的桌面计算机(后面称为开发主机或简称主机,host machine)一样,那就不需要交叉编译了。嵌入式系统的内存通常是几十兆字节,且只有闪存而没有硬盘这种大容量存储设备。在这种资源有限的环境中,不可能将开发工具安装在嵌入式设备中(后面称为目标机,target machine),然后像平时做桌面软件开发那样在嵌入式设备上直接进行软件开发,因此,嵌入式的开发工作一般是在主机上进行的。

  那么当目标机的处理器和主机的处理器不同时(比如目标机是ARM处理器,而主机是X86处理器),如何保证在主机上编译的程序可以在目标机上运行呢?

  当使用编译gcc时,需要指定目标机处理器和主机处理器型号,如果不加以指定,则认为主机与目标机是一样的,且与当前编译它的环境一致。如果在gcc编译时,指定主机与目标机处理器型号不一致,则生成的编译器就是交叉编译器(cross compiler),即生成的编译器将在指定主机上进行编译活动,但在编译器生成的程序却运行于目标机上。

gcc会对代码完成预处理,编译,汇编和链接四个步骤。

gcc,一个神奇的编译器

gcc,一个神奇的编译器

gcc,一个神奇的编译器

这里注意:汇编文件的后缀是s(小s)表示:在后期阶段不在进行预处理操作,所以我们不能在这里面写预处理的语句在里面;汇编文件的后缀是S(大S)表示:会进行预处理、汇编等操作,所以我们可以在这里面加入预处理的命令。

gcc实用选项:

-S:生成汇编

-I:指定头文件路径

-g:包含调试信息

-On:n=0~3,编译器优化,n越大优化等级越高

-Wall:提示更多的警告信息

-D:编译器时定义宏,注意-D和宏之间没有空格

-E:生成预处理文件

-c:只编译,不链接

-C 告诉预处理器不要丢弃注释。配合`-E'选项使用。

-M:生成与.c和头文件的依赖关系以用于Makefile,包括系统库的头文件

-MM:生成与.c和头文件的依赖关系以用于Makefile,不包括系统库的头文件

-o:生成目标文件。eg: -o filename。将经过gcc处理的结果保存为filename。如果这个选项被忽略,生成的可执行文件默认为a.out,,假设源文件为file.c,目标文件默认为file.o,汇编文件默认为file.s。

gcc -v可以查看gcc的版本信息,但是要是在gcc -v 后面加上一个源文件例如,gcc -v main.c,这样可以获得gcc所使用的系统头文件。

gcc,一个神奇的编译器

 

加上源文件选项 :

gcc,一个神奇的编译器

gcc,一个神奇的编译器

 

产生映射文件

gcc,一个神奇的编译器

gcc的-Wl选项用于指定传递给连接器的选项,-Map=main.map选项由gcc传递给连接器以只是连接器为我们生成名为main.map的映射文件。在使用-Wl选项时,如果后面的选项如有多个,则需要用逗号分开。

映射文件除了包含nm工具获取的信息外,还包含了各符号来源于哪一个库以及库中的哪一个目标文件等更为详细的信息。

 在链接选项中:

gcc,一个神奇的编译器