g++ 编译四步骤

gcc 编译四步骤

主要经过四个阶段:预处理阶段、编译阶段、汇编阶段和链接阶段;

从源文件到目标文件的转化是由编译器驱动程序完成的;

linux> g++ hello.cpp -o hello

在这里,G++编译器驱动程序读取源程序文件 hello.cpp,并把它翻译成一个可执行目标文件 hello。这个翻译过程可分为四个阶段完成,如下图所示。执行这四个阶段的程序(预处理器、编译器、汇编器和链接器)一起构成了编译系统(compilation system);

g++环境搭建 :点击
来源于:库克李名

本文用 hello.cpp 为例,hello.cpp 的代码如下:

#include<iostream>
using namespace std;

int main() {
	printf("Hello wrold ! ");
	return 0;
}

预处理阶段:

预处理器( cpp )根据以字符#开头的命令,修改原始的 C++ 程序。比如hello.c中第 1行的#include < iostream > 命令告诉预处理器读取系统头文件 iostream 的内容,并把它直接插入程序文本中。结果就得到了另一个 C++ 程序,通常是以.i 作为文件扩展名;

  1. 将所有的#define删除,并且展开相关的宏定义;
  2. 处理相应的预编译条件指令,如#if、#ifdef ;
  3. 处理#include预编译指令,将被包含的文件插入到相应位置;
  4. 删掉所有注释部分;
  5. 添加行号的文件标识符;

编译阶段:

编译器( cc1 )将文本文件 hello.i 翻译成文本文件 hello.s ,它包含一个汇编语言程序。包含该程序包含函数 main 的定义等;

  1. 词法、语法、语义分析,将源代码的字符序列分成一系列的片段,然后片段进行语法分析,生成语法树,判断表达式是否正确有意义;
  2. 优化生成的代码;
  3. 将生成的代码转换成汇编代码;
  4. 优化汇编代码;
  5. 这个过程对编译器的要求很高,也体现了不同编译器的效率问题,编译过程不仅与编译有关系,还与机器的硬件条件有关系,优化过程一方面实对中间代码的优化,这部分不依赖于机器,比如删除公共表达式、循环优化、复写传播、删除无用的复制等等。还有一部分是针对所处的硬件平台进行的优化,这部分要充分考虑到硬件特性,相关和指令集的特点、相关寄存器的使用来提高效率,也是非常考验相关工程师的水平的;

汇编阶段:

汇编器( as )将 hello.s 翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序( relocatable object program )的格式,并将结果保存在目标文件 hello.o 中。hello.o 文件是一个二进制文件 。如果我们在文本编辑器中打开 hello.o 文件,将看到一堆乱码;

汇编过程是把编译后的汇编语言转换成目标机器指令而生成目标文件的过程;
目标文件最少包含代码段和数据段两个段。代码段可读可执行一般不可写,数据段一般可读可写可执行;
再win平台上一般生成.obj文件;

链接阶段:

请注意,hello程序调用了 printf 函数,它是每个 C++ 编译器都提供的标准 C++ 库中的一个函数。printf 函数存在于一个名为 printf.o 的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到我们的 hello.o 程序中。链接器( ld )就负责处理这种合并。结果就得到 hello 文件,它是一个可执行目标文件或者简称为可执行文件),可以被加载到内存中,由系统执行;

就是将不同的目标文件链接成一个可执行文件的过程;
汇编完毕的代码不能直接执行,还有许多问题没有解决:
比如源文件调用了另一个源文件中的变量或者函数;程序中可能调用了某个库中的库函数等等。这些问题都有链接来解决。
链接过程的目的就是将目标文件彼此相连接,使得他们可以连成一个整体装入操作系统执行。
根据链接方式的不同,可以分为静态链接和动态链接两种:

1.静态链接:

静态链接的过程中,函数代码会从静态库中拷贝到最终可执行文件中,这样程序在执行的时候就会把文件中的代码拷贝到该> 进程的虚拟地址空间中。这样可执行文件与静态库的文件不再联系了,删除静态库或者移到另一个环境也可以使用。静态库> 的后缀为win下 .lib ;linux下.a ;

2.动态链接

在动态链接过程中,函数的代码并不会拷贝到可执行文件中,只会在可执行文件中记录必要的定位信息,可以找到相应动态库代码的位置即可。在运行程序时,需要把动态库映射到进程的虚拟地址空间中,所以动态库和文件是相关联的,如果删掉动态库可执行文件就无法正常运行了。 文件后辍为:win下为.dll,linux下为.so;

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值