前言:
我们之前已经介绍了gcc和g++的基本使用方法,并涉及了许多子指令,但手动输入这些指令有时会显得繁琐。此时,自动化工具makefile就显得尤为重要。
可以把makefile理解为编程语言中的宏,它可以简化命令的输入,从而大大减少工程的工作量。因此,makefile的使用不仅可以提高工程的完整性,还能提升效率。
简单来说,makefile是一个自动化命令工具。使用时,首先需要创建一个名为makefile或Makefile的文件,并在其中编写一些指令和操作,以实现自动化。
我们先来看看如何简单使用makefile:
第一步是创建一个makefile文件并添加一些指令,稍后会详细介绍。
第二步,我们来看一个示例代码:
然后,我们只需执行make命令,就可以生成一个名为test的可执行文件,并且运行它也是没有问题的:
此外,clean指令也可以按预期执行。
我们从makefile文件的第一个要点开始:
第一行的test:test.c,其中test:test.c表示依赖关系,test是目标文件,test.c是被test依赖的文件。
冒号后面的部分称为依赖文件列表,依赖文件可以用空格分隔,也可以为空。依赖方法必须使用Tab键进行缩进,不能使用四个空格,否则会报错。
这里的依赖关系可以类比为父子关系,儿子依赖父亲给钱,依赖方法则是养育。
如果我们重复使用该命令会怎样呢?
第一次执行成功,但之后会显示“test is up to date”,表明test文件已经是最新状态。
这时,我们可以回顾之前提到的文件的ACM时间。
首先查看test.c的ACM时间:
不允许多次执行编译命令的原因是makefile工具会比较源文件和可执行文件的ACM时间。如果可执行文件和源文件的ACM时间有差异,make会检测到源文件已更新,从而重新编译。这样做是为了提高效率,避免反复编译已编译好的文件。
不同自动化工具对时间的判断标准可能不同。例如,VS有时会因为时间判断问题出现bug,重建解决方案后重新运行即可。此时,清空解决方案是为了更新可执行文件的ACM时间,重新比较后发现源代码较新,从而成功编译。
之前介绍的touch命令可以创建文件,看似在这里无用,但它可以更改ACM时间:
因此,想要重复编译,可以通过touch命令更改ACM时间后再编译。
这里引出一个关键词,.PHONY:
我们会发现clean总是可以执行,这就是.PHONY的作用。被.PHONY修饰的指令可以重复执行,因此我们可以重复执行clean。同样,我们可以用.PHONY修饰test:
这样就可以重复编译了。clean也可以重复执行,因为clean是特殊方法,后面不需要跟任何东西:
现在我们来探讨一下原理部分,为什么直接make会执行第一个指令?
这是因为makefile的执行顺序是从上到下进行的,所以直接make会默认执行第一个指令。如果我们改变指令的位置:
此时make会执行第一个语句。
学习到这里,你可能会觉得每次执行指令都要显示出来,缺乏神秘感。能否不显示呢?
当然可以,此时用到的符号是@,@可以使指令不显示:
此时执行make后,rm -rf也不会显示:
同理:
所以@只能应用于单个指令,不是多行的。对于echo@,可以这样做:
这里还有一个有趣的点是,makefile中的注释使用#,并且允许变量的存在,虽然称为变量,但实际上是宏:
执行时实际上是进行替换。
但这样使用会导致上述错误。
需要搭配$使用:
此时就不会有问题了。
这里涉及了替换,我们再看看@和^:
不难看出,@和^分别代表目标文件和依赖文件。
现在又提到了依赖关系,我们来看一段代码:
我们可以发现依赖关系是连着的,因此可以直接创建编译的三个阶段的文件。
既然依赖关系是连着的,尝试打乱顺序会怎样呢?
可以发现,仍然可以创建文件。难道打乱顺序也没有问题吗?
当然不是:
此时只能创建预处理期间的文件,而无法创建可执行文件。凡事都需要一个带头的,因此可执行文件必须放在最前面。
感谢阅读!
以上就是初识Linux · 有关makefile的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号