一、GCC简介
(一)含义
GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理C语言。GCC 很快地扩展,变得可处理 C++。后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective-C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。
(二)常用命令
命令 | 含义 |
---|
-E | 仅作预处理,不进行编译、汇编和链接 | -S | 仅编译到汇编语言,不进行汇编和链接 | -c | 编译、汇编到目标代码(也就是计算机可识别的二进制) | -o | 执行命令后文件的命名 | -g | 生成调试信息 | -w | 不生成任何警告 | -Wall | 生成所有的警告 |
(三)GCC编译工具
GCC编译工具链是GCC编译器的一整套工具,主要作用就是将源代码转化为可执行应用程序。
GCC编译工具链包括以下三部分:
- Gcc-Core:GCC编译器,完成预处理和编译过程,将C代码转换为汇编
- Binutils:包括了链接器ld,汇编器as,目标文件格式查看器readelf等一系列小工具
- glibc:包含C语言标准库,C中常使用的printf、malloc等函数
1.Gcc-Core
Gcc-Core主要是完成预处理和编译过程,将C代码转化为汇编语言。
2.Binutils
Binutils(bin utility),是GNU二进制工具集,通常跟GCC编译器一起打包安装到系统。在程序开发的时候,可能不会直接调用这些工具,而是在使用Gcc编译指令的时候,由GCC编译器间接调用。 全部的工具,可以通过下面的命令来查看:ls /usr/bin | grep linux-gnu-
常用工具:
- addr2line:用来将程序地址转换成其所对应的程序源件及所对应的代码行,也可以得到所对应的函数。该工具将帮助调试器在调试的过程中定位对应的源代码位置。
- as:主要用于汇编。
- ld:主要用于链接。
- ar:主要用于创建静态库。
- ldd:可以用于查看一个可执行程序依赖的共享库。
- objcopy:将一种对象文件翻译成另一种格式,譬如将.bin 转换成.elf、或者将.elf 转换成.bin等。
- objdump:主要的作用是反汇编。
- readelf:显示有关 ELF 文件的信息。
- size:列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段、总大小等。
3.glibc库
编写C语言时,所使用的read、write、open、printf等函数,都是基于该库的。在Ubuntu系统中,libc.so.6就是glibc的库文件,我们可以直接执行,查看版本信息。
二、GCC编译过程
(一)简单示例
test.c:
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
以上程序,一步到位的编译指令是:gcc test.c -o test 。 实质上,上述编译过程是分为四个阶段进行的:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)、连接(Linking)。
1.预处理
gcc -E test.c -o test.i 或gcc -E test.c 可以输出test.i文件中存放着test.c经预处理之后的代码。打开test.i文件,看一看,就明白了。后面那条指令,是直接在命令行窗口中输出预处理后的代码。 -E 命令,可以让编译器在预处理后停止,并输出预处理结果。在本例中,预处理结果就是将stdio.h文件中的内容插入到test.c中。
2.编译
gcc -S test.i -o test.s 预处理后,可直接对生成的test.i文件编译,生成汇编代码。 -S 命令,表示在程序编译期间,在生成汇编代码后,停止,-o 输出汇编代码文件。
3.汇编
gcc -c test.s -o test.o 对于上一步骤生成的汇编代码文件test.s,gas汇编器负责将其编译为目标。
4.链接
gcc test.o -o test gcc连接器是gas提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。 对于上一步骤生成的test.o,将其与C标准输入输出库进行连接,最终生成程序test。最后在命令行窗口中,执行./test ,即可得到结果。
(二)多个程序文件编译
通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用GCC能够很好地管理这些编译单元。 假设有一个由test1.c和test2.c两个源文件组成的程序,为了对它们进行编译,并最终生成可执行程序test,一步到位编译命令:gcc test1.c test2.c -o test 。 如果同时处理的文件不止一个,GCC仍然会按照预处理、编译和链接的过程依次进行。如果深究起来,上面这条命令大致相当于依次执行如下三条命令: gcc -c test1.c -o test1.o gcc -c test2.c -o test2.o gcc test1.o test2.o -o test
三、ELF文件
在计算机科学中,是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。 是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。
ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。
参考文献 https://www.cnblogs.com/ggjucheng/archive/2011/12/14/2287738.html
|