深度剖析“GCC编译器编译过程”
(这张图是本人画的并非网络图,如果有编译过程没有提到的可以提出来)
首先说说第一步
一.预编译
1.配置编译器环境
编译器在编译之前要运行配置文件通常叫configure的配置文件,一般这个配置文件是由autoconf生成!
autoconf简介:
autoconf是由GNU组织开发的,autoconf的作用是能检查当前系统环境配置,包括分析一些软件包的依赖属性,并生成configure配置文件!
该配置文件是采用shell脚本格式所编写的,也就是说autoconf所生成的配置文件不需要用autoconf才能读取,只要能够读取shell脚本代码的程序都可以读取!
通过读取configure文件获取一些系统环境变量配置,编译参数,确保能在不同的系统环境下编译出的程序能正常运行!
2.头文件预编译
这里说的头文件编译不是编译头文件,众所周知头文件本身是不会参与编译的,真正参与编译的是.c/.cpo文件,头文件会被拷贝到.c/.cpp文件里一同编译,编译器通过.c/.cpp文件里的#include确定头文件位置并把头文件里面的声明或者变量定义全部拷贝到.c/.cpp文件里由一同编译并生成pch(编译好的代码),pdb(程序数据库文件)文件,通常一些使用imprt加载进来的dll,tld也会一同编译下次编译时会直接使用这个编译结果。这样做大大提高了编译效率,但是要保证更新.h/.cpp文件后一定要重新预编译不然编译器会使用上一次的编译结果。
这个步骤做不做是由程序员决定的,有些IDE会自动做这一步骤提高编译速率!而且IDE会检查如果.h/.c文件被更改会自动重新预编译生成新的pch文件保证不会使用旧的编译结果!
同时在这一步也确定了头文件的依赖关系。
3.宏替换,条件编译
这一步编译器会把用#define定义的宏变量替换成定义值,并做条件编译判断哪些代码要编译哪些代码不需要编译!
4.删除注释
编译器会把源文件中带//,/*符合开头的十进制字符串全部删除!
同时也会删除源文件中额外的空格包括换行缩进!
5.词法分析
词法分析器通常是基于有限状态自动机!同时词法分析器也支持正则表达式!
词法分析器主要作用就是把源文件里的字符(不是用双引号扩起来的字符串)一个一个从左到右的读取到源程序的字符流中并将读取到词法分析器的输入缓冲区里并单词化,例如 int a = 0;那么词法分析读取并分析之后则得到如下信息
int 整形变量声明
a 标识符
= 赋值语句
0 数字
; 语句结束
保存到自己输入缓冲区里供语法分析器调用!一般情况下词法分析器是以函数形式存在的以便语法分析器调用!
词法分析器还会对单词进行分类那些是关键字那些是合法的标识符,这些都是通过正规则表达式来匹配给出!
二.编译
1.语法分析
语法分析器通过调用词法分析器获取词法分析器字符流里的单词符号并抽象的构建成一个语法树得到中间代码开始从左到右的的开始检查是否有语法错误或者表达式错误!一旦发现有错误的语法或者表达式那么语法分析器会生成一个表格来存放第几行的代码发生了什么错误,并在检查完之后把表格里到错误信息输出到屏幕上!有的编译器在发现错误时可以自己更正不过是简单的语义错误!
2.代码优化
代码优化器有两种一种是会对语法分析器分析后的中间代码进行优化调整,另外一种是对汇编生成之后的目标代码进行优化调整!
3.汇编
会把源文件里的代码翻译成汇编指令!不同的系统使用的汇编指令不同!比如Linux和Windows所使用的汇编指令集不同,而且不同的CPU所使用的汇编指令集也是不同的!所以编译器会检查你的CPU所使用的指令集翻译成不同的汇编指令集!
三.汇编
1.将汇编指令转换成二进制数据
这一步会将汇编指令翻译成二进制数据!并且把代码文本(双引号扩起来的字符)一并翻译成二进制!
四.链接
这一步会对一些动态库,静态库以及其它相关文件进行链接,比如printf存放于printf.o文件里那么编译器要把peintf.o和源文件进行链接合并生成可执行文件!
注意本篇博客仅针对GCC编译器,其他编译器编译过程可能略有不同但是编译过程都是差不多的!
深度剖析“GCC编译器编译过程”相关推荐
- 【gcc/g++】1.编译器, 编译过程和基本参数
"木叶飞舞之处" 一, gcc编译器 二, gcc的编译过程 1--完整版 1. 预处理 2. 编译 3. 汇编 4. 链接: 2--简化版 简化编译过程 3--编译完成 三, g ...
- vs编译器 printf 控制台输出_【语言教程】通过语言了解GCC编译器工作过程
通过c语言了解GCC编译器如何工作的 比特 下面是c语言初学必看的打印helloworld #include int main(){ printf("hello, world\n" ...
- Linux下Gcc 的编译过程
在linux下开发难免会用到gcc编译.GCC(GNU Compiler Collection.GNU编译器套装),是由 GNU 开发的编程语言编译器.它是GNU编译器套装以GPL许可证所发行的自由软 ...
- GCC/G++编译过程
GCC编译过程 # 编写一个最简单的C++程序 $ cat hello.cpp int main() {return 0; }# -v选项可以打印出详细的编译过程,以及编译命令. $ gcc -v - ...
- linux下gcc的编译过程详解
Linux系统下的Gcc(GNU C Compiler)是GNU推出的功能强大.性能优越的多平台编译器,是GNU的代表作品之一.gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一 ...
- GCC的编译过程以及其同盟成员和ELF文件的分析
文章目录 一.GCC的同盟成员介绍 1.GCC的介绍 2.同盟成员之Binutils 3.同盟成员之C 运行库 二.GCC的详细编译过程 1.编译的简介 2.预处理(Preprocessing) 3. ...
- Linux 的GCC的编译过程及方式
GCC的使用 文章目录 GCC的使用 前言 一.编译过程分析 二.Linux中的编译链接 1.1 预编译阶段 1.2 编译阶段 1.3 汇编阶段 1.4 链接阶段 1.5 补充 二.编译链接命令 三. ...
- Keil5配置GCC编译器编译STM32工程
Keil一般使用ARMCC编译MCU工程代码.偶然听说Keil也是支持内嵌GCC编译器的.于是尝试了网上博客所述的一些方法,最终找到了一篇博客 http://blog.csdn.net/lan1205 ...
- Keil5.15使用GCC编译器编译STM32工程
一.下载GCC编译器 GCC编译器下载地址 二.安装GCC 我们可以把GCC解压到keil的安装目录下面.如下图 1 2 三.配置Keil使用GCC编译器 1.配置CC编译规则,Misc Contr ...
最新文章
- 路由器、路由与路由表
- 汽车保险解读:解析涉水损失险与自燃险
- html标签属性%= %,HTML标签属性集合
- P6800-[模板]Chirp Z-Transform【NTT】
- 集合框架(一) ----------Map集合遍历的方法
- 在eclipse中安装svn插件
- js基础之---slice()
- web myeclipse为什么连接不上css_Web技巧 (03)
- ios block常见的错误(二)——循环引用
- cad2007错误1308 html,win7系统安装CAD2008提示“错误1308,源文件未找到“的解决方法...
- fei 正则表达式_正则表达式 匹配 中文/日文/韩文
- 人生感悟-人生需学会放下
- 街头篮球服务器位置,求街头篮球各个服务器IP地址
- 三月写给沉默王二的一封道歉信
- Android WiFi热点监听
- 直播知识点实录|百度大脑EasyDL产业应用系列 安全生产专场
- Deepin安装向日葵报错
- 痛失阵地,又一家热门BT种子观影网站关停
- kirin710f是什么处理器_我告诉你kirin710f是什么处理器
- 数据库管理工具哪个好?强力推荐Navicat Premium 16 mac中文版
热门文章
- leach协议c++代码_入门教程4:教你STM32F407标准库移植机智云代码(控制LED灯)
- python利用什么写模板_利用python自动生成verilog模块例化模板
- oracle主键重复异常捕获,Oracle异常处理异常处
- linuxmove命令_linux中mv命令使用详解
- linux克隆后没有eth0,解决linux机器克隆后eth0不见的问题
- 安装python多少内存_Python进程使用的全部内存?
- docker build -t_利用Dockerfile自定义镜像-图解轻松学Dockeramp;K8S
- ftp 访问mysql6,RedHat6.5开启ftp访问已有目录方法
- python django mysql_Python之模块、函数和缩进
- mysql 报500错误_java 项目开启mysql binlog参数后报500错误: