Linux项目自动化构建工具-make/ makefile及其应用:多文件编写第一个linux程序:进度条(懒人学习必备博文!!!)

目录

 1.前言--make/makefile的引入

2.快速上手make/makefile---自动化构建

3.关于依赖关系和依赖方法

4.自动化清理 

为什么我们执行编译的时候,make一下就好,清理却要使用make clean?

5. make/makefile是如何知道当前目录下可执行文件是否为最新

6.文件的三个时间

6.1 Modify 修改时间-----修文件内容的时间

6.2对属性修改的时间:change

6.3access时间是访问时间,查看文件内容的时候发生改变,

touch命令更新时间

7.make/makefile 语法补充

7.1 .PHONY:目标文件名

7.2 使用$@代表目标文件。使用$^代表依赖文件列表

8.make/makefile应用第一个 linux小程序:进度条

8.1知识铺垫

8.1.1缓冲区

8.1.1.1sleep函数

8.1.2 回车与换行

8.1.3 缓冲区换行回车综合-----倒计时程序

8.2 入门版本进度条

8.3 升级进度条改造

8.3.1.进度推进

8.3.2.百分比

8.3.3.旋转光标

​编辑

8.4 进度条结合实际

9.结语 


 1.前言--make/makefile的引入

 在windows下的vs中,当我们的项目中有多个源文件的时候,我们直接点击运行,就将多个源文件生成.o文件再和库中的.o文件进行链接生成可执行程序,也可以源文件之间自由组合形成多个可执行程序,但是并不关心他们之间的依赖关系哪里是源文件,哪里是头文件,先链接那个文件、后链接那个文件,这是因为vs编译器主动帮用户做了,然而在linux中需要我们手动操作。

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

make是一个命令,makefile是一个文件(主旨)

而makefile是需要在当前工作目录下需要我们自己创建的一个文件。

保存的是依赖关系和依赖方法。

2.快速上手make/makefile---自动化构建

我们首先创建一个.c文件

创建一个makefile文件,文件名不能写错,可以写Makefile/makefile

vim makefile文件

保存退出,当我们需要编译这段代码的时候直接使用make指令:

接下来我们就来了解一下依赖关系和依赖方法

3.关于依赖关系和依赖方法

故事:某天,员工小明发现到了发工资的日子,但是老板忘记给他打钱了,于是就给老板打去电话:老板,我是你的员工小明(表明关系),希望把工资发给我(依赖方法)。老板说好的,下午打上卡。

文中的小明的第一句话就是在说明自己和老板的依赖关系,通俗来讲:依赖关系就是说明我为什么要给你,而不是将电话打给别的老板

依赖方法:如何发工资

所以代码中:

mybin依赖于mytest.c,第二行就说明了从mytest.c到mybin的方法。

第一行中,表明依赖关系,依赖关系的表明上使用冒号作为分隔符,冒号左边称为目标文件

冒号右边称为依赖文件列表。

4.自动化清理 

当我们再次执行make时发现:

告诉我们当前的可执行文件已经是最新的了,因为我们编译好过后就没有对源文件再进行过更改。

如何清理项目:清理可执行程序

debug的时候需要将代码清理掉重新编译

方法:打开makefile,定义一个clean;依赖关系为空

依赖方法为:tab键开头 rm 目标文件名(如果有其他临时文件删除就可以)

执行make clean指令就可以清理我们的可执行程序

如果再次清理就会报错:没有这个文件,不想看到报错可以添加-f选项

而后我们在make就可以重新编译了

 这就是自动化清理

为什么我们执行编译的时候,make一下就好,清理却要使用make clean?

因为

①make和makefile执行文件的时候某认是从上到下执行。

如果我们调换一下mkefile文件里面的内容,make时某认就是clean:

②某认只形成一个执行

5. make/makefile是如何知道当前目录下可执行文件是否为最新

当我们再次执行make时发现:

告诉我们当前的可执行文件已经是最新的了,因为我们编译好过后就没有对源文件再进行过更改。

但是如果使用gcc指令还是可以编译:

那么说明对当前可执行文件的检查是make和makefile做的,那么make和makefile是如何知道我们当前目录下的可执行文件是否是最新的呢。

一个文件对应三个时间,创建时间、内容被修改时间、权限被修改时间。只要可执行文件的最近

修改时间比所有的源文件的最近修改时间新,那么说明它就是最新的。

源文件和可执行程序时间是不会一样的逻辑上。

如果我们这里有十个源文件,但是只对其中一两个进行了修改,那么最终可能就是将老的obj项目和新的合并,这个时候编译可能还报错,但是重新生成解决方案就没有错误了就是这个原因。

6.文件的三个时间

查看文件相关时间属性使用指令:stat 文件名

6.1 Modify 修改时间-----修文件内容的时间

我们现在使用vim写入一段代码,然后再修改一下代码观察一下时间

当前的modify时间为:

我们现在对代码进行修改:

modify时间为:

 change也跟着修改了

文件= 内容+属性

对内容修改:modify

6.2对属性修改的时间:change

属性:ll命令下看到的都是文件内容,我们现在修改一下文件的属性

只有change的时间发生了改变 ,对内容做修改时,删除了代码,增加了代码,文件大小属性也改变了,所以change也会改变。

6.3access时间是访问时间,查看文件内容的时候发生改变,

当前

修改后:

只有access的时间发生了改变 

但是如果连续查看可能时间就不会变化,这是因为不是每一次查看都会更改时间,在linux的历史中,最开始是读写文件都会使访问时间修改,但是这个也是数据,也需要操作系统写入磁盘进行记录,和其他两个时间不同,访问文件的比重要比其他两个操作的比重大得多,数据更新频率很快,而且如果文件数量很多,访问时间的更新又要求实时,操作系统就会花费很大的∠(°ゝ°)和资源来做这个时间更新,所以连续查看不会更新访问时间。

可执行程序和源文件比较的是modify。(看源代码是否被更改)

那么在不修改文件内容的前提下,可以调用touch命令来更新文件的时间。

touch命令更新时间

touch 文件名,没有这个文件的时候帮我们创建文件

有这个文件的时候,会刷新这个文件的时间。

那么就可以再次make.

7.make/makefile 语法补充

7.1 .PHONY:目标文件名

这是一个关键字,修饰mybin这个目标文件,使其成为一个伪目标。 

该目标文件总是被执行, 这个目标文件的依赖关系和依赖方法,    在make时总是执行                  

使得我们每次想要重新编译就可以重新编译,不用touch修改时间。

惯用做法:一般将清理设置为伪目标。

7.2 使用$@代表目标文件。使用$^代表依赖文件列表

正常运行

makefile也支持变量定义

但是我们的可执行程序不仅仅只是依赖一个.c文件那么简单 

makefile会先对依赖关系执行推导,再逆向执行依赖方法

8.make/makefile应用第一个 linux小程序:进度条

8.1知识铺垫

8.1.1缓冲区

8.1.1.1sleep函数

让程序执行到sleep函数时休眠指定的秒数

我们编写这个程序:

生成可执行文件并运行我们会发现,会先打印,然后三秒过后程序结束。

将程序修改如下,去掉换行符:

 

执行编译运行,发现前三秒什么也没有,三秒后打印程序结束

 两个程序都是顺序执行的,对于第二个程序来说,程序在休眠时间,printf已经跑完了,木有看到字符串,那么这个字符串一定是被保存在某个地方(c对IO提供了一个缓冲区),程序结束时拿出来。我们的printf输出并不是直接就将数据输出到我们的屏幕上,而是先将数据放入了缓冲区(可以理解为一段内存空间),当有\n时就会1立即刷新缓冲区内容到屏幕,没有\n的时候没有立即刷新,还在内存中,看不到,程序结束的时候,会把缓冲区内容刷新到屏幕。

8.1.2 回车与换行

严格意义上,回车与换行不一样,回车与换行控制光标移动

换行:从当前光标位置,跳到下一行相同的位置叫做换行

回车:从当前光标位置回到当前行最开始叫做回车。

\n实际上是回车+换行

\r 只回车不换行 

8.1.3 缓冲区换行回车综合-----倒计时程序

编写这个程序:

我们发现运行的时候并不会出行我们的10,9,8.。。。倒计时内容,是因为混冲区没有刷新的问题

介绍flush函数,刷新一下我们的缓冲区:

刷新一个流,C语言程序默认在启动的时候会打开三个流。stdin标准输入   stdout标准输出 stderr标准错误,所以可以直接从键盘读取数据,直接输出数据到屏幕

 

如果开始是10,就会打印90 80 这是因为显示器只认识字符 ,10打印完9.8等只会覆盖第一个字符,修改如下:

就OK了。

8.2 入门版本进度条

进度条原理就是:不换行递增式输出

第一次打印一个,然后第二次光标不换行,回车到最开始打印两个符号,一次增加实现覆盖增长。

直接上代码:

补充:sleep函数以秒为单位,usleep函数以毫秒为单位

结果如下: 

 

8.3 升级进度条改造

建立多个文件

建立依赖关系

可以直接使用.c

 

8.3.1.进度推进

效果:

 

 

8.3.2.百分比

%%实现

8.3.3.旋转光标

| / -\\交替打印

8.4 进度条结合实际

上述程只是一个演示,百分比等都是简单演示,进度条程序应该和某些程序捆绑起来,比如说下载,比如说传递,那么我们已经下载的比上我们文件总的大小得到真正的下载百分比,我们的进度条也应该控制到这个进度,还有下载卡顿的时候,我们的光标不旋转,进度条不推进。

我们现在模拟一种下载的场景:

进度条代码修改为:

编译运行:

可以彩色输出,搜索printf彩色输出即可。

9.结语 

以上就是本期的所有内容,知识含量蛮多,大家可以配合解释和原码运行理解。创作不易,大家如果觉得还可以的话,欢迎大家三连,有问题的地方欢迎大家指正,一起交流学习,一起成长,我是Nicn,正在c++方向前行的奋斗者,数据结构内容持续更新中,感谢大家的关注与喜欢。

 

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

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

相关文章

在虚拟机ubuntu中端里输入vim filename.不显示vim界面,而是vim可以在以下的 package 找到

1。打开终端 2.输入以下命令来更新软件包列表: sudo apt update 3,输入以下命令来安装vim编辑器: sudo apt install vim 4等待安装完成后,再次输入"vim filename"命令,应该就能正常显示vim界面了。

express实现用户登录和注册接口

目录 1 创建数据库2 连接数据库3 集成ORM库4 创建业务逻辑5 创建路由7 测试接口总结 我们在编写后端接口的时候操作数据库是一种常见的功能需求,express本身并不提供直接操作数据库的能力,需要借助第三方库来操作数据库,本篇讲解一下软件开发…

JavaScript 之 var、let 和 const

JavaScript 之 var、let 和 const 1.作用域2.重新赋值3.重复声明总结 var、let 和 const 都是用来声明变量的关键字,但它们之间有一些重要的区别 1.作用域 var:声明的变量具有函数作用域或全局作用域。 在函数内部声明的变量只能在该函数内部访问&…

【二叉树】Leetcode 543. 二叉树的直径【简单】

二叉树的直径 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例1: 输入:root [1,2…

基于SpringBoot + Vue实现的在线装修管理系统设计与实现+毕业论文

介绍 系统包含用户、装修队、管理员三个角色 管理员: 管理员管理:管理其他管理员的账号和权限,确保系统管理的层次化和安全性。 装修队管理:审核装修队的资质,管理装修队的人员信息,监控工程进度&#xff…

可视化学习:实现Canvas图片局部放大镜

前言 最近我在可视化课程中学习了如何在Canvas中利用像素处理来实现滤镜效果,在这节课程的结尾留了一道局部放大镜的题目,提示我们用像素处理的方式去实现这个效果,最终实现随着鼠标移动将图片局部放大,本着把学到的内容落地实践的…

elementUI this.$msgbox msgBox自定义 样式自定义 富文本

看这个效果是不是很炫?突出重点提示内容,对于用户交互相当的棒! 下来说说具体实现: let self = this const h = self.$createElement; this.$msgbox({title: null,message: h("p", {style: "margin-top:10px"}, [h("i", {class: "el-i…

命名空间【C++】(超详细)

文章目录 命名空间的概念命名空间的定义命名空间定义的位置作用域每一个命名空间都是一个独立的域作用域符:: 编译器找一个变量/函数等的定义,寻找域的顺序为什么要有命名空间?1.解决库与程序员定义的同名的重定义问题2.解决程序员…

【氮化镓】p-GaN栅极退化的温度和结构相关性

论文总结: 本文献深入研究了带有p-GaN栅极的正常关断型(normally-off)高电子迁移率晶体管(GaN-HEMTs)在恒定电压应力下的时序退化行为。通过直流特性分析和温度依赖性分析,研究了故障时间(TTF)与应力温度和器件几何结构的依赖性。结果显示,p…

JavaWeb作业四

一. 单选题(共5题,30分) 1. (单选题, 6分) 以下关于Spring核心容器相关说法错误的是。 A Spring框架的所有功能都是通过其核心容器来实现的。 B 创建BeanFactory实例时,需要提供Spring所管理容器的详细配置信息,这…

FME学习之旅---day17

我们付出一些成本,时间的或者其他,最终总能收获一些什么。 【FME-HOW-TO系列】28 栅格邻域函数 RasterConvolver转换器说明: 接受包含栅格几何对象的输入要素,并在对所有波段应用卷积滤波 器后输出要素。 本人对栅格数据处理的较…

mysql笔记:25. docker环境中mysql主从复制、主主复制实操

文章目录 一、准备工作1. 安装配置Docker2. 准备MySQL相关的配置和数据目录 二、基于日志点的主从复制1. 配置Master服务器1.1 修改配置文件1.2. 在docker中启动Master节点1.3. 创建用户并授权 2. 配置Slave1服务器2.1. 修改配置2.2. 启动服务2.3. 指定Master2.4. 开始复制 3. …

vue computed和watch的区别【网易,京东,拼多多】

知识点 computed和watch的区别 题目 讲一下vue组件的computed和watch的区别。 答案 应用场景不同 computed用在根据data属性或者其他computed计算得到一个新值的情况,computed的值一般被用在渲染中。 watch用在监听数据变化,然后做一些有副作用的操…

【2023】kafka在linux和docker安装(kafka-1)

目录💻 一、linux安装kafka1. 安装jdk2. 上传解压到/usr/local目录下3、使用kafka 二、docker安装kafka1. 下载2. 安装zookeeper3. 安装kafka 一、linux安装kafka 环境主机 mac m2、虚拟机Ubuntu22.04.4 1. 安装jdk yum install -y java-1.8.0-openjdk.x86_64下载k…

11-设计模式:Go常用设计模式概述

设计模式是啥呢?简单来说,就是将软件开发中需要重复性解决的编码场景,按最佳实践的方式抽象成一个模型,模型描述的解决方法就是设计模式。使用设计模式,可以使代码更易于理解,保证代码的重用性和可靠性。 …

【Entity Framework】EF中DbSet类详解

【Entity Framework】EF中DbSet类详解 文章目录 【Entity Framework】EF中DbSet类详解一、概述二、定义DbSet2.1 具有DbSet属性的DbContext2.2 具有 IDbSet 属性的 DbContext 2.3 具有 IDbSet 属性的 DbContext三、DbSet属性四、DbSet方法五、DbContext动态生成DbSet 一、概述 …

打工人神器! Raccoon 代码小浣熊

继这三个之后,今天又来了一个 [ Raccoon代码小浣熊 ] 核心精要与产品特点 全面支持多种编程语言和IDE:「代码小浣熊」支持超过90种主流编程语言,包括但不限于Python、Java、JavaScript、C、Go和SQL等。同时,它集成了市面上主流的…

Quiet-STaR:让语言模型在“说话”前思考

大型语言模型(llm)已经变得越来越复杂,能够根据各种提示和问题生成人类质量的文本。但是他们的推理能力让仍然是个问题,与人类不同LLM经常在推理中涉及的隐含步骤中挣扎,这回导致输出可能在事实上不正确或缺乏逻辑。 考虑以下场景:正在阅读一…

CTF题型 php://filter特殊编码绕过小汇总

CTF题型 php://filter特殊编码绕过小汇总 文章目录 CTF题型 php://filter特殊编码绕过小汇总特殊编码base64编码string过滤器iconv字符集 例题1.[Newstarctf 2023 week2 include]2.[Ctfshow web 117] php://filter 是一个伪协议,它允许你读取经过过滤器处理的数据流…

YOLO图像前处理及格式转换

import cv2 import numpy as np import os import glob# 数据增强函数 def augment_data(img):rows,cols,_ img.shape# 水平翻转图像if np.random.random() > 0.5:img cv2.flip(img, 1)img_name os.path.splitext(save_path)[0] "_flip.png"cv2.imwrite(img_n…