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

大家好!这篇文章主要讲Linux的最后一个工具,并说一个进度条小程序。
在这里插入图片描述

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

1.1 背景知识

以前在vs下,我们创建一个项目,我们编辑,运行就行了。我们不需要考虑项目结构,比如:多文件时,.h,.c,.cpp,我们先编译哪一个文件呢?链接需要哪些库?库和头文件等在哪里去找?等等一些问题我们都不需要考虑。那么在Linux下,有没有什么方式帮助我们解决这些问题呢?
而makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

1.2 什么是make/Makefile

makefile是一个文件,make是一个命令工具,是一个解释makefile中指令的命令工具

1.3 如何使用make/Makefile

首先我们创建一个文件,在里面编写一些代码:
在这里插入图片描述
然后我们需要在当前项目目录下,创建一个Makefile/makefile文件(大小写都行)。
在这里插入图片描述
现在我们就需要在这个Makefile里写一些依赖关系和依赖方法
为什么要写依赖关系和依赖方法呢?因为我们的目的是:形成可执行程序。而形成可执行程序它的依赖关系是:它的源文件。它的依赖方法是:gcc

1.3.1 代码演示

第一步:可执行程序名:源文件。表明它的依赖关系。
在这里插入图片描述
前面是编译后的名字,后面是需要的源文件。
第二步:按一下Tab键。然后写出gcc的编译方式
在这里插入图片描述
在这里,依赖方法在依赖关系的后面,并且必须以Tab开头
写完后保存退出。此时我们在使用make命令:
在这里插入图片描述
我们可以看到它生成一个test可执行程序,并且可以正常运行。
这个过程在vs上叫做生成解决方案,那么清理解决方案怎么写呢?有的人会说用rm,这是不行的。因为用rm,可能会把源文件删除。所以,我们应该这样做:
在这里插入图片描述
.PHONY的意思:是Makefile中的一个关键字,后面跟着的叫做伪目标
伪目标也是目标,它也有目标关系和目标方法

写好之后,我们保存一下。然后用命令——“make clean”,以此来清除所有的目标文件,以便重新编译
在这里插入图片描述
这里我们还需要解释一下.PHONY关键字。clean被.PHONY修饰时,表明总是被执行的
这是什么意思呢?我用代码演示一下什么是不是总被执行的
在这里插入图片描述
从这里我们可以看到make执行test的依赖方法时,只能执行一次。下次再使用make,就不会再形成新的test了。这个就叫做不是总被执行的。不被执行的原因是:认为test已经是最新的文件,不需要再次执行,浪费资源。

那么现在我们再把test目标被.PHONY修饰,看有什么变化。
在这里插入图片描述
在这里插入图片描述
可以看到,它现在是可以被重复执行的。所以总是被执行的意思是:无论目标文件是否新旧,照样可以直接执行

那么makefile是如何识别我的exe/bin是新的还是旧的呢?
在Linux下有一个命令可以查看文件的时间。
在这里插入图片描述
在Linux下有三种时间,acm时间。
Access的意思是:进入,访问文件的时间。
Modify的意思是:修改文件内容的时间。
Change的意思是:修改文件属性的时间。

在这里插入图片描述
从上图我们可以看到,文件的属性更改。它的change时间也发生变化,其它的没有发生变化。

我们再举一个例子:
在这里插入图片描述
我们进去修改了文件的内容,所以它的Access的时间和Modify发生了变化。为什么它的Change的时间也发生了变化呢?原因是:修改了文件内容,它的大小也可能发生变化,所以它的属性发生了变化

所以现在我们就可以讲解一下makefile是如何识别我的exe/bin是新的还是旧的。
原因如下
我们知道源文件的Modify时间一定是比可执行程序的Modify时间早,如果我们对源文件进行修改,它的Modify时间会修改,就会在可执行程序的Modify时间后面。所以,根据对比源文件和可执行程序的最近修改时间,评估要不要重新生成

那么还有一个问题:为什么make会自动执行test的依赖方法,而不自动执行clean的依赖方法呢?
原因是:makefile默认只会形成第一个目标文件,执行该依赖关系的依赖方法。
我们给它们掉换一下位置:
在这里插入图片描述
在这里插入图片描述
可以发现make执行的就是clean的依赖方法。

1.3.2 多文件的Makefile演示

这个我们现阶段只需要了解一下,见一下就行了。
在这里插入图片描述
首先,我们创建两个源文件和一个头文件。
在这里插入图片描述
打开头文件,写一个test函数声明。
在这里插入图片描述
然后打开test.c完成函数的实现。
在这里插入图片描述
在main.c文件中调用这个函数。
写好之后。如果我们想用这两个源文件(.c)去生成两个目标文件(.o),然后去链接库形成可执行程序该怎么写呢?
在这里插入图片描述
我们创建一个makefile,然后vim。
在这里插入图片描述
这里我们是没有main.o和test.o的,但是makefile会自动向下寻找执行依赖关系和依赖方法。
在这里插入图片描述
在这里我们要注意一点:第二种依赖方法我们没有写-o。在makefile中,我们不写,它会默认生成同名.o文件。这两种写法都可。

然后,我们把makefile文件写完:
在这里插入图片描述
这里的意思是:* 号是通配符,它会清理所有的.o文件和可执行程序test。注意:*号和.o之间没有空格,一定要记住!!!
在这里插入图片描述
在这里插入图片描述

1.3.3 makefile的特殊写法

在这里插入图片描述
这两个符号是什么意思呢?我们可以运行一下:
在这里插入图片描述
所以$@代表的意思是:我们的目标文件。而 $^代表的是我们依赖文件列表(也就是所以的依赖文件)。

2. Linux第一个小程序-进度条

2.1 缓冲区

在写这个小程序之前,我们需要一些准备知识。
在这里插入图片描述
在Linux下有一个sleep函数,是让程序休眠的。它的单位是秒,对应的头文件是< unistd >。在Windows下有一个Sleep函数,它的单位是毫秒。

那么现在有一个问题:这个程序是先执行第一步还是第二步呢?
在这里插入图片描述
从运行结果我们可以看到,它是先执行了第一步然后才执行第二步。
在这里插入图片描述
那么我们把\n去掉是什么情况呢?
在这里插入图片描述
在这里插入图片描述
从这个运行情况来看。可能有的同学会认为是先执行了第二步,再执行的第一步。其实并不是这样的,学过C语言的我们知道程序是从上往下编译的。所以还是先执行的第一步,然后执行的第二步。

那么为什么这里的hello world数据没有在睡眠前打印出来,也没在睡眠后打印出来,而是在程序结束时才打印出来呢原因是:数据在缓冲区里
那么这里是缓冲区指的是哪里的缓冲区呢?
这个问题,我们暂时是回答不出来的。以后再说。不过缓冲区其实就是一段内存空间。所以hello world数据就在这个内存空间里。而这个内存空间有一个刷新策略:立马将内存中的空间显示出来。而刷新策略中有一个叫做行刷新

现在有一个问题:不想用\n,如何把数据立马刷新出来?
我们可以用一个函数来强制刷新:
在这里插入图片描述
在C语言的文件操作那篇文章其实有提到过。大家可以去看一下那篇文章。
快速通道:C语言文件操作
大家再去实验一下就可以看出结果了。

2.2 回车和换行

用严格定义来说:
回车:将光标回到当前行的最开始。
换行:新起一行,但和上行的列不变。

而我们平时口头说的"回车",“换行”。其实是二者的结合。
在Linux下\n就是二者的结合,而单单的回车是\r

现在我们就写一个倒计时打印的程序:
在这里插入图片描述
在这里我们写的是回车,记住一定要刷新缓冲区不然不会立即显示。
演示这里不好演示,大家可以自己试一下。

2.3 代码演示

首先,我们创建一个目录,然后创建一些文件:
在这里插入图片描述
划黄线的大家可能有些疑惑,这个我们前面的说过。
> 是定向输出到文件,如果文件不存在,就创建文件。如果文件存在,就将其清空
在这里插入图片描述
然后,我们进入Makefile先把基本的指令写好。
在这里插入图片描述
然后开始写实现进度条的函数。我们知道一般的进度条它是从0到100,所以会循环101次。然后我们可以定义一个字符数组,按字符串来打印。第一次打印0个字符,第二次打印1个字符… …
在这里插入图片描述
这里的usleep也是一个睡眠函数。单位是微秒
在这里插入图片描述
但是我们打印出来是这样的一个结果。
在这里插入图片描述
因为我们是\r,光标还是在最左侧,所以当我们打印完了之后,命令行提示符会把前面的字符给覆盖了。所以这里我们需要在循环结束后再加一个\n。
在这里插入图片描述
结果就是这个样子了:
在这里插入图片描述
如果我们想加一个%多少的数字呢?我们可以这样:%%就是一个%
在这里插入图片描述
运行情况如下:
在这里插入图片描述
如果大家演示的话,你能发现后面的]号是跟着#号一起动的,如果我们想预留空间的话。在C语言有专门的方式。
在这里插入图片描述
运行情况如下:
在这里插入图片描述
在这里,我们还可以增加一个动态的效果。就是类似一个旋转符合,第一次打印|,第二次打印/,第三次打印-,第四次打印\。
在这里插入图片描述
运行情况如下:
在这里插入图片描述
在C语言中,我们还能输出时带有颜色:
在这里插入图片描述
举个例子:
在这里插入图片描述
在这里插入图片描述
剩下的大家可以自己发挥,写出优美的进度条吧!
在这里插入图片描述

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学代码的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值