【Linux学习笔记】代码编译工具gcc/g++

  • 1. 程序的翻译
    • 1.1. 预处理
    • 1.2. 编译
    • 1.3. 汇编
    • 1.4. 链接
  • 2. 动态链接和静态链接
    • 2.1. 动态链接
    • 2.2. 静态链接
    • 2.3. 动态链接和静态链接的区别
    • 2.4. 动态链接和静态链接的验证
  • 3. make/makefile
    • 3.1. 依赖方法和依赖关系
    • 3.2. 写一个makefile文件
    • 3.3. PHONY的意义
    • 3.4. makefile的推导规则
  • 4. Linux下的第一个小程序
    • 4.1. 缓冲区概念
    • 4.2. 小程序代码

1. 程序的翻译

在Linux中,gcc/g++是一个c/c++编译器。下面我们从程序的翻译过程来了解gcc工具的应用。程序的翻译分为以下的4步:

  1. 预处理
  2. 编译
  3. 汇编
  4. 链接

1.1. 预处理

程序翻译的第一步,就是做预处理工作。在Linux中,我们可以利用gcc创建一个文件来查看预处理的过程。

命令: gcc -E 文件名 -o 你想取的文件名

功能:翻译一个文件,当做完预处理阶段,就停下来。 -o选项是生成临时的文件。

示范:

img

其中,我们要知道程序翻译的过程中,预处理部分是做了什么工作的?

  • 程序的预处理:
  1. 头文件展开
  2. 去注释
  3. 宏替换
  4. 条件编译

那么我们知道了预处理是做了以上工作的,我们来打开test.i文件看看是不是这样的?

img

img

我们可以看到,通过gcc工具,输入相应的指令,我们可以看到程序翻译的预处理部分。

1.2. 编译

编译的工作主要是把C语言转换成相应的汇编语言。下面我们通过gcc工具来看一看过程。

命令: gcc -S 文件名 -o test.s

功能: 从现在开始,进行程序的翻译,做完编译工作,变成汇编之后,就停下来。

示范:

img

打开新形成的文件,我们可以看到里面的一些汇编代码。

img

1.3. 汇编

汇编这一步的主要功能就是将汇编代码变成二进制文件(不可执行)。

命令: gcc -c 文件名 -o test.o

功能:从现在开始,进行程序的翻译,完成汇编工作后,形成一个不可执行的二进制文件

示范:

img

打开test.o文件,我们可以看到里面的内容。

img

1.4. 链接

链接这一过程结束后,就形成了可执行程序(可执行的二进制程序)。主要内容就是库 + 你的代码。

命令: gcc 文件名 -o 你想取的文件名

功能:将汇编的文件与库链接,形成可执行的二进制程序。

示范:

img

通过执行该文件,我们可以相当于完成了程序的翻译。

img

2. 动态链接和静态链接

2.1. 动态链接

在日常的一天,你对自己接下来的一整天都做了一份计划,例如,吃早餐,看书,看剧,…

你是一名高中生,家里没有电脑,但是你这时候给自己的安排是打电脑游戏。那怎么办呢?

办法当然是去网吧咯,在网吧里,里面的机子都可以满足你对电脑的需求。

那么把角度切换回程序的世界。你对你接下来的一整天都做好的计划就是你的程序,当你的程序运行到打电脑游戏的时候,你才会动身去网吧使用电脑。

就好像你的代码需要某个功能的实现,例如打印,刚好库里printf就能实现你的需求。

这个动态就类似让你动起来。

img

其中你是怎么知道网吧的位置呢?那肯定是找人问的咯。同样的,切换回程序的世界,程序是怎么知道库的存在呢?答案是编译器的存在,编译器可以认为是你找网吧时问的那个人,通过那个人你找到了网吧,程序通过编译器找到了标准库。

2.2. 静态链接

回到上面的例子,某一天父母发现你对电脑的需求,所以在家里给你配了一台电脑,从此以后你用电脑的时候就不再需要跑去网吧了,而是在家使用电脑。切换回程序的世界,当你自己亲手写了一个函数,当你的程序运行到某一步时,就不需要调用标准库里的函数,而是直接可以使用你写的代码。

img

2.3. 动态链接和静态链接的区别

  • 动态链接
  1. 如果一个网吧要升级,你觉得你还能去上网吗?答案肯定是不能的。同样的道理,如果一个库要升级,你就不能使用这个库的代码了。
  2. 如果网吧被取缔了,那么你就没得上网咯。同样的,如果一个库被取缔,你也不能使用这个库的代码了。
  3. 从你家里到一家网吧是需要一段路程的,那么也就是说是要花费时间的。同样的,动态链接也是需要时间的。

动态链接的优势:

  1. 形成的可执行程序小,主要体现在内存,磁盘,网络方面。如果你的软件程序体积小,那么内存加载就会快;同样的在磁盘中所需要占用的空间也小;同样的网络上下载文件,如果体积小,那么下载的速度也会快很多。就好比你去网吧,在电脑方面上的东西,你基本都不用带,人过去就行;切回代码的角度,就是你直接调用库代码即可。
  • 静态链接
  1. 家里有电脑,我根本就不关心网吧要不要升级。同样的,我自己写了一个代码,跟库里的一模一样,那么我就用自己的代码就好啦。
  2. 网吧被取缔了,机器都没了,但是与我无关,因为我有家里的电脑。如果因为某些原因,不小心把库给删除了,我依旧能用我的代码。
  3. 时间问题,由于我家里有电脑,我根本就不需要出门,所以时间上的花费就少了很多。

静态链接的优势:

  1. 不受库的影响,种种优点就是上面所说的。但缺点也明显,就是形成的可执行程序体积太大!

2.4. 动态链接和静态链接的验证

  1. 动态库在Linux下的命名

一般是libXXXXXX.so,其中lib是前缀,.so是后缀,去掉前缀和后缀,中间的就是库的名称。

  1. 静态库在Linux下的命名

一般是libXXXXXX.a,其中lib是前缀,.so是后缀,去掉前缀和后缀,中间的就是库的名称。

  1. 使用ldd + 文件名即可查看你文件中的代码使用了哪个库。

动态链接的验证

file + 可执行程序的文件名即可查看文件的链接方式。

img

其中你也可以在使用gcc工具对文件进行编译的时候,指定文件使用静态链接。操作如下:

img

img

3. make/makefile

make是一个命令,makefile是一个文件。

用一个例子来解释,就好比厂里有一台机子,你在操作台上面提前设置好动作,让机器实现自动化。

切换会代码的角度,就是创建好一个makefile文件,里面的内容是关于你接下来的动作,例如编译代码。

img

img

makefile文件中的指令:

img

3.1. 依赖方法和依赖关系

用生活中的例子来解释,假如你是一个学生,你生病了要请假,那么就要向班主任说明你的情况并作出申请,然后班主任同意了即可请假离校。其中学生和班主任是依赖关系,你一个学生总不能向你的好基友请假吧。所谓的依赖方法就是请假的程序,向班主任申请,班主任同意,离校…

切换回代码的角度,我要形成可执行程序,我要依赖源文件。依赖方法就是我接下来要怎么做,其中上图的依赖方法可以看到,我是要用gcc工具来编译形成可执行程序。

3.2. 写一个makefile文件

如何编写一个makefile文件呢?

  1. 在第一行中,冒号是关键(:) ,冒号的左边是形成的目标文件,冒号的右边是依赖文件(可有可无)
  2. 在接下来的第二行,先有一个table的间隔,然后开始编写依赖方法。
  3. 如图所示:

img

img

3.3. PHONY的意义

我现在写好了一个伪目标makefile文件如下:

img

上面的test没有用PHONY修饰,那么只要vim里面的代码没有任何改动,那么make命令就不会执行。如下:

img

但是用了PHONY修饰的指令,会一直执行。如下:

img

我把test也加上PHONY修饰。

img

执行make命令如下:

img

那么g++是怎么知道文件到底更没更新呢?先来认识一下文件的三个时间

img

其中make命令就是根据依赖的文件与目标文件形成时间的先后来判断是否需要更新。

3.4. makefile的推导规则

首先我们看到上面的makefile的文件内容是直接生成可执行程序的,但是可执行程序是怎么来的呢?同样的也是经过程序的翻译才能得到的可执行程序。所以根据刚才所说的,我们可以知道实际的makefile内容应当是这样的:

img

  1. 先依赖test.o文件,但是没有,所以进入到下一层找
  2. 依赖test.s文件,没有,进入下一层
  3. 依赖test.i文件,没有,进入下一层
  4. 依赖test.c文件,有,形成test.i文件
  5. 形成test.i文件后,逐一返回上层执行命令。

img

一句话总结,你可以理解为是数据结构中的栈结构,也就是先进后出。

4. Linux下的第一个小程序

4.1. 缓冲区概念

下面来看两个代码

img

img

其中代码的不同就是少了一个换行符,在语言层面,换行符其实就相当于行缓冲。

第一个代码因为有了行缓冲,所以printf里面的内容直接被刷新。所以是先打印内容,再等待2s。

第二个代码因为没有行缓冲,所以printf里面的内容没有直接被刷新,而是先等待2s,然后再从缓冲区里面打印出来。

4.2. 小程序代码

利用上面的缓冲区概念,我们可以利用这个特性,做出一个倒计时的小程序。

1 #include "process.h"2 void Process()3 {4     char s[NUM];5     memset(s,'\0',sizeof(s));6     int cnt = 0;7     char ch[4] = {'|','\\','/','-'};8     while(cnt <= 100)9     {10         printf("[%-100s][%d%%][%c]\r",s,cnt,ch[cnt%4]);                                                                                                             11         fflush(stdout);12         s[cnt++] = STR;13         usleep(50000);14     }15     printf("\n");16 }

效果可以自行运行代码查看,很有趣的小程序。

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

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

相关文章

无人机电力巡检:国网安徽实际案例解析

在科技快速发展的今天&#xff0c;传统行业正在经历前所未有的转型。电力巡检&#xff0c;这一看似传统且乏味的任务&#xff0c;却因为无人机技术的介入而焕发新生。今天&#xff0c;让我们深入了解一个具体的案例&#xff0c;探索无人机如何革新电力巡检。 案例背景&#xff…

【Machine Learning】03-Unsupervised learning

03-Unsupervised learning 3. Unsupervised Learning3.1 无监督学习&#xff08;Unsupervised Learning&#xff09;3.1.1 聚类&#xff08;Clustering&#xff09;3.1.2 K-均值聚类算法&#xff08;K-means Clustering&#xff09;3.1.3 高斯分布&#xff08;Gaussian distrib…

深度学习入门(一)之感知机

文章目录 前言什么是感知机简单的逻辑电路与门与非门和或门 感知机的实现简单的实现导入权重和偏置 感知机的局限性异或门线性和非线性 多层感知机已有门电路的组合异或门的实现 代码合集 前言 感知机是由美国学者1957年提出来&#xff0c;作为神经网络的起源算法。因此学习感…

新增Node.js运行环境、新增系统缓存清理功能,1Panel开源面板v1.7.0发布

2023年10月16日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.7.0版本。 在这个版本中&#xff0c;1Panel新增Node.js运行环境&#xff1b;新增系统缓存清理功能&#xff1b;应用安装时支持选择远程数据库。此外&#xff0c;我们进行了40多项功能更新和…

阿里云云服务器实例使用教学

目录 云服务器免费试用 详细步骤 Xshell 远程连接 云服务器免费试用 阿里云云服务器网址&#xff1a;阿里云免费试用 - 阿里云 详细步骤 访问阿里云免费试用。单击页面右上方的登录/注册按钮&#xff0c;并根据页面提示完成账号登录&#xff08;已有阿里云账号&#xff09;…

配置hpa后,target显示<unknown>/50%

背景&#xff1a; 有两个服务&#xff0c;server 负责主要后端请求&#xff0c;bill 负责计量计费请求。服务都是使用 helm 部署。测试提了一个缺陷&#xff0c;说全部服务没有配置hpa。 解决一 按照之前的代码结构添加了hpa后&#xff0c;发现&#xff1a; ➜ kubectl get…

软件外包开发团队人员构成

软件外包开发团队的人员构成可以因项目的规模、类型和要求而有所不同。通常&#xff0c;一个典型的软件外包开发团队可能包括以下关键角色&#xff0c;每个角色都有要完成的工作。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 项目经…

playwright: local variable ‘page‘ referenced before assignment

安装好playwright后&#xff0c;运行相关程序出现此错误&#xff0c;按照下述链接中的方法安装相关组件和浏览器驱动后&#xff0c;问题得以解决。 https://www.cnblogs.com/fengyangsheng/p/17531254.html安装playwright pip install -i https://mirrors.aliyun.com/pypi/si…

区块链运行原理

文章目录 前言区块链的结构区块链的交易过程区块链的共识机制区块链交易存在的问题特性总结 前言 上文《认识区块链》中可以知道区块链是一个通过各种加密算法、共识机制以及其他技术可以实现一个点对点的电子现金系统&#xff0c;从而达到去第三方的效果&#xff08;通常称之…

【Wifi】Wifi架构介绍

Wifi架构介绍 本文基于Android介绍其Wifi架构。Wifi是许多操作系统提供的重要功能之一&#xff0c;特别是越来越多的车载系统wifi是其必备功能。为啥wifi是必备功能&#xff1f; 一方面是传统的上网&#xff08;现在有些车载使用DCM模块管理网络&#xff09;&#xff0c;另一方…

没有前端如何测试后端跨域问题

一、问题 前段时间对项目中的跨域做了相关的处理&#xff0c;网上有很多跨域的解决方案。前端解决&#xff0c;后端解决&#xff0c;nginx代理解决。我采用的是在后端中使用Cors来解决跨域的问题。但是前端项目还没有搭建起来&#xff0c;并不知道Cors的解决方案是否会生效&am…

Apollo(阿波罗)分布式配置中心

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

CSS Vue/RN 背景使用opacity,文字在背景上显示

Vue <div class"training_project_tip"> <div class"tip">展示的文字</div> </div> .training_project_tip { font-size: 12px; font-weight: 400; text-align: left; color: #ffffff; margin-top: 8px; position: relative; dis…

如何将前后端分离项目部署到本地的Docker Desktop容器运行并且访问

文章目录 前言 完成了客户的一个前后端分离项目&#xff0c;要求部署到客户电脑上去展示&#xff0c;那肯定不能直接把代码弄上去跑呀~~~&#xff0c;于是我就想把他们都打包部署到本地的docker容器里面&#xff0c;方便运行和访问&#xff0c;so&#xff0c;以下内容就详细介…

LeetCode09——回文数

LeetCode09 自己写的解,转化为字符串再反转&#xff0c;比较笨。 import java.util.Scanner; public class Result01 {public static void main(String[] args) {System.out.println("请输入整数&#xff0c;我来帮您判断是否是回文数。");Scanner scanner new Sc…

Linux之解除ssh远程登录限制

背景&#xff1a;复制了一个虚拟机&#xff0c;将root密码重置为123456后&#xff0c;使用xshell通过ssh登录竟然失败&#xff0c;检查了很多次&#xff0c;确定root账号密码正确&#xff0c;以下是记录的排查过程。 1、查看ssh登录日志 Ubuntu&#xff1a;/var/log/auth.log…

2023年中国门把手产量、销量及市场规模分析[图]

门把手行业是指专门从事门把手的设计、制造、销售和安装等相关业务的行业。门把手是门窗装饰硬件的一种&#xff0c;用于开启和关闭门窗&#xff0c;同时也具有装饰和美化门窗的作用。 门把手行业分类 资料来源&#xff1a;共研产业咨询&#xff08;共研网&#xff09; 随着消…

R/d2及S/C4估计总体标准差,比较其CPK及规格限概率的差异

R/d2 和 S/C4 是用于估计总体标准差的无偏估计方法&#xff0c;通常用于控制图中。这些估计方法的主要目的是通过样本数据来估计总体标准差&#xff0c;以便监测过程的稳定性和变异性&#xff0c;而不需要收集整个总体的数据。 具体来说&#xff1a; R图中的 R/d2 和 S图中的…

【数据结构】二叉树--OJ练习题

目录 1 单值二叉树 2 相同的树 3 另一颗树的子树 4 二叉树的前序遍历 5 二叉树的最大深度 6 对称二叉树 7 二叉树遍历 1 单值二叉树 965. 单值二叉树 - 力扣&#xff08;LeetCode&#xff09; bool isUnivalTree(struct TreeNode* root) {if (root NULL){return true;}…

【linux】重定向+缓冲区

重定向缓冲区 1.重定向1.1重定向本质1.2重定向接口1.3重定向分类1.3.1>输出重定向1.3.2>>追加重定向1.3.3<输入重定向 2.理解 >&#xff0c; >>&#xff0c; <3.如何理解linux下一切皆文件4.缓冲区4.1理解缓冲区问题4.1.1为什么要有缓冲区4.1.2缓冲区刷…