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.xdnf.cn/news/1473855.html

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

相关文章

SCI论文发表:构建清晰论文框架的10个原则 (附思维导图,建议收藏)

我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 论文框架是什么?对我们完成一篇论文有哪些作用? 之前娜姐分享过一篇深圳湾实验室周耀旗教授关于论文写作的文章,他提出的第一个重要原则就…

VScode将界面语言设置为中文

1. 点击左侧的扩展图标,打开侧边栏“EXTENSIONS”面板。 2. 在搜索框中输入“Chinese”,查找出“中文简体”插件,点击“install”按钮。 3. 等待插件安装完成,点击右下角“restart”按钮,从而重新启动Vscode。

Linux多进程和多线程(七)进程间通信-信号量

进程间通信之信号量 资源竞争 多个进程竞争同一资源时,会发生资源竞争。 资源竞争会导致进程的执行出现不可预测的结果。 临界资源 不允许同时有多个进程访问的资源, 包括硬件资源 (CPU、内存、存储器以及其他外 围设备) 与软件资源(共享代码段、共享数据结构) …

【HTML入门】第二课 - head标签下的常见标签们

目录 1 本节概要 2 head下的常见标签 2.1 网页编码设置 2.2 网页的标题 2.3 样式标签 3 head标签的内容不会显示到网页上 4 查看网页源代码 1 本节概要 上一节,我们说了HTML网页最基本的框架标签,说到标签分为head头部和body身体部分。这一小节呢…

baomidou多数据源切换注解@DS没有效果

baomidou多数据源切换注解DS没有效果 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.1.1</version> </dependency> ##原因 方法上有Transaction…

代理模式的实现

1. 引言 1.1 背景 代理模式&#xff08;Proxy Pattern&#xff09;是一种常用的设计模式&#xff0c;它允许通过一个代理对象来控制对另一个对象的访问。在面向对象编程的框架中&#xff0c;代理模式被广泛应用&#xff0c;尤其在Spring框架的AOP&#xff08;面向切面编程&am…

Mongodb oplog的作用及如何评估和更改保留时间

作者介绍&#xff1a;老苏&#xff0c;10余年DBA工作运维经验&#xff0c;擅长Oracle、MySQL、PG数据库运维&#xff08;如安装迁移&#xff0c;性能优化、故障应急处理等&#xff09; 公众号&#xff1a;老苏畅谈运维 欢迎关注本人公众号&#xff0c;更多精彩与您分享。oplog …

【论文解读】AGENTLESS:揭开基于LLM的软件工程代理的神秘面纱,重塑软件工程自动化新基线

&#x1f4dc; 文献卡 英文题目: Agentless: Demystifying LLM-based Software Engineering Agents;作者: Chunqiu Steven Xia; Yinlin Deng; Soren Dunn; Lingming ZhangDOI: 10.48550/arXiv.2407.01489摘要翻译: 大型语言模型&#xff08;LLM&#xff09;的最新进展显著推进…

Python + OpenCV 开启图片、写入储存图片

这篇教学会介绍OpenCV 里imread()、imshow()、waitKey() 方法&#xff0c;透过这些方法&#xff0c;在电脑中使用不同的色彩模式开启图片并显示图片。 imread() 开启图片 使用imread() 方法&#xff0c;可以开启图片&#xff0c;imread() 有两个参数&#xff0c;第一个参数为档…

基于顺序表的通讯录实现

一、前言 基于已经学过的顺序表&#xff0c;可以实现一个简单的通讯录。 二、通讯录相关头文件 //Contact.h #pragma once#define NAME_MAX 20 #define TEL_MAX 20 #define ADDR_MAX 20 #define GENDER_MAX 20typedef struct PersonInfo {char name[NAME_MAX];char gender[G…

Hugging face Transformers(2)—— Pipeline

Hugging Face 是一家在 NLP 和 AI 领域具有重要影响力的科技公司&#xff0c;他们的开源工具和社区建设为NLP研究和开发提供了强大的支持。它们拥有当前最活跃、最受关注、影响力最大的 NLP 社区&#xff0c;最新最强的 NLP 模型大多在这里发布和开源。该社区也提供了丰富的教程…

C++友元函数和友元类的使用

1.友元介绍 在C++中,友元(friend)是一种机制,允许某个类或函数访问其他类的私有成员。通过友元,可以授予其他类或函数对该类的私有成员的访问权限。友元关系在一些特定的情况下很有用,例如在类之间共享数据或实现特定的功能。 友元可以分为两种类型:类友元和函数友元。…

高级计算机体系结构--期末教材复习

Chap2 性能评测和并行编程性能评测并行编程为什么需要三次 barrier改进方法 Chap3 互连网络交换和路由二维网格中 XY 路由 死锁、活锁及饿死死锁避免的方法&#xff1a;虚通道、转弯模型二维网格中最小 西向优先、北向最后和负向优先算法转弯模型&#xff1a;超立方体的部分自适…

前端面试题19(vue性能优化)

Vue.js应用的性能优化是一个多方面的过程&#xff0c;涉及初始化加载、运行时渲染以及用户交互等多个环节。以下是一些关键的Vue性能优化策略&#xff0c;包括详细的说明和示例代码&#xff1a; 1. 懒加载组件 对于大型应用&#xff0c;可以使用懒加载来减少初始加载时间。Vu…

JavaWeb----JSPJSTL

目录 JSP显隐注释在JSP中写java程序JSP的指令标签JSP中的四大域对象简易版用户登录EL表达式 JSTL条件动作标签if标签 choose\when\otherwise标签迭代标签格式化动作标签 用户登录实例查看是否安装了mysql用户登录界面后台实现 JSP JSP全名是Java Server Pages&#xff0c;它是建…

电机控制杂谈——增量式的预测电流控制的优势在哪?

1.前言 前几天看到这么个问题。“模型预测控制如何消除静态误差” 评论说用增量式的预测控制。 这个回答让我想起来我大四下看的这篇论文。现在都一百多被引用了。 但是苦于当时能力有限&#xff0c;没办法复现这个文章。 所以现在想重新验证一下。 2.静态误差和电机磁链有…

[CP_AUTOSAR]_分层软件架构_内容详解

目录 1、软件分层内容1.1、Microcontroller Abstraction Layer1.2、ECU Abstraction Layer1.2.1、I/O HW Abstraction1.2.2、Communication Hardware Abstraction1.2.3、Memory Hardware Abstraction1.2.4、Onboard Device Abstraction1.2.5、Crypto Hardware Abstraction 1.3、…

Apache Seata分布式事务启用Nacos做配置中心

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Seata分布式事务启用Nacos做配置中心 Seata分布式事务启用Nacos做配置中心 项目地址 本文作…

便携式气象站:探索自然的智慧伙伴

在探索自然奥秘、追求科学真理的道路上&#xff0c;气象数据始终是我们不可或缺的指引。然而&#xff0c;传统的气象站往往庞大而笨重&#xff0c;难以在偏远地区或移动环境中灵活部署。 便携式气象站&#xff0c;顾名思义&#xff0c;是一种小巧轻便、易于携带和安装的气象观测…

VitePress美化

参考资料&#xff1a; https://blog.csdn.net/weixin_44803753/article/details/130903396 https://blog.csdn.net/qq_30678861/category_12467776.html 站点信息修改 首页部分的修改基本都在.vitepress/config.mts,这个文件内修改。 title 站点名称 description 描述 top…