c++编译和链接过程


前言

.cpp :源文件
.s : 源文件的汇编代码
.o : 可重定位目标文件
.a: 静态链接库
.so: 动态链接库
.exe :可执行文件,点击即可运行


C++程序编译过程

整个编译过程分为两大步:

1)编译 :把文本形式的源代码翻译成机器语言,并形成目标文件

2)连接 :把目标文件 操作系统的启动代码和库文件组织起来形成可执行程序

3)加载

1.编译

1.1 编译预处理

预处理又称为预编译,是替换插入工作。编译器执行预处理指令(以#开头,例如#include),这个过程会得到不包含#指令的**.i文件**。这个过程会插入#include 包含的文件代码,进行#define 宏定义的替换 , 处理条件编译指令 (#ifndef #ifdef #endif)等

1.2 编译

通过预编译输出的.i文件中,只有常量:数字、字符串、变量的定义,以及c语言的关键字:main、if、else、for、while等。这阶段要做的工作主要是,通过语法分析和词法分析,确定所有指令是否符合规则,之后翻译成汇编代码。

这个过程将.i文件转化位**.s文件**。

1.3 汇编

汇编过程就是把汇编语言翻译成目标机器指令的过程,生成目标文件(.obj .o等)。目标文件中存放的也就是与源程序等效的目标的机器语言代码。

目标文件由段组成,通常至少有两个段:

代码段.text:包换主要程序的指令。该段是可读和可执行的,一般不可写

数据段:存放程序用到的全局变量或静态数据。可读、可写、可执行。

这个过程将.s文件转化成.o文件。


2.链接Linking

链接可以在三个时刻进行:并分为静态链接动态链接

编译时(compilation time),也就是在源代码被翻译成机器代码时。
加载时(load time),在程序被加载器loader加载到内存并执行时。
运行时(run time),由应用程序负责加载。

2.1静态链接

LD是静态链接器,它的输入是一组ELF可重定位目标文件和命令行参数,输出是一个完全链接的,可以加载和运行的ELF可执行目标文件。

为了构造可执行文件,静态链接器有以下任务:

1.符号解析。目标文件定义并且引用符号,每一个符号对应于一个函数,一个全部变量,或者一个静态变量。符号解析的目的是将每个符号引用和一个符号定义关联起来。
2.重定位。编译器和汇编器生成的section都是从地址0开始的,链接器通过把每个符号定义和一个内存位置关联起来,对这些section进行重定位,然后修改对这些符号的引用,使得它们指向相应的内存位置。链接器使用汇编器产生的重定位条目执行这样的重定位。

###和静态库链接
一个静态库包含多个可重定位文件,每个可重定位文件都是根据一个函数创建的。在应用时,只需要指定静态库的名字,链接器会只会复制其中被应用程序引用的目标模块

Linux中的静态库以archive(后缀名为.a)的文件形式存在

2.2可重定位目标文件

一个ELF可重定位目标文件由以下section组成:

2.3 动态链接

静态库的问题:
需要定期维护和更新,当静态库更新时,需要将引用程序和更新了的库重新链接。每一个进程都需要把这些函数复制到代码段中。
因此动态链接共享库能弥补该缺陷

共享库是一个目标模块,在运行或者加载时,可以加载到任意的内存地址,并且和一个在内存中的程序链接起来。这个过程叫做动态链接。共享库也叫作共享目标(shared object),在linux中用.so后缀,在windows中叫做DLL(动态链接库)。

共享库共享的方式:

一个库只有一个.so文件,所有引用该文件的可执行目标文件共享这个。
在内存中,一个共享库的.text节的副本可以被不同的进程共享。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值