📖结论
对于一个源代码,进行一次编译,得到一个可执行文件后,如果没有对源代码做任何修改,再去对源代码进行编译,make会觉得没必要,不会重新编译。
📖如何实现
一定是源文件 形成可执行文件,先有源文件,才有可执行文件,一般而言,源文件的最近修改,比可执行文件要早。如果,更改了源文件,那和之前形成的可执行文件相比,此时的源文件最近修改时间就比可执行文件新。
所以,只需要比较可执行文件的最近修改时间和源文件的最近修改时间,如果.out文件的最近修改时间晚于.c文件,就不需要重新编译。反知,则需要重新编译。
📖查看文件时间
stat mytest:查看mytest文件的有关时间。
Access:文件最近一次被访问的时间,查看文件内容、修改文件内容,都属于访问文件。
Modify:最近一次修改文件内容的时间。
Change:最近一次修改文件属性的时间。
这三个时间是相互关联的,有的操作可能会同时更新多个时间。例如:修改文件的内容,那这三个时间都会更新,因为修改文件内容,首先要访问该文件,其次修改后,文件的大小会发生变化,所以这三个时间都会更新。
如上图所示:修改文件内容,三个时间都更新了,但是修改文件属性,Modify没更新可以理解,为什么Access也没有更新???
正是因为对文件的各种操作,都会导致Access时间改变,早期的Linux系统,确实会随着对文件的操作,时刻更新Access时间,这些时间信息都存储在计算机的硬盘上,而硬盘都属于外部设备,进行读写操作会比较慢,过高频率的更新一个文件的Access,当整个系统在被多个用户使用的时候,就会有大量的Access更新行为,这些行为都会往硬盘中写数据,这就会导致整个系统的运行速度下降。所以,在现在的Linux中,对Access的更新策略进行了修改,维护了一个计数器,会根据Modify和Access的更新达到一定次数的时候,才会更新Access,以此来提高系统的运行效率。(注:不同系统的更新策略会有差异)
📖手动更新文件时间
touch test.c:将test.c文件的所有时间更至最新。
touch -m test.c:将test.c文件的Modify时间更至最新。
touch -a test.c:将test.c文件的Access时间更至最新。
touch -c test.c:将test.c文件的Change时间更至最新。
📖再回到编译
是否重新编译,其实就是比较源文件和可执行文件的Modify时间。
📖结论
make会根据源文件和目标文件的新旧,判定是否需要重新执行依赖方法进行编译。这意味着,依赖方法并不是每次都会执行。
📖.PHONY伪目标
要想让makefile文件中的依赖方法总是被执行,可以用.PHONY对相应的标签进行修饰。
.PHONY:mytest mytest:test.c gcc test.c -o mytest
告诉make,mytest对应的依赖方法总是被执行。
上面只是给大家演示.PHONY的作用,一般情况下,对编译操作不加.PHONY进行修饰,而是对清理操作加.PHONY修饰。
mytest:test.c gcc test.c -o mytest .PHONY:clean clean: rm -rf mytest
📖特殊符号
- $@:表示标签,依赖关系冒号左边的内容。
- $^:表示依赖的文件,依赖关系冒号右边的内容。
mytest:test.c gcc $^ -o $@ .PHONY:clean clean: rm -rf mytest
📖取消执行make指令时的回显
在前面的介绍中,每次执行make指令,都会把对应的依赖方法回显出来,像下面这样:
可以在makefile文件中的依赖方法前面加上@,取消回显。
mytest:test.c @gcc $^ -o $@ .PHONY:clean clean: @rm -rf mytest
🎁结语:
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,您的支持就是春人前进的动力!