当前位置: 首页 > 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的时候,其实还是没变的,不一样的是,我们的操作变简单了

结语

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

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

http://www.xdnf.cn/news/589123.html

相关文章:

  • shell脚本总结5
  • 当AI遇上科研:北大“科学导航”重塑学术探索全流程
  • LeetCode Hot100 (哈希)
  • x-cmd install | cargo-selector:优雅管理 Rust 项目二进制与示例,开发体验升级
  • OpenCV计算机视觉实战(7)——色彩空间详解
  • 网络图片的缓存和压缩
  • 海康相机---采集图像
  • 如何解决鸿蒙应用闪退问题
  • Flutter 3.32 新特性
  • 鸿蒙Flutter实战:21-混合开发详解-1-概述
  • flutter getx路由管理、状态管理、路由守卫中间件、永久储存get_storage
  • 汇川EasyPLC MODBUS-RTU通信配置和编程实现
  • S7-1500PLC通过工艺对象实现V90总线伺服定位控制(105报文)
  • 英伟达有意入股 PsiQuantum,释放战略转向量子计算的重要信号
  • JVM常量池(class文件常量池,运行时常量池,字符串常量池)
  • Mysql数据库之索引与事务
  • 【内部教程】ISOLAR-AB配置以太网栈|超详细实战版
  • Kotlin与Flutter:跨平台开发的互补之道与实战指南
  • Armadillo C++ 线性代数库介绍与使用
  • Kotlin 极简小抄 P10(类与对象、主构造函数、带有默认参数值的主构造函数、次要构造函数)
  • 【机器学习】集成学习算法及实现过程
  • Ubuntu20.04的安装(VMware)
  • 详解受约束的强化学习(四、数学符号说明)
  • PL/Python数据库: PostgreSQL Python扩展
  • Argo CD 详解:从 GitOps 到持续交付的完整实践
  • 关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别
  • 相机标定与图像处理涉及的核心坐标系
  • 2. PyQGIS Windows下开发环境搭建
  • Java——集合类
  • 【Android】屏幕适配小合集