linux下C语言的编译原理

C语言编译详解

GCC 编译器在编译一个C语言程序时需要经过以下 4 步:

1. 将C语言源程序预处理,生成.i文件。{预编译处理(.c)}

  • a.宏定义指令:将所有的#define删除,并且展开所有的宏定义

  • b.条件编译指令:处理所有的条件预编译指令,比如#if #ifdef #elif #else #endif等

  • c.头文件包含指令:处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置

  • d.特殊符号指令:预编译器可研识别一些特殊的符号,例如:删除所有注释 “//”和”/* */”

  • e.添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号

  • f.保留所有的#pragma编译器指令,因为编译器需要使用它们

2. 预处理后的.i文件编译成为汇编语言,生成.s文件。{优化程序(.s .asm)}

  • 编译过程就是把预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码

3. 将汇编语言文件经过汇编,生成目标文件.o文件。{汇编程序(.obj、 .o、.a、 .ko)}

  • 汇编器是将汇编代码转变成机器可以执行的命令,每一个汇编语句几乎都对应一条机器指令。根据汇编指令和机器指令的对照表一一翻译即可。用一下指令进行汇编

4. 将各个模块的.o文件链接起来生成一个可执行程序文件。{链接程序(.exe、 .elf、 .axf 等}

  • 通过调用链接器ld来链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件., 链接的主要内容是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确地衔接,链接分为静态链接和动态链接。

  • 静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大。静态库文件:是一个二进制文件,存放的功能函数实现,在文件编译时要访问文件,编译之后静态库文件可以删除

  • 而动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去,动态库文件:是一个二进制文件,存放的功能函数实现,在文件执行时要访问文件,编译时不需要动态库文件

      linux动态库文件后缀名:.so
      window动态库文件后缀名:.dll
    

linux下C语言的编译原理_第1张图片
.i文件、.s文件、.o文件可以认为是中间文件或临时文件,如果使用 GCC 一次性完成C语言程序的编译,那么只能看到最终的可执行文件,这些中间文件都是看不到的,因为 GCC 已经经它们删除了。

参考文章:
文章1
文章2
文章3

你可能感兴趣的:(Makefile)