C程序编译过程

1.概述

通常我们使用gcc来生成可执行程序,命令为:gcc hello.c,默认生成可执行文件a.out。但实际上编译包括预处理(Preprocessing),编译(Compilation),汇编(Assembly),链接(Linking)四个部分。


C程序编译过程_第1张图片
gcc_compilation_stages.jpg

2.预处理(Preprocessing)

预处理阶段gcc将hello.c转为hello.i,输入命令gcc -E hello.c -o hello.i -E 表示只进行预处理。
预处理具体过程如下:

  1. 头文件的展开:将程序中所用的头文件用其内容来替换头文件名。
  2. 宏替换:扫描程序中的符号,将其 替换成宏所定义的内容。
  3. 去掉注释:去掉程序中的注释。
  4. 条件编译:在程序中难免会有文件的重复引用,如果每次引用都要重新调用文件中的内容,这样就会增加许多不必要的开销 。所以为了防止这种情况的发生,我们在文件中使用条件编译符号来防止这种情况的发生。

3. 编译(Compilation)

编译就是把预处理完的文件hello.i进行词法分析,语法分析及优化后生成的汇编代码 gcc –S hello.i –o hello.s -S 表示预处理和编译

4.汇编(Assembly)

汇编就是将汇编代码转换为机器指令的过程。每一条汇编代码对应一条机器指令,汇编就是根据汇编指令和机器指令的对照表一一翻译即可。 gcc –c hello.c –o hello.o -c 表示进行预处理,编译,汇编。

5. 链接(Linking)

通过调用链接器ld来链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件。ld -static crt1.o crti.o crtbeginT.o hello.o -start-group -lgcc -lgcc_eh -lc-end-group crtend.o crtn.o (省略了文件的路径名)。
链接的主要内容是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接。
链接的主要过程包括:地址和空间分配(Address and Storage Allocation),符号决议(Symbol Resolution),重定位(Relocation)等。
链接分为静态链接动态链接
静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大。 静态链接就是将多个目标文件组合在一起形成一个可执行文件,如将a.o 和 b.o 链接在一起形成 可执行文件ab。

C程序编译过程_第2张图片
静态链接过程.jpg

动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去。

C程序编译过程_第3张图片
动态链接过程.png

你可能感兴趣的:(C程序编译过程)