概述
GCC 和 gcc 的区别
GCC (GNU Compiler Collection),故名思义它是一个编译器的集合,GCC 不仅能用于c/c++ 的程序还能用于其他的编程语言,(比如 Java ,只是后面 Java 开源了,他的支持由 Linux 官方来支持了)。gcc 是 GCC 里面的 C 语言编辑器。
交叉编译
嵌入式产品的资源常常是有限的,因此不可能将开发工具安装到嵌入式设备中,然后向桌面软件那样直接在嵌入式设备上面软件开发。因此嵌入式设备的开发工作是在主机执行的,当完成过后通过特定的工具生成能在目标机上运行的可执行程序,在下载到目标机。当主机和目标机的处理器型号不一样,但是要在其他的处理器上编译另一个处理器就用到了交叉编译器。
gcc 幕后的工作
gcc 通过 预处理(preprocessing),编译(compilation),汇编(assembly),链接(linking)四个步骤,将 C 语言转换成可执行的程序。预处理的命令是将展开源文件里面的所有宏定义,比如 #include xxx ,#define 等会将里面的内容替换成具体的内容。预处理结束后的文件会被 gcc 的 cc 工具调用对其进行编译。编译通俗的讲是完成一定的翻译工作,将一种格式转换成另一种格式。当 C 程序被编译成汇编程序的时候,C 语言的语法会被转换成汇编语言中的相应的元素,在汇编的语言中不会出现关于C语言方面的踪迹。然后gcc 使用as 汇编器转换成目标文件(这时候的目标文件只包含符号信息)。最后 gcc 使用 ld 工具就各个文件和库进行连接生成可以执行的目标文件。
gcc的使用技巧
命令的选项的作用常常会被我们忽略,但是在软件开发的过程中如果掌握一些命令将提高解决问题的效率能帮助我们探索更加深层的知识。下面会讲一些常用的使用方法。
- 解决宏错误
通过使用-E选项,可以获得gcc对.c文件完成预处理后的结果。
- 辅助编写汇编程序
写汇编程序时先使用c语言编写实现相应功能的函数,然后通过使用gcc获得函数所对应的汇写汇编程序时先使用c语言编写实现相应功能的函数,然后通过使用gcc获得函数所对应的汇编代码,再在此基础上做一定的修改, 那将极大地简化汇编程序的编写工作。通过使用gcc的-s参数能获得一一个C源程序文件的汇编程序。
使用-S参数时,我们可以根据需要使用-O优化选项。从gcc_S.s 的内容可以看出,"This is a gcc -s test\n”这个字符串是放在.rdata段的。看来获得C程序对应的汇编代码还有助于我们了解C语言实现方面的细节。
- 获取系统文件的路径
在某些情形下,我们需要知道gcc所使用的系统头文件路径。系统头文件是指C语言本身和操作系统相关的头文件。静态分析工具就需要告之系统头文件路径。通过使用gcc的-v选项就可以获取系统头文件路径,如图。其中列出“search list"就是指系统头文件路径。
- 产生映射文件
gcc 的 -WI 选项用于指定传递给链接器的选项, -Map: ***.map 选项由 gcc 传递给链接器以指示链接器为我们生成名为 ***.map 的映射文件。在使用 -Wl 选项时,它后面的选项如有多个,则需用逗号加以分割。映射文件中除了包含 nm 工具所获取的信息外,还包含各符号来源于哪一个库及库中的哪一个目标文件等更为详细的信息。
查看文件内的内容
- 通过选项定义宏
除了使用#define指令在源文件中定义宏外,还可以在编译-个源文件时通过使用-D选项定义宏。
- 生成依赖关系
从图中的显示结果可以看到,gcc 输出了main.c 所包含的所有文件,其中一部分 是直接包含的,而另一部分是间接包含的。被包含的文件分成两类:一类来自系统头文件,比如_ _ansi.h、newlib.h等;另一-类来自我们所开发的项目,比如这里的main.h和foo.c.由于系统头文件在绝大多数情形下是不会改变的,因此在构造make所需的依赖关系时不必将它们纳入其中。通过使用-MM选项,可以让gcc生成不包含系统头文件的依赖关系。(这经常在 makefile 里面用到)
- 指定链接库
当一个可执行程序的生成需要使用其他的库时,需要在链接时加以指定,这就要用到 gcc 的 -L 和 -1 选项。
TIPS
在 gcc 进行程序链接的时候依赖关系需要从左向右进行指定。gcc的这种奇怪特性造成当依赖关系比较复杂时需要对同一个库在不同的位置指定多次,否则就会出现无法成功链接的情形。
总结
目前不知道要总结什么,好好想想在补充。