make和makefile
基础知识
在一个大型工程项目中,通常存在多个源文件,那么这些文件哪些是要被先编译,哪些后编译,或者说某些文可能会重复编译。makefile制定了一系列的规则来指定。
makefile带来的好处就是自动化编译,一旦写好这个文件,只需要一条make命令,整个工程就能自动完成编译,极大的提高了效率。
make是一个命令,makefile是一个文件
make/makefile的使用
系统本身并没有makefile,需要我们自己创建makefile文件(也可以叫Makefile)。该文件中主要写依赖关系和依赖方法:
注意:
有了makefile文件,make命令才能派上用场,保存退出makefile文件后在终端输入make命令就能完成自动编译
这个时候你可能有一个疑问:为什么只执行了第一条指令没有执行clean的指令?
makefile默认只执行第一个依赖方法,如果你要执行clean可以使用make+依赖关系
那么为什么要有依赖关系和依赖方法?
我们来感性认识一下:设定一个这样的情景,现在是月底了,你兜里没钱了,所以你决定打电话给你爸要钱
如果你给你爸打电话只说:我是你儿子(表明依赖关系),你爸很难清楚你要干啥
你要想完成目标,你应该说:我是你儿子(依赖关系),我没钱了,打钱(依赖方法)
同理,对于makefile来说,基于mytest.c生成mytest文件(依赖关系),需要执行gcc mytest.c -o mytest命令(依赖方法)
伪目标
为什么多次make会失败,但是多次make clean却能一直成功?
观察makefile文件发现:clean用.PHONY
修饰了,而mytest没有
被.PHONY
所修饰的就是伪目标,而伪目标可以不遵守规则,因此可以多次反复执行。
三个时间
不加伪目标make无法多次执行的原因在于目标文件没有更新,不用重新编译(在一些大型工程项目中,仅是编译的过程就可能要耗费数十分钟甚至几小时)
那么它怎么知道我没有更新目标文件呢?这里就依赖于文件属性中的时间了
对于mytest来说,一定是先有的mytest.c才有的mytest,所以如果mytest的时间modify时间比mytest.c的modify时间要早说明近期对mytest.c文件进行过修改,也就需要重新编译,此时就可以再次执行make
拓展
Access是访问时间,Modify是文件内容更改时间,Change是文件属性更改时间。
但是modify时间更新change时间也会更新,因为内容变了文件大小就会变,文件大小也是一种属性。
但是此时有一个奇怪的问题产生了,我刚刚修改文件内容时用vim打开了mytest.c文件,明明访问了mytest.c文件啊,为什么Access时间没有更新?
首先要清楚,我们访问一个文件不一定修改这个文件,但是我们修改这个文件一定要访问这个文件。
意思是访问文件的频率可能会很高,如果每访问一次就修改一次访问时间,就会进行大量多余的IO
所以设计者决定采用,多长时间后访问或者连续访问多少次以后再更新访问时间
推导规则
调用make指令后makefile文件内依赖方法的执行顺序和我的写法正好相反,这是为什么?
在make推导的时候会根据依赖关系而推导,从上到下,当依赖文件列表不存在会继续根据依赖文件列表所对应的项而继续。但这样是将简单的过程复杂化了,平时没必要这样写,这里也只是做讲解用。
小程序进度条
缓冲区问题
首先明确一件事,是printf语句先执行还是sleep先执行?
很明显,该代码中没有任何循环或者选择结构,也就是说代码是从上往下执行的,先执行printf再执行sleep
不对啊,结果显示是先休眠再打印。
printf打印的结果没有显示在屏幕上也没有丢失,是因为暂存在了缓冲区。
缓冲区默认是行刷新,也就是说如果printf语句中有\n就会马上刷新
\r称为回车,即回到该行行首,如果行首本来有字符,再写入就会覆盖。
\n称为换行,也就是从本行的所在位置到下一行是此位置。
所以\r\n就是回车换行,但是在语言层面,\n就是回车换行
此外,还可以使用
fflush(stdout)
手动刷新
倒计时程序
#include<stdio.h> #include<unistd.h> int main() { int cnt=10; while(cnt) { printf("剩余时间:%2d/r",cnt);//%2d是控制格式,一次刷新两个字符 fflush(stdout);//刷新缓冲区 cnt--; sleep(1); } return 0; }
进度条
采用分文件的方式来写:
不用在makefile文件中放process.h文件,因为编译器会自动到当前目录去查找
最后一起来看看程序的运行结果:
最近的文章都写的比较短,因为我感觉写太长了没什么人看,虽然我的文章本来也没人看。不知道各位大佬对我的文章有没有什么好的建议。