预处理,编译,汇编,链接
在进行Linux开发的过程中,对GNU工具链的理解和使用是很关键的,在此以从源码到最终可执行文件的转换过程为主线,对其中使用到的工具以及过程做大致总结,以后会分别对具体使用的工具做详细介绍
GNU计划,又称革奴计划,目标是创建一套完全自由的操作系统。一个操作系统不仅仅是一个内核;它还包括编译器、编辑器、电子邮件软件,和许多其他东西。Linux与其他GNU软件结合,完全自由的操作系统正式诞生。该操作系统往往被称为“GNU/Linux”或简称Linux。
GCC(GNU CompilerCollection)是GNU组织开发的一个编译器。目前支持的语言有 C、C++、Objective-C、Fortran、Java和Ada等。GCC原本作为GNU操作系统的官方编译器,现已被大多数类
Unix操作系统(如
Linux、BSD、Mac OS X等)采纳为标准的编译器,GCC同样适用于微软的Windows。
GCC最基本的用法是∶gcc [options] [filenames]。一般高级语言程序编译的过程:预处理、编译、汇编、链接。gcc在后台实际上也经历了这几个过程,我们可以通过-v参数查看它的编译细节,如果想看某个具体的编译过程,则可以分别使用-E,-S,-c和 -O,对应的后台工具则分别为cpp,cc1,as,ld。
1.预处理
使用工具:cpp
作用:主要是C语言编译器对各种预处理命令进行处理,包括头文件的包含、宏定义的扩展、条件编译的选择等。
结果:生成作用过后的文件,即预处理命令等得到解释。
2.编译
使用工具:cc1
作用:编译之前,C语言编译器会进行词法分析、语法分析(-fsyntax-only),接着会把源代码翻译成中间语言,即汇编语言。大多数的编译程序直接产生机器语言的目标代码,形成可执行的目标文件,但也有的编译程序则先产生汇编语言一级的符号代码文件,然后再调用汇编程序进行翻译加工处理,最后产生可执行的机器语言目标文件。
结果:产生中间语言(汇编语言)的文件或产生机器语言的目标代码(可执行)。
3.汇编
使用工具:as
作用:把作为中间结果的汇编代码翻译成了机器代码,即目标代码,不过它还不可以运行。
结果:默认产生ELF格式的目标代码(可重定位)。
4.链接
使用工具:ld
作用:链接是处理可重定位文件,把它们的各种符号引用和符号定义转换为可执行文件中的合适信息(一般是虚拟内存地址)的过程。链接又分为静态链接和动态链接,前者是程序开发阶段程序员用ld(gcc实际上在后台调用了ld)静态链接器手动链接的过程,而动态链接则是程序运行期间系统调用动态链接器(ld-linux.so)自动链接的过程。
比如,如果链接到可执行文件中的是静态连接库libmyprintf.a,那么.rodata节区在链接后需要被重定位到一个绝对的虚拟内存地址,以便程序运行时能够正确访问该节区中的字符串信息。而对于puts,因为它是动态连接库libc.so中定义的函数,所以会在程序运行时通过动态符号链接找出puts函数在内存中的地址,以便程序调用该函数。
静态链接过程主要是把可重定位文件依次读入,分析各个文件的文件头,进而依次读入各个文件的节区,并计算各个节区的虚拟内存位置,对一些需要重定位的符号进行处理,设定它们的虚拟内存地址等,并最终产生一个可执行文件或者是动态链接库。
结果:产生一个可执行文件或者是动态链接库。
参考链接:编译原理 (预处理>编译>汇编>链接)