前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于makefile的那点事【进阶版】(三个时间问题)

关于makefile的那点事【进阶版】(三个时间问题)

作者头像
用户11173787
发布2024-06-24 11:20:17
610
发布2024-06-24 11:20:17
举报
文章被收录于专栏:破晓破晓

写在最前面:

建议你在会基本使用makefile的基础上,再阅读本篇博客!!

提出问题:

不知道大家有没有这样的经历,当我们利用makefile进行编译时,你有没有遇到过这样的情形:

命令行输入make,按下回车,完成编译,然后如果我们继续输入make,Linux会提示我们:“up to date”,这是什么意思?意思是从上一次编译完成,到现在,依赖对象没有发生过改动,不需要重新编译。

不就是再重新编译嘛,再重新编译一下不就可以了?又不用多长时间。

其实,这种想法是错误的,现在我们写的文件中的代码非常少,少则几行,多则几十行,上百行,运行起来也就是不到一秒的时间。但是,如果是在大公司,写的大型程序,代码量都是几万行起步,编译起来就浪费时间了,几十分钟或者几个小时都有可能,我们知道Linux是一个极其重视效率的平台,既然已经编译过了,为什么还要做无用功呢?

但是,gcc怎么知道这个文件通过makefile已经被编译过了呢?还别说,这是一个值得探索的问题!!

分析问题:

不知道同学们知不知道关于文件的三个时间,

代码语言:javascript
复制
[user@VM-8-5-centos exercise]$ stat my.out 
  File: ‘my.out’
  Size: 23744           Blocks: 48         IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 1975452     Links: 1
Access: (0775/-rwxrwxr-x)  Uid: ( 1003/    user)   Gid: ( 1003/    user)
Access: 2024-05-30 15:53:02.495932934 +0800
Modify: 2024-05-30 15:53:00.595888648 +0800
Change: 2024-05-30 15:53:00.595888648 +0800
 Birth: -

这三个时间分别为Access,Modify,Change,接下来,我先说一下这三个时间分别指的是什么时间。

Access:

这个时间为:最近一次访问这个文件的时间

我只是打开了这个文件,即访问了这个文件并未进行任何其他的操作,access就发生了发生了变化。

Modify:

Modify时间为文件内容更改的时间,一般而言Modify发生变化Change时间也会跟着发生变化。至于原因,卖个关子,一会再说:

我打开文件,并增加了一些内容,我们来看不出我们所料,两个时间都发生了变化。

Change:

这个时间是指文件的属性发生变化的时间,因为文件的属性不止包括文件的权限,还有文件的大小,都是文件的属性,所以才会有刚刚的现象。

这一次,我进行了权限的修改,但未进行文件内容的修改,但也算是访问文件了吧?但为什么仅Change时间发生变化,Accsee时间没有变化?这个我们等到一会儿去聊

对内容的修改,往往涉及属性;带单单对属性的修改,往往不涉及到内容!!

再谈Access:

之前,在老的操作系统内核中,只要是我们访问了这个文件,Access时间就会发生变化。意思是如果我们一连多次的访问这个文件,Access时间就会连续发生变化,也就是Accesss时间更改的频率太高了。

对于一个文件来说,是修改这个文件的次数多,还是访问这个文件的次数多呢

我认为:访问这个文件的次数更多,因为修改文件一定会访问这个文件,但是访问这个文件并不代表修改这个文件;我们读取一个文件的内容,属于访问这个文件,但并未涉及到修改文件的内容。

在运行程序时,会涉及到反复访问大量的文件,每访问一下这个文件,就要更改Access时间。时间这个概念对文件来说也是属性,文件在磁盘中放着,修改文件的属性就等于大量的IO操作。这对操作系统来说,无疑是一个巨大的负担。

另外,有多少人会关心读取这个文件内容的时间呢?相对于而言,我们更关心的是这个文件内容和权限被修改的时间,所以,只要文件的内容和权限发生修改,对应的时间就会立即发生变化。

随着操作系统的更新换代,新的操作系统对这方面做了相应的优化,突出体现在Access修改的频率上。由原来的只要一访问就发生变化,变为现在的等到访问一定的次数或者时间,Access时间再发生一次修改。

解决问题:

再谈问题:gcc是怎么知道这个文件上次编译之后并未发生内容修改,不需要重新编译呢?

比较时间,这个现象的背后就是gcc比较时间,更准确的来说:就是比较了源文件和可执行程序的Modify时间。

我们先达成这样一个共识:在初次编译时,源文件的Modify时间一定比编译后生成的可执行程序的Modify时间早,这就好比父亲和儿子,先有父亲,再有儿子嘛,源文件就好比作父亲,可执行程序就是源文件的儿子。

在初次编译形成可执行程序后,源文件内容并未发生修改的情况下,Modify时间也未发生改变,依旧早于可执行程序的时间,这是再次输入make命令的话,gcc就通过比较时间得知:源文件没有发生修改,没有必要二次编译。但如果源文件内容发生修改,Modify时间发生修改,由原来的早于可执行程序的时间变得晚于可执行程序的时间,这时,gcc就会得知源文件发生改变,有二次编译的需要!!!

验证推论:

相信大家在刚学Linux时,学的前几个命令中,肯定touch这个命令:

我们常用的touch命令为:在没有这个文件的情况下,创建文件文件;如果这个文件已经存在,那就更新这个文件为最新时间。

接下来,我们这样操作:

这样一来,是不是验证了我们的推论!!!

顺便说一下:.PHONY的作用就是让它修饰的伪目标不遵循这样的规则,所以“总能运行”

写到最后,因作者水平有限,文中难免会出现错误,请各位读者指正!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 提出问题:
  • 分析问题:
    • Access:
      • Modify:
        • Change:
          • 再谈Access:
          • 解决问题:
          • 验证推论:
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档