gcc/g++的四步编译

目录

  • 前言
  • 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.mzph.cn/diannao/42028.shtml

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

相关文章

技术实现路径怎么写?(Word项目技术路径文档参考)

软件项目编写技术实现路径至关重要,因为它为项目团队提供了清晰的开发蓝图。这一路径明确了从项目启动到交付各阶段所需的技术方案、步骤及预期成果,有助于团队统一认识,确保开发工作有序进行。同时,技术实现路径有助于识别潜在的…

HetuEngine简介

目录 HetuEngine是什么? HetuEngine的特点以及使用场景 特点 使用场景 HetuEngine介绍 结构 近期用到了Hetu,了解下这个工具是起什么作用的。 HetuEngine是什么? 是引擎,设计是为了让与当前的大数据生态完美融合的引擎&am…

本安防爆手机:危险环境下的安全通信解决方案

在石油化工、煤矿、天然气等危险环境中,通信安全是保障工作人员生命安全和生产顺利进行的关键。防爆智能手机作为专为这些环境设计的通信工具,提供了全方位的安全通信解决方案。 防爆设计与材料: 防爆智能手机采用特殊的防爆结构和材料&…

Mysql部署MHA高可用

部署前准备: mysql-8.0.27下载地址:https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.27-1.el7.x86_64.rpm-bundle.tar mha-manager下载地址:https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-mana…

为什么需要做网络安全服务?

网络安全服务之所以重要,是因为它在保护数字资产、维护企业运营、确保法规遵从、防范恶意行为以及建立信任等方面扮演着关键角色。以下是一些主要的理由: 保护核心资产和数据: 数字化转型使得企业数据变得极其宝贵,包括知识产权、…

深度学习模型加密python版本

支持加密的模型: # torch、torch script、onnx、tensorrt 、torch2trt、tensorflow、tensorflow2tensorrt、paddlepaddle、paddle2tensorrt 深度学习推理模型通常以文件的形式进行保存,相应的推理引擎通过读取模型文件并反序列化即可进行推理过程. 这样一来&#…

20K Stars!一个轻量级的 JS 库

大家好,我是CodeQi! 一位热衷于技术分享的码仔。 Driver.js 是一个轻量级的 JavaScript 库,旨在帮助开发人员创建网站或应用程序的引导和教程。通过 Driver.js,您可以引导用户了解网站的各个功能和使用方式。 Driver.js 提供了高度可定制的功能,使其能够适应各种需求和…

使用Python绘制和弦图

使用Python绘制和弦图 和弦图效果代码 和弦图 和弦图用于展示数据的多对多关系,适合用于社交网络、交通流量等领域的分析。 效果 代码 import pandas as pd import holoviews as hv from holoviews import opts hv.extension(bokeh)# 示例数据 data [(A, B, 2),…

印尼网络安全治理能力观察

在全国国际机场的移民服务完全瘫痪 100 多个小时后,印尼政府承认其新成立的国家数据中心 (PDN) 遭受了网络攻击。 恶意 Lockbit 3.0 勒索软件加密了存储在中心的重要数据,其背后的黑客组织要求支付 800 万美元的赎金。 不幸的是,大多数数据…

性能测试相关理解(一)

根据学习全栈测试博主的课程做的笔记 一、说明 若未特别说明,涉及术语都是jmeter来说,线程数,就是jmeter线程组中的线程数 二、软件性能是什么 1、用户关注:响应时间 2、业务/产品关注:响应时间、支持多少并发数、…

深入解析 androidx.databinding.Bindable 注解

在现代 Android 开发中,数据绑定 (Data Binding) 是一个非常重要的技术。它使得我们能够简化 UI 和业务逻辑之间的连接,从而提高代码的可读性和维护性。在数据绑定中,Bindable 注解是一个关键部分,它帮助我们实现双向数据绑定和自…

【车载开发系列】GIT安装详细教程

【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程一. GIT软件概念二. GIT安装步骤三. GIT安装确认三. GIT功能使用1)Git Bash2)Git CMD3)Git FAQs4)Git GUI 一. GIT软件概念 G…

数据库系统原理 | 查询作业1

整理自博主本科《数据库系统原理》专业课自己完成的实验课查询作业,以便各位学习数据库系统概论的小伙伴们参考、学习。 *文中若存在书写不合理的地方,欢迎各位斧正。 专业课本: ​ ———— 本次实验使用到的图形化工具:Heidisql…

云端AI大模型群体智慧后台架构思考

1 大模型的调研 1.1 主流的大模型 openai-chatgpt 阿里巴巴-通义千问 一个专门响应人类指令的大模型。我是效率助手,也是点子生成机,我服务于人类,致力于让生活更美好。 百度-文心一言(千帆大模型) 文心一言"…

MySQL基础篇(三)数据库的修改 删除 备份恢复 查看连接情况

对数据库的修改主要指的是修改数据库的字符集,校验规则。 将test1数据库字符集改为gbk。 数据库的删除: 执行完该数据库就不存在了,对应数据库文件夹被删除,级联删除,里面的数据表全部被删除。 注意:不要随…

浅识Jmeter与浅谈互联网公司高并发业务压测流程痛点

浅谈Jmeter 什么是Jmeter JMeter 是 Apache 软件基金会开发的一个开源软件,用于负载测试和性能测试。它被设计用来模拟多种请求到服务器、网络或对象,以测试其性能。JMeter 可以用于测试静态和动态资源,并且可以模拟各种协议的请求&#xf…

NDVI数据集提取植被覆盖度FVC

植被覆盖度FVC 植被覆盖度(Foliage Vegetation Cover,FVC)是指植被冠层覆盖地表的面积比例,通常用来描述一个区域内植被的茂密程度或生长状况。它是生态学、环境科学以及地理信息系统等领域的重要指标,对于理解地表能…

绝区叁--如何在移动设备上本地运行LLM

随着大型语言模型 (LLM)(例如Llama 2和Llama 3)不断突破人工智能的界限,它们正在改变我们与周围技术的互动方式。这些模型早已集成到我们的手机中,但到目前为止,它们理解和处理请求的能力还非常有限。然而,…

手写实现一个ORM框架

手写实现一个ORM框架 什么是ORM框架、ORM框架的作用效果演示框架设计代码细节SqlBuilderSqlExecutorStatementHandlerParameterHandlerResultSetHandler逆序生成实体类 大家好,本人最近写了一个ORM框架,想在这里分享给大家,让大家来学习学习。…

leetcode力扣_排序问题

215.数组中的第K个最大元素 鉴于已经将之前学的排序算法忘得差不多了,只会一个冒泡排序法了,就写了一个冒牌排序法,将给的数组按照降序排列,然后取nums[k-1]就是题目要求的,但是提交之后对于有的示例显示”超出时间限制…