gcc/g++的四步编译

news2024/9/22 21:18:54

目录

  • 前言
  • 1.预处理(进行宏替换)
  • 2.编译(生成汇编)
  • 3.汇编(生成二进制文件)
  • 4. 链接 (生成可执行文件)
    • a. 动态库 && 动态链接
    • b. 静态库 && 静态链接
    • c. 验证
    • d. 动静态链接的异同
  • 5. 指令总结

前言

该篇文章主要介绍 linux 平台中 gcc/g++ 编译器的使用及其编译原理(本文以g++为例),其中包括,预处理,编译,汇编,链接(着重讲述预处理和链接过程。


1.预处理(进行宏替换)

预处理阶段主要处理的工作有:去注释,头文件展开,条件编译以及宏替换。这可能是自从我们学习c语言之后,大家都铭记于心的一点。但是预处理之后,文件到底变成是什么样子??我们来做个实验

以下是我们的测试代码:

在这里插入图片描述

然后我们通过g++编译器 进行四部编译的第一步操作

[outlier@localhost dir]$ g++ -E test.cpp -o test.i
其中的 -E 作用是告诉g++编译器,编译工作截止到预处理阶段就停止
而 -o 的左边的源文件,右边是编译完成之后生成的目标文件

ok,接下来我们对比两个文件有什么区别

在这里插入图片描述

左边是预处理后的源文件,右边是我们的c++文件,我们可以看到,头文件展开后,源代码量来到1w+,同时我们代码中原本的宏定义以及注释,以及被进行宏替换和注释去除的操作了,同时对源文件进行了条件编译的处理。


2.编译(生成汇编)

[outlier@localhost dir]$ g++ -S test.i -o test.s
其中的 -S 代表截止到编译阶段

生产的汇编文件如下图:

在这里插入图片描述

3.汇编(生成二进制文件)

[outlier@localhost dir]$ g++ -c test.s -o test.o
其中的 -c 代表截止到汇编阶段

生成的二进制文件如下图:

在这里插入图片描述
生成的 .o 文件属可重定位目标二进制文件,是不可独立执行的,需要经过链接操作才能执行。

4. 链接 (生成可执行文件)

[outlier@localhost dir]$ g++  test.o -o test
其中的 -c 代表截止到汇编阶段

运行效果如下图:

在这里插入图片描述

链接操作主要的工作即为,将上述汇编阶段之后形成的可重定位目标二进制文件 和 库文件 进行链接形成可执行程序。

那么,为什么需要链接呢?

在编译过程中的预处理阶段,编译器只是将头文件拷贝到我们的源文件中,而头文件只包含了我们需要用到的各种方法的声明,并没有包括实现,而各种方法的实现恰恰就在库文件当中。所以我们需要与库文件进行链接,进而形成可执行程序。

那么链接过程是怎么样子的呢??

a. 动态库 && 动态链接

我们通过引入一个故事线进行阐述:
假设张三重生于10年代的高中时代,作为高中生的张三,非常喜欢打CF,但是又奈何家庭条件一般,家里没有电脑可以玩,于是在高中入学的时候,张三就找机会去向学长们打听到了学校附近的网吧,然后经过一番盘算,张三约了宿舍的好兄弟,计划好周末在学校留宿,然后白天去网吧跟兄弟们打CF。

于是乎,张三在周五晚上连夜制定了周末的计划:

9:00 吃早餐
9:30 语文作业
10:30 数学作业
12:00 吃午餐
13:00 午休
14:30 去网吧打CF
18:00 回学校
。。。。。。。。。。
23:30 睡大觉

接着,周六的太阳从东边缓缓升起,张三也随着计划表的时间线,从上而下去执行,除了网吧,张三计划的其它操作,都能够在学校当中完成,只有网吧打游戏的需求,学校满足不了,张三需要去网吧才能完成计划。而至于网吧在哪,张三已经提前向学长打听到了(学校南门往西500米处的)。而上完网吧后,张三便原路返回,并且随着时间线继续往下去执行自己的计划表。

那么故事就告一段路,我们可以从中类比得到:
所谓的网吧需求,也即我们的链接需求,我们的源代码中,只有头文件(方法的声明),没有库文件(方法的实现),因此我们对库文件有需求!!等价于故事性中张三可以在学校中完成除了打游戏的其它事情,打游戏需要到网吧才能完成。

再者,打游戏的可不仅仅是张三,还有张三的舍友,朋友等等,但是他们不需要去其它网吧,因为学校的网吧能够容纳学校的需求量,因此,张三打游戏也是去学校南门往西500米的网吧,张三的舍友、朋友也是去那个网吧。因此,网吧只要1个就够了,所以所谓的动态库,又称之为共享库,不是每个用户需要一个动态库,而是多个用户其实都是在使用同一个动态库,至于这个动态库在哪,等价于学长的编译器,会告诉你在哪。

一个月过去了。。。因为学校附近的网吧呼声越来越高,不小心透露到某些学生的家长耳中。家长们得知很是担忧,于是乎,家长们联合进行了一波举报。第二天,相关部门对该网吧进行一系列的检查,发现该网吧存在安全隐患等问题,对该网吧进行了封锁,停止其营业。而作为张三等人,并没有在第一时间得知,网吧被封锁了,于是在某个周末像往常一样,跟好兄弟们前往网吧打CF,到达目的地后才发现,网吧已经被封锁,无法正常使用。

而在上述的故事中,我们又能得知,所谓的网吧被封锁,导致的张三等人无法正常使用,即我们动态库有文件缺失,即无法继续正常使用,而影响的也不只是一个程序,所有程序可能都会被影响。而上述这种链接方式,即为动态链接!


b. 静态库 && 静态链接

相信理解了动态链接的大致原理之后,静态链接也就游刃有余了。

所谓静态链接无非就是,张三上了大学之后,有了属于自己的笔记本电脑,再也不需要跑到网吧去了,只需要在床上翻个身子,来到创下的桌子,即可完成张三的需求。那么类似于这种,把库文件拷贝到自己的本地电脑中,这就是静态库!编译的时候使用镜本地电脑中的库文件进行链接,这就是静态链接!


c. 验证

在这里插入图片描述

g++ test.cpp -o test_static -static			// 静态链接编译

[outlier@localhost dir]$ ll
total 2012
-rwxrwxr-x  1 outlier outlier    9024 Jul  6 17:07 test
-rw-rw-r--. 1 outlier outlier     628 Jul  6 16:44 test.cpp
-rwxrwxr-x  1 outlier outlier 1608368 Jul  6 18:24 test_static

在这里插入图片描述

从上面的图文,我们不难发现,gcc/g++ 编译器都是默认的动态链接的方式,而当我们指定了静态链接,所形成的可执行程序大小也随之变大,这个也不难理解,毕竟静态链接就相当于,我们需要把库文件拷贝到自己的源文件当中。


d. 动静态链接的异同

动态库因为是共享库,有效的节省资源(磁盘空间,内存空间,网络空间等),但是动态库一旦缺失,导致各个程序都无法运行。
静态库,不依赖库,程序可以独立运行,但是体积大,比较消耗资源(磁盘,内存)



5. 指令总结

g++ -S test.i -o test.s						// 预处理
g++ -S test.i -o test.s						// 编译
g++ -c test.s -o test.o						// 汇编
g++  test.o -o test							// 链接
g++ test.cpp -o test						// 一步编译
g++ test.cpp -o test_static -static			// 静态链接编译
g++ test.cpp -o test_debug -g				// debug编译
g++ test.cpp -o test_static_debug -static -g  	// 静态+debug编译



以上就是gcc/g++ 编译器 以及 关于动静态库的相关内容。如果感觉该篇文章给你带来了收获,可以 点赞👍 + 收藏⭐️ + 关注➕ 支持一下!
感谢各位观看!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1901548.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[leetcode hot 150]第一百三十题,被围绕的区域

题目: 给你一个 m x n 的矩阵 board ,由若干字符 X 和 O 组成,捕获 所有 被围绕的区域: 连接:一个单元格与水平或垂直方向上相邻的单元格连接。区域:连接所有 0 的单元格来形成一个区域。围绕&#xff1a…

广州佛山中山数据中心机房搬迁公司

随着数据中心的发展和迭代,必然面临数据中心搬迁。数据中心搬迁听来简单,其实涉及诸多方面,如信息迁移的安全性、业务的连续性、搬迁的规范性、方案的可行性、组织的统一性等。友力科技(广州)有限公司,自原…

女生学计算机好不好?感觉计算机分有点高……?

众所周知,在国内的高校里,计算机专业的女生是非常少的,很多小班30人左右,但是每个班女生人数只有个位数。这就给很多人一个感觉,是不是女生天生就不适合学这个东西呢?女生是不是也应该放弃呢?当…

排序——交换类排序、插入类排序、选择类排序、归并类排序

排序 排序算法分为交换类排序、插入类排序、选择类排序、归并类排序。 交换类排序 冒泡排序 冒泡排序的基本思想是:从后往前(或从前往后)两两比较相邻元素的值。若A[ j - 1 ] > A[ j ],则交换它们,直到序列比较…

软件测试与开发流程

软件测试简介 软件测试是对软件进行检测和评估,以确定其是否满足所需结果的过程和方法。它是在规定的条件下对程序进行操作,发现程序错误,从而衡量软件质量,并对其是否满足设计要求进行评估的过程。 与计算机系统操作有关的计算机…

昇思25天学习打卡营第2天|MindSpore快速入门

打卡 目录 打卡 快速入门案例:minist图像数据识别任务 案例任务说明 流程 1 加载并处理数据集 2 模型网络构建与定义 3 模型约束定义 4 模型训练 5 模型保存 6 模型推理 相关参考文档入门理解 MindSpore数据处理引擎 模型网络参数初始化 模型优化器 …

优化路由,优化请求url

1、使用父子关系调整下使其更加整洁 2、比如说我修改了下url,那所有的页面都要更改 优化:把这个url抽出来,新建一个Api文件夹用于存放所有接口的url,在业务里只需要关注业务就可以 使用时 导包 发请求 如果想要更改路径,在这里…

ReAct Agent 分享回顾

在人工智能的迅速发展中,ReAct Agent作为一项前沿技术,受到越来越多的关注。本文结合ReAct Agent 提出者的访谈内容,探讨ReAct Agent的研究背景、技术挑战、未来展望,以及它与大模型的紧密联系,分析其科研成果与商业化…

迅捷PDF编辑器合并PDF

迅捷PDF编辑器是一款专业的PDF编辑软件,不仅支持任意添加文本,而且可以任意编辑PDF原有内容,软件上方的工具栏中还有丰富的PDF标注、编辑功能,包括高亮、删除线、下划线这些基础的,还有规则或不规则框选、箭头、便利贴…

使用Docker、Docker-compose部署单机版达梦数据库(DM8)

安装前准备 Linux Centos7安装:https://blog.csdn.net/andyLyysh/article/details/127248551?spm1001.2014.3001.5502 Docker、Docker-compose安装:https://blog.csdn.net/andyLyysh/article/details/126738190?spm1001.2014.3001.5502 下载DM8镜像 …

动态颤抖的眼睛效果404页面源码

动态颤抖的眼睛效果404页面源码, 源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面 动态颤抖的眼睛效果404页面源码

【密码学】密码学五要素

密码学五要素是密码系统的基本组成部分,这五个要素共同构成了密码系统的框架。在实际应用中,密码系统的安全性依赖于密钥的安全管理以及算法的强度。 如果任何一方被泄露或破解,那么整个密码系统都将面临风险。因此,在设计和使用密…

关于多人开发下git pull报错代码冲突问题的解决方案

关于多人开发下git pull报错代码冲突问题的解决方案 问题描述 最近多人开发项目习惯性先 git pull 来更新代码的时候,遇到了下面的问题:error: Your local changes to the following files would be overwritten by merge: Please, commit your change…

医疗器械FDA | FDA如何对医疗器械网络安全认证进行审查?

FDA医械网络安全文件出具​https://link.zhihu.com/?targethttps%3A//www.wanyun.cn/Support%3Fshare%3D24315_ea8a0e47-b38d-4cd6-8ed1-9e7711a8ad5e FDA对医疗器械的网络安全认证进行审查时,主要关注以下几个方面,以确保医疗器械在网络环境中的安全性…

vulhub靶场之DEVGURU:1

1 信息收集 1.1 主机发现 arp-scan -l 发现主机IP地址为“192.168.1.11 1.2 端口发现 nmap -sS -sV -A -T5 -p- 192.168.1.11 发现端口为:22,80,8585 1.3 目录扫描 dirsearch -u 192.168.1.11 发现存在git泄露 2 文件和端口访问 2…

力扣5----最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串 示例 1: 输入:s "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。示例 2: 输入:s "cbbd" 输出…

嵌入式通信协议全解析:SPI、I²C、UART详解(附带面试题)

目录 一、什么是通信 二、 通信的分类 同步通信(Synchronous Communication) 异步通信(Asynchronous Communication) 不同协议标准区分图: UART UART的特点: UART的通信过程: UART的配置…

Linux多进程和多线程(四)进程间通讯-定时器信号和子进程退出信号

多进程(四) 定时器信号alarm()函数示例alarm()函数的限制定时器信号的实现原理setitimer()函数setitimer()和alarm()函数的区别 setitimer() old_value参数的示例 对比alarm()区别总结: 子进程退出信号 示例: 多进程(四) 定时器信号 SIGALRM 信号是用来通知进程…

ctfshow web 36d 练手赛

不知所措.jpg 没啥用然后测试了网站可以使用php伪达到目的 ?filephp://filter/convert.base64-encode/resourcetest/../index.<?php error_reporting(0); $file$_GET[file]; $file$file.php; echo $file."<br />"; if(preg_match(/test/is,$file)){inclu…

统一视频接入平台LntonCVS视频监控平台具体功能介绍

LntonCVS视频监控平台是一款基于H5技术开发的安防视频监控解决方案&#xff0c;专为全球范围内不同品牌、协议及设备类型的监控产品设计。该平台提供了统一接入管理&#xff0c;支持标准的H5播放接口&#xff0c;使其他应用平台能够快速集成视频功能。无论开发环境、操作系统或…