当前位置: 首页 > news >正文

【Linux 学习计划】-- makefile

目录

什么是makefile

makefile细节讲解

依赖方法的递归关系

makefile进阶玩法,$@,$^,变量

结语


什么是makefile

当我们有一个可以编译的文件的时候,如果我们每一次重新编译都要写gcc,就不太好

而且如果你要编译的东西多了,那么这会是一个很头疼的事情

所以,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力

我们先来见一见makefile:

现在我们有一个待编译的文件,test.c

如果要让makefile自动编译的话,我们就需要创建一个名字叫做makefile的文件,并且:

我们需要在makefile里面这么写,这里就是见一见,接下来我们会在下文详细讲解,现在先讲操作

当我们讲makefile这个文件处理好了之后,我们如果这时候要编译test.c文件的话,我们只需要输入一个make命令即可,如果不想要可执行程序了,也就是生成出来的test文件的时候,我们就输入make clean 就可以将其删除了

如下图:

makefile细节讲解

依赖关系、依赖方法、目标文件、依赖文件

我们先回顾一下上面的makefile

目标文件:其中,我们的第一行的test,就是目标文件,意思就是我们这个makefile的目的是要生成哪一个文件

依赖文件:后面的test.c就是依赖文件,但是这里有两个细节需要说明,第一个是,在未来我们的依赖文件并不只有一个,而大概率是多个,而我们只需要在后面加一个空格然后接着往后面拼文件名即可。第二个是,有时,我们的依赖文件可以为空,比如第四行的clean,我们清理并不需要依赖文件,直接清理即可

依赖关系:依赖关系就是,第一行一整行,我们要生成test,就需要依赖test.c这个文件才能生成出来

依赖方法:其实就是第二行一整行

.PHONY是什么

我们可以做一个小实验,如下:

我们可以看到,其中被.PHONY修饰的是clean,而我们发现,当我们重复make的时候,他不允许,说以及是最新的了,但是我们却可以无限删除

换一下,如果我们现在用.PHONY修饰make:

所以我们可以得出结论,也就是,被.PHONY修饰的文件,可以被重复执行

makefile的默认生成方式

makefile默认只会生成第一对依赖关系,这也就是为什么当我们使用了make指令了之后,只会将test生成出来,而clean没有被执行

为什么对可执行默认不用 .PHONY 修饰

在一些大公司里面,我们每编译一次,说不定就要用半个小时,甚至一两个小时,这时候如果我们误触了,重新编译,那么我们的时间就被消耗了,效率就低了,这就是原因

makefile如何知道一个可执行程序可以重新编译了

我觉得在这里我需要重新讲一下这个问题本身,也就是:当我们重复make的时候,他会说不给你make,因为已经是最新了,但是系统如何知道,这个文件已经不是最新了,可以重新make了呢?

我们来看下面这张图:

可以看到,我们在图中,只是对test.c文件touch了一下而已,并没有改变文件本身的内容,就可以让make重置

其实是这样的,文件都会有他的修改时间,只要修改时间不一样了,被修改过了,既可以重新make了

另外就是,系统会比较目标文件和依赖文件,只要有一个依赖文件的时间比目标文件的新,那么就代表可以重新make了

依赖方法的递归关系

我们可以看一下下面这张图:

来解析一下这张图,首先我们需要知道的是,makefile是默认只会看第一对依赖关系的,所以他会先去看,我们要生成test,需要test.o,但是我们没有test.o,所以就会接着往下找

接着,要生成.o,但是需要.s,接着往下,直到找到test.c,这时候,就会再往上重新走一遍,有了.c,就能有.i,有了.i,就有了.s,接着是.i,test

这其实就是递归了,所以当我们以后想要生成多对依赖关系时,就可以用这种方法

makefile进阶玩法,$@,$^,变量

这其实就是我们最终想要的makefile了

我们先来讲一下@和^,这其实就代表了第一行中的test和test.c,或者说:

@代表的是所有目标文件,^ 代表的是所有的依赖文件

也就是一个代表 : 左边,一个代表 : 右边

但是我们单用这两个符号并不像,需要配合 $ 符号一起使用,而 $ 符号代表的就是提取的意思

makefile中的变量

是的你没看错,makefile中也是可以有变量的,只不过放在这里讲,是因为,我们这些变量需要配合 $() 一起使用,如下图:

其中,$ 符号的意思就是提取,加上括号,我们就可以使用这些变量了

而在第二张图我们也可以看到,即使我们用了$@^()这些符号,但是当我们在外面使用make的时候,其实还是没变的,不一样的是,我们的操作变简单了

结语

这篇文章到这里就结束啦!!~( ̄▽ ̄)~*

如果觉得对你有帮助的,可以多多关注一下喔

相关文章:

  • 6.13.拓扑排序
  • 危险品摆渡人
  • BSD 操作系统的历史、影响及贡献
  • day33 python深度学习入门
  • k8s容器入门(1)有状态服务 vs 无状态服务 核心区别
  • 企业级爬虫进阶开发指南
  • Vue 3 与 Vue 2 的区别详解
  • 【Leetcode 每日一题】3362. 零数组变换 III
  • KCTF-CCG CrackMe crypto 1.0
  • 从零基础到最佳实践:Vue.js 系列(9/10):《单元测试与端到端测试》
  • Linux spi
  • 【语法】C++的map/set
  • 问题 | 撰写一份优秀的技术文档,既是科学也是艺术。
  • 基于大模型的胫腓骨干骨折全周期预测与治疗方案研究报告
  • ubunt配置本地源
  • 小米2025年校招笔试真题手撕(二)
  • 基于Python写的Telnet带GUI客户端
  • 深度学习相比传统机器学习的优势
  • Python中的并发编程
  • 接口自动化测试框架(pytest+allure+aiohttp+ 用例自动生成)
  • 广州市企业网站建设/seo zac
  • 国外做微课的网站/常用的搜索引擎有哪些?
  • 五金商城网站建设注意/培训师资格证怎么考
  • 某某公司电子商务网站建设与维护/seo和sem的联系
  • 基于asp网站开发 论文/惠州网站建设方案推广
  • 网站建设五年发展规划/郑州网站建设方案优化