【Linux修炼】6.gcc/g++及Makefile【工具篇】

news2024/11/17 7:40:48

在这里插入图片描述每一个不曾起舞的日子,都是对生命的辜负。

Linux-gcc/g++及Makefile

  • 本节目标
  • 程序的翻译过程
    • 1.程序的翻译过程
    • 2. 理解选项的含义
    • 3. 动态链接和静态链接
  • Linux项目自动化构建工具-make/Makefile
    • 1. 背景
    • 2. “见见猪跑”
    • 3. makefile原理及语法
      • 3.1 Makefile原理
      • 3.2 Makefile语法
    • 4. gcc不更新文件的剖析
    • 5. 理解makefile的推导规则
  • Linux的第一个小程序-进度条
    • 1. 行缓冲区概念
      • 1.1 sleep \n
      • 1.2 \r && \n
      • 1.3 fflush(stdout)
      • 1.4 倒计时实现
    • 2. 进度条程序实现

本节目标

  • 1. 了解gcc/g++的使用
  • 2. 掌握makefile的原理
  • 3. 进度条

程序的翻译过程

在C语言中,我们已经学过程序的编译和链接,在这里将复习一下我们之前所学的内容并引出后续gcc/g++的内容。

1.程序的翻译过程

  1. 预处理(头文件展开,去注释,宏替换,条件编译)
  2. 编译:把C变成汇编语言
  3. 汇编:把汇编变成二进制(不是可执行,二进制目标文件不能被执行)
  4. 链接:把你下的代码和C标准库中的代码合起来

2. 理解选项的含义

如果我们直接gcc test.c 就会跳过上述四个过程直接编译生成最终的a.out可执行文件,因此我们不直接这样,而是划分成四条指令依次执行上述的四步翻译过程,在此过程中理解选项的含义。

image-20221023122647933

3. 动态链接和静态链接

首先我们要清楚,我们自己写的代码和库是两码事。C标准库是别人给我们准备好的,让我们直接使用的。我们所有使用库中函数的代码(printf()),其中我们自己只写了该函数的调用,没有对应的实现!只有当链接的时候,对应的实现才和我们的代码关联起来!

那么这就引入了链接,链接的本质:无非就是我们调用库函数的时候和标准库如何关联的问题。这种关联就包括动态和静态。

  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc hello.o –o hello
  • gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

事实上,对于动态和静态的理解,就好比在网吧还是家上网一样。如果你在网吧,此时网吧升级就会影响到你,这也就是所谓的动态;如果把网吧的电脑买来带回家上网,说明你已经有一台自己的电脑,相当于拷贝了一份网吧的电脑到自己家,上网就不会受到网吧升级时的影响,这就是所谓的静态。

因此经过定义与理解的总结:

  • 动态链接: 受库升级或者被删除的影响,形成的可执行程序小,节省资源。

  • 静态链接: 不受库升级或者被删除的影响,形成的可执行程序提交太大! – 网络,磁盘,内存

在Linux下库的命名:

  • 动态库:lib XXXXXXX.so
  • 静态库:lib XXXXXXX.a

即去掉前缀lib和相应的后缀,就是库的名字。举例:libc.so.6就是c标准库。

image-20221025163231092

当我们执行查看c标准库的时候,就可以看到具体的信息,并发现此标准库默认是.so结尾的动态库。

对于动态库和静态库来说,动态库是系统自带的,即系统安装完毕就可以使用,而静态库则一般需要我们自己安装,这也说明了静态库并不是直接拷贝动态库的内容。因此我们需要手动安装一下静态库:sudo yum install -y glibc-static

安装静态库定之后,我们就可以通过 在已有的指令基础上加上-static指定静态库编译:

image-20221025164032546

即系统本身,为了支持我们编程,给我们提供了标准库.h(告诉我们怎么用:标准的动静态库.so/.a)而对于此动静态链接,我们是基于Linux系统去演示的,事实上也只对Linux环境有效,但对于windows来说,其原理是一样的(windows下的动态库:.dll 静态库:.lib)

安装C++版本的gcc(g++):sudo yum install -y gcc-g++

Linux项目自动化构建工具-make/Makefile

1. 背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

2. “见见猪跑”

对于makefile,若想利用make命令,则必须创建makefile命名的文件(m大写也可),在内部编写一定的依赖规则之后,我们通过make就可以对应的执行程序,就省略了类似于这种gcc test.c -o test的编译指令,好我们来看看如何操作:

步骤1: 创建makefile文件,并在makefile文件里编辑相应的依赖关系依赖方法

image-20221025192313685

image-20221025192521664

**步骤2:**执行make指令并输出

image-20221025193005075

这样最大的效果就是不用再写gcc编译了。

3. makefile原理及语法

3.1 Makefile原理

探讨makefile的原理,其最核心的内容就是依赖关系依赖方法

那么什么是所谓的依赖关系和依赖方法呢?对于上面的步骤来说,在makefile文件中:第一行代表着依赖关系,也就是mycode这个要生成的文件是基于mycode.c实现的,mycode依赖于mycode.c。但仅仅有了依赖关系是不够的,需要明白这种关系是为了什么或者是继续什么原因才依赖的,也就是所谓的依赖方法,在第二行中,我们看到mycode是基于mycode.c经过gcc编译生成的,即gcc就是依赖方法。

3.2 Makefile语法

image-20221025194756703

就此例来说,第一行仍是依赖关系,但注意下面必须是tab造成的空格,而不是直接按四下空格。

此外,对于新增的clean来说,也是有一定意义的,.PHONY被改关键字修饰的对象是一个伪目标。我们知道在make时会生成mycode,通过clean这样的方式,就可以将其用make clean 删除:image-20221025195232758

对于.PHONY来说:这个伪目标总是被执行的。那么如何理解这句话呢?

我们先来看看这样的演示:image-20221025200202673

我们发现,当这个mycode已经是最新版本的情况·下,是不会再次gcc出来的。

那如果我们将makefile进行如下的修改:image-20221025195942086

修改后:

image-20221025200030851

发现其仍然是可以执行的。这就是所谓的伪目标总是被执行的含义。

注:对于第一条指令来说,默认规定直接make就可以执行,就比如上面的gcc,这与make clean一样的完整写法make mycode来说是一样的。

4. gcc不更新文件的剖析

对于上面的示例,我们知道了gcc对于已经是最新版本的生成的执行文件来说并不会将其改变,并会提示已经是最新版本,就上面的mycode.c来说,是mycode.c的modify时间不如mycode的modify时间晚,即是在最新的mycode.c下生成的mycode是不会被gcc再次编译生成的,这是由于mycode是基于mycode.c所创建出来的。

因此对于上面的.PHONY 的gcc来说,其能执行是因为.PHONY规定之后,就不遵循这个所谓时间的规则。

5. 理解makefile的推导规则

为了演示推导过程,我们将makefile中的依赖关系进行拆分(但最终效果是一样的)

image-20221026114250545

通过以上修改,我们退出vim模式并执行make

image-20221026113212131

我们发现,对于makefile的依赖关系来说,是从上到下的,即mycode依赖于mycode.o,但此时并没有mycode.o,因此就需要找mycode.o的依赖对象mycode.s,mycode.s继续找他的依赖对象mycode.i,但mycode.i也并不存在,mycode.i就会找他的依赖对象mycode.c,mycode.c是存在的,因此执行情况是从下到上的。

但对于此推导规则,我们只需要明白其中的逻辑,真正利用makefile的时候,没必要将原来的一条gcc指令变成好几条指令。

Linux的第一个小程序-进度条

基于mycode.c,我们在mycode.c中进行编写

1. 行缓冲区概念

1.1 sleep \n

image-20221026180836646

先来执行一下这个程序:(动图)
在这里插入图片描述

我们发现,sleep尽管在printf语句的后面,但是显示器是仍然是先执行的sleep,这是什么原因呢?

实际上,这是一个行缓冲的问题,即确实在语言上先执行的printf,但却不是直接打印在显示器上,而是进入了缓冲区,而缓冲区是以\n为截止条件的,也就是说这一行中程序如果没有\n,就会暂时保留在缓冲区内部,直到出现\n或者程序执行完成。因此,上面的动图并没有直接执行printf是因为没有\n。

修改之后:

image-20221026181721804

那我们看一下添加\n的演示:(动图)

在这里插入图片描述

添加\n之后就可以直接显示了。

1.2 \r && \n

对于回车换行,实际上是两个概念,换行\n是换到下一行,而回车\r是回到这一行的起始位置,因此我们键盘上的enter键称之为回车换行实际上是两个功能合并在了一起。image-20221026182227031

我们看一下回车\r的演示:(动图)

在这里插入图片描述

不显示的原因就是我们的回车\r将之前的内容给覆盖掉了,并且在缓冲区中回到了这一行的起始位置,因此程序结束也并没有打印。

1.3 fflush(stdout)

因此为了解决上面的问题,可以用刷新缓冲区的办法实现:

image-20221026183016087

修改完之后观察:(动图)

在这里插入图片描述

1.4 倒计时实现

通过上面的了解,大家已经知道了缓冲区的概念,因此为了下面的进度条实现,在这里我们先通过上面的知识实现一下倒计时:image-20221026183814410

上述实际上有一定的细节,我们知道/r只是回到起始位置,但如果不控制格式2d,就会出现打印10,90,80……的情况,因为我们每次只覆盖了第一个位置,因此在这里要控制格式,并且fflush(stdout)。

实现动图:.
在这里插入图片描述

这样就实现了一个简单的倒计时。

2. 进度条程序实现

对于进度条来说,通过最上面的航缓冲的知识,我们已经知道应该如何去规避了,因此在这里直接展示进度条,我将程序分成三个部分,即经典的main.c/process.c/process.h,并且将makefile中的依赖对象也改变,对于依赖对象来说,只要-o后面最靠近的是要生成的即可。

makefile代码:image-20221027155755097

接下来我们看看代码,并将其执行:(主程序)image-20221027160112444

进度条执行过程:(动图)

在这里插入图片描述

此外,我们还可以改变颜色:即在printf处进行修改:

image-20221027160613372

演示:(动图)

在这里插入图片描述
到这里本章就结束了,如果对你有帮助的话,记得点赞支持一下呀!

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

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

相关文章

pytorch初学笔记(二):TensorBoard之add_scale()的使用

目录 一、SummaryWriter类的介绍 1. 定义 2. SummaryWriter初始化 2.1 初始化 2.2 帮助文档给出的使用范例 2.3 常用方法 二、add_scale()方法介绍 1. 常用参数介绍 2. 绘制图形 2.1 安装tensorboard 2.2 对应代码 2.3 打开tensorboard窗口 2.3 注意事项 三、a…

kubernetes学习笔记

参考 Cloudman 老师的《每天5分钟玩转Kubernetes》,记录如何使用 Kubernetes ,由于版本变化,一些命令也有相应的变化,本文对应 Kubernetes 1.25.3 5. 运行应用 010.123 用 Deployment 运行应用 原文使用kubectl run命令&#x…

JS(Dom对象的属性和方法)第十六课

Dom对象的属性和方法自定义的熟悉操作上面是今天博客要讲述的内容 一个案例回顾上次课讲的内容 下面是Html中的元素布局结构 <div>我是div审查元素<p>我是p标记的元素</p><span>我是span的元素信息</span></div><div class"one&…

搭建ftp服务器注意事项

很早之前写过一篇关于FTP服务器相关博客&#xff1a;FTP服务器主动被动模式详解。直到最近生产环境需要搭建一个FTP服务&#xff0c;才发现一些细节还需注意。 生产环境搭建ftp服务器&#xff0c;如果有外部用户需要连接ftp服务器下载文件&#xff0c;一般用的是Passive (PASV&…

[深度学习] 名词解释--正则化

正则化 花书的定义&#xff1a;凡是可以减少泛化误差&#xff08;过拟合&#xff09;而不是减少训练误差的方法&#xff0c;都叫正则化方法。 目的&#xff1a;拟合训练数据&#xff0c;防止模型过拟合&#xff0c;通常使用L2正则化.用各种方法规范模型参数的方法. 什么是神经网…

408 | 【2012年】计算机统考真题 自用回顾知识点整理

选择题 T2&#xff1a;后缀表达式&#xff08;逆波兰表达式&#xff09;—— 注意 操作数的顺序&#xff01; 中缀转后缀 运算顺序不唯一&#xff0c;因此对应的后缀表达式也不唯一“左优先”原则&#xff1a;只要左边的运算符能先计算&#xff0c;就优先算左边的用栈实现中缀…

JS(DOM)第十五课

Dom的全称是Document Object Model DOM 定义了访问 HTML 和 XML 文档的标准 Dom的定义 DOM 文档对象模型 DOM是针对XML的基于树的API。描述了处理网页内容的方法和接口&#xff0c;是HTML和XML的API&#xff0c;DOM把整个页面规划成由节点层级构成的文档。 DOM本身是与语言无…

基于simulink的超级电容,电池及DC motor充放电系统仿真

目录 一、理论基础 二、核心程序 三、测试结果 作者ID &#xff1a;fpga和matlab CSDN主页&#xff1a;https://blog.csdn.net/ccsss22?typeblog 擅长技术&#xff1a; 1.无线基带,无线图传,编解码 2.机器视觉,图像处理,三维重建 3.人工智能,深度学习 4.智能控制,智能优…

【C ++基础】迭代器(iterator)在string里面的简单使用

【C 基础】迭代器(iterator)在string里面的简单使用 前言 本文是为了扫清后面学习的难点&#xff0c;而特意写的文章&#xff0c;只是介绍迭代器如何在string中使用。 迭代器的详细解释请看这里&#xff1a; [点击跳转&#xff08;这里还没有写哦&#xff09;] C专栏主页&am…

【Node.JS】事件的绑定与触发

往期文章 【Node.JS】写入文件内容 【Node.JS】读取文件内容 目录 简介 绑定事件 on&#xff08;&#xff09; addListener&#xff08;&#xff09; once&#xff08;&#xff09; 监听事件emit&#xff08;&#xff09; 传参 删除事件 removeListener&#xff08;&am…

【无人机】基于蚁群算法的无人机航路规划研究附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

【笔试题】【day14】

目录 第一题&#xff08;哪些成员变量需要在初始化列表初始化&#xff09; 第二题&#xff08;多态的条件&#xff09; 第三题&#xff08;多态的条件&#xff08;通过父类对象调用的全部都是父类的方法&#xff09;&#xff09; 第四题&#xff08;菱形继承&#xff0c;虚…

猴子也能学会的jQuery第一期——什么是jQuery

#1024程序员节&#xff5c;用代码&#xff0c;改变世界 &#x1f4da;系列文章—目录&#x1f525; 猴子也能学会的jQuery第一期——什么是jQuery 猴子也能学会的jQuery第二期——引入jQuery 未完待续 目录 &#x1f4da;系列文章—目录&#x1f525; &#x1f4c4;需要具备的…

【最佳实践】瀚高数据库 Windows企业版v6.0.4 的安装

Windows7、Windows10 一、安装 解压缩文件“hgdb6.0.4-enterprise-windows10-x86-64-20220127.zip”&#xff0c;以【管理员】身份运行 setup.exe。 安装过程基本上是下一步下一步即可&#xff0c;注意步骤如下。 1.1 安装主目录 注意安装路径&#xff0c;不要包含中文&am…

【创作中心】自定义模板的使用

个人主页&#xff1a;天寒雨落的博客_CSDN博客-初学者入门C语言,数据库,python领域博主 &#x1f4ac; 刷题网站&#xff1a;一款立志于C语言的题库网站蓝桥杯ACM训练系统 - C语言网 (dotcpp.com) 特别标注&#xff1a;该博主将长期更新c语言内容&#xff0c;初学c语言的友友们…

2022年12月1日起,OCS将停止接受GOTS的原料投入

【2022年12月1日起&#xff0c;OCS将停止接受GOTS的原料投入】 GOTS介绍&#xff1b; 全球有机纺织品标准&#xff0c;Global Organic Textile Standard, 简称GOTS。该标准由国际天然纺织品协会&#xff08;IVN&#xff09;、日本有机棉协会&#xff08;JOCA&#xff09;&#…

数字化智慧梁场管理系统解决方案

系统介绍 数字化智慧梁场管理系统实现对预制构件生产的全周期智慧化管理。系统以BIM为基础&#xff0c;搭建完整数字孪生模型&#xff0c;依据生产工序智能排程&#xff1b;围绕生产工序&#xff0c;生产任务智能传递&#xff0c;协同工作&#xff1b;依据生产工序&#xff0c;…

Python实战:获取bing必应壁纸首页的每日一图(仅做学习用)

目录需求网站分析代码实现进一步接口获取其他资源需求 老板&#xff1a;微软必应https://cn.bing.com/ 首页的每日一图看着不错&#xff0c;能不能自动获取 我&#xff1a;我试试 网站分析 我们查看网页元素&#xff0c;不难发现背景图就在类名为.img_cont 的标签下 可是搜…

Vitepress搭建组件库文档(下)—— 组件 Demo

上文 《Vitepress搭建组件库文档&#xff08;上&#xff09;—— 基本配置》已经讨论了 vitepress 搭建组件库文档的基本配置&#xff0c;包括站点 Logo、名称、首页 home 布局、顶部导航、左侧导航等。本文进入最重要的部分 —— 如何像 Element Plus 那样一遍代码就可以展示组…

面试查漏补缺--java基础-容器源码解读

前言&#xff1a; 本文主要是通过源码来解读一些自己还不懂的地方&#xff0c;一些数据结构上的东西&#xff0c;不做过多的解读。 文章目录一、容器体系二、List容器2.1 ArrayList源码2.2 Vector 源码2.3 LinkedList三、Set容器3.1 HashSet一、容器体系 容器总的来说分为两大…