目标的坚定是性格中最必要的力量源泉之一,也是成功的利器之一。没有它,天才会在矛盾无定的迷径中徒劳无功。💓💓💓
目录
✨说在前面
🍋知识点一:Linux项目自动化构建工具Makefike
•🌰1. Makefile背景
•🌰2. 理解Makefile
🍇基本概念与过程
🍇ACM三种时间
🍇Makefile推导规则
🍇变量
🍋知识点二:Linux小程序-进度条
•🌰1. 行缓冲区、fflush
•🌰2. 进度条实现
• ✨SumUp结语
✨说在前面
亲爱的读者们大家好!💖💖💖,我们又见面了,上篇文章我们讲解了linux中的重要工具-编译器gcc、g++以及动静态链接的详细过程,大家可以回顾一下,加深印象~
我们今天给大家讲解一下Linux中的另外一个重要工具-Linux项目自动化构建工具Makefike的使用。由于使用命令编译链接文件比较繁琐,如果文件一多,那么一个一个处理将要耗费大量的时间。那么,在Linux中开发有什么方法解决这个问题呢?带着这个疑惑我们来开启这一篇文章的学习吧~
👇👇👇
💘💘💘相关链接如下(直接点击即可)【Linux】Linux重要工具
【Linux】Linux编译器-g++、gcc、动静态库
🎉🎉🎉xshell + 云服务器🎉🎉🎉
博主主页传送门:愿天垂怜的博客
🍋知识点一:Linux项目自动化构建工具Makefike
•🌰1. Makefile背景
会不会写Makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行复杂的功能操作
Makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
•🌰2. 理解Makefile
🍇基本概念与过程
Makefile 是 make 命令所读取的配置文件,包含了构建项目的规则。其主要作用是检查项目文件的依赖关系,自动执行必要的命令,从而更新目标文件。一般来说,Makefile 主要包括以下三部分内容:
- 目标(Target):需要生成的文件,例如可执行文件。
- 依赖(Dependencies):生成目标所依赖的文件或目标。
- 命令(Commands):构建目标时需要执行的命令。
直接这么说其实大家不好理解,我们直接给大家写一写让大家看看然后再作具体讲解:
首先我们写一份代码在文件 myproc.c 中,并创建 Makefile 文件,这里的 Makefile 也可以写成 makefile。
接着我们使用vim在 Makefile 中添加以下代码,接着保存退出。此时当我们输入make命令时,会发现直接执行了我们在 Makefile 中写的 gcc 命令。
继续向 Makefile 中添加代码,此时退出输入 make clean,会发现直接执行了我们在 Makefile 中写的 rm 命令。
将 myproc 和 clean 位置互换,看看有什么发现?
那么接下来我来给大家分析一下。
对于 makefile 的书写规则如下:
target: dependencies
command
对于我写的例子,target 就是 myproc,也就是我最终生成的可执行程序;dependencies 意为依赖关系,也就是我的 myproc 文件是依赖什么来生成的,这个很重要;command 是命令,也叫做依赖方法,也就是 myproc 是通过什么方法生成的。
这里有一个很重要的点,就是make命令扫描 Makefile 文件的时候,会从上到下进行扫描,默认形成第一个扫描到的目标文件。我们这里myproc是第一个,所以我们输入make命令就会执行它所对应的依赖方法,上面我们互换myproc 和 clean 的现象也证明了这一点。
🍇ACM三种时间
相信说到这里再回头看代码就能很好的理解了,不过还有一个地方:为什么clean 上一行需要加上.PHONY呢?这是什么东西呢?
我们注意到,clean其实是依赖空文件的,也就是没有依赖具体文件,依赖方法是 rm 命令。.PHONY标识表示一个伪目标,被.PHONY标识的依赖方法总是被执行。
那什么叫总是被执行呢?我们接下来看看:
我们能看到,我们第一次使用make命令是没有问题的,但是后续就不能继续make了,并且提示我们 myproc.c是最新的。那是不是意思是说,myproc.c没有被跟新过,也就没有必要形成新的可执行程序了呢?其实却是是这样的,Linux默认老代码是不进行重新编译的。那问题是,make是怎么知道代码的新旧问题的呢?
这里我们就不得不再聊一聊我们曾经的 ACM 时间了,忘了的话大家可以看看我写的这一篇博客:
【Linux】Linux的基本指令(1)_linux cde-CSDN博客
我们可以用 stat 来查看文件的三种时间:
ACM三种时间的详细区别:
时间属性 | 缩写 | 含义 | 更新条件 |
访问时间 | atime(access time) | 文件内容最后一次被读取的时间 | 使用如cat、more等命令读取文件内容时更新,但ls、stat等命令不会修改此时间 |
修改时间 | mtime(modify time) | 文件内容最后一次被修改的时间 | 对文件内容进行修改(如使用vi编辑器保存文件)后更新状态 |
改动时间 | ctime(change time) | 文件状态(如权限、所有者、链接等)最后一次被更改的时间 | 对文件执行更改属性(如使用chmod、chown命令)或修改链接等操作时更新 |
根据ACM时间中的修改时间(Modify Time),系统就可以得知源文件 myproc.c 和二进制代码 myproc 的新旧了。
🍇Makefile推导规则
对于上面的代码,为了让大家理解 Makefile 的推导规则,我们对它进行复杂化:
那么借助这个说明什么呢?其实,Makefile 类似一个栈结构,各个指令进行的具体细节如下图所示:
🍇变量
Makefile 允许我们使用变量:
- 变量可以在很多地方使用,比如目标,依赖,命令等。
- 变量的赋值可以是用:“ =,?=,:=,+= ”。
- 变量的引用:通过 $() 来完成变量的引用。
对于我们之前写的 Makefile ,可以优化为:
但是大家注意,虽然这样写还算OK,但是我们习惯上都是先将.c文件翻译成.o文件,然后多个.o文件链接形成可执行程序,所以我们还可以继续进行修改:
然而写到这里还有一处不足,就是这并没有证明 Makefile 的必要性。虽然它实现了自动化构建,但是在文件中依然需要写这些步骤。因此,我们可以对代码继续进行优化:
这里源文件我们可以用 $(shell ls *.c) ,它表示将列出当前文件中.c结尾的文件,当然我们也可以使用一个类似于库函数的东西 $(wildcard *.c),也是相同的作用。同理,对于目标文件,我们也有更好的写法:$(SRC:.c=.o) 。这样,一份小而精美的 Makefile 文件就写完了。
🍋知识点二:Linux小程序-进度条
•🌰1. 行缓冲区、fflush
我们之前在编写C语言代码或C++代码时难免会遇见一些奇怪的问题,比如下面的这个例子:
按正常来说打印完hello linux~后程序等待1s后结束,但是大家可以在自己的云服务器上试试,结果像是sleep语句先执行,而后再执行printf语句一样,这是怎么回事呢?
实际上,标准输入输出在Linux环境下大多是行缓冲的,也就是说,当一行结束,这一行才会从缓冲区中向对应输入输出流中输入内容。也就是在执行sleep语句时,printf的内容还在缓冲区中没有输入到标准输出流,所以我们没有看到hello linux~。那怎么解决呢?我们可以用fflush来刷新缓冲区,注意参数:
接下来请大家独立理解下面这个倒计时的代码:
•🌰2. 进度条实现
准备工作:
代码实现:
上面的代码相信大家都是可以看懂的,大家也可以下去自己实践一下。不过上面的代码是不能使用的,因为一个正常的进度条,一定要结合场景,随着下载内容随时更新进度条,这才对,显然上面的进度条无法满足这个功能。
因此我们对其进行优化:
• ✨SumUp结语
到这里本篇文章的内容就结束了,本节给大家讲解了Linux的又一类重要工具-自动化构建工具Makeifle以及一个小程序。大家可以将我文章中写的操作自己实操一遍。加深印象。希望大家能够认真学习,迎接接下来的挑战,期待大家继续捧场~💖💖💖