makefile 中的目标究竟是什么?
make 被设计的初衷是用于编译和管理 C 语言源代码的,所以目标在默认情况下:
- make 认为**目标对应着一个文件 **
- make 比较目标文件和依赖文件的新旧关系,决定是否执行命令
- make 以文件处理作为第一优先级
1 | # 下面的代码有何意义: |
当前目录不存在名为 clean 的文件时,clean会被作为标签进行使用,执行 rm *.o hello.out 命令;
当前目录下存在名为 clean 的文件时,由于 make 以文件处理作为第一优先级,所以他会去检查 clean 这个命令,这时他会发现 clean 文件(目标)所对应的依赖并没有被修改过(clean没有依赖所以也就无法被修改依赖),那么 make 就会认为 clean 文件是最新的就会不执行下面的命令,并提示”clean 是最新的。”
为了解决这个问题(我们要执行 clean 下的命令而不是让 make 将 clean 当成成文件进行处理),我们就引入了”伪代码”这个概念。
makefile 中的伪目标
- 通过 .PHONY 关键字声明一个伪目标
- 伪目标不对应任何实际文件
- 不管伪目标的依赖是否更新,命令总是执行
伪目标语法
先声明,后使用;
1 |
|
这样处理后即使当前目录下存在 clean 文件,make 也只会将 clean 当作一个标签进行处理,而不是文件;
因为此时 clean 就相当于变成了 .PHONY 文件的依赖,而 .PHONY 这样一个文件其实并不存在,所以 clean 文件的创建时间相比 .PHONY 来说永远是新的;这样 clean 下的命令就肯定会被执行;
妙用
规则调用(函数调用)
1 |
|
这样当我们执行 make rebuild 时他就会按照先 clean 再 all 的顺序执行下去;
技巧
当我们使用的不是 GNU 下的标准 make 程序时,可能不存在 .PHONY 这个关键字,那么该如何实现伪目标的效果呢?
1 | clean: FORCE |
原理:如果一个规则没有命令或者依赖,并且它也不是一个文件名,在执行此规则时,目标(FORCE)总会被认为是最新的
小结
- 默认情况下,make 认为目标对应着一个文件
- .PHONY 用于声明一个伪目标,伪目标不对应实际的文件
- 伪目标的本质是 make 中特殊目标 .PHONY 的依赖
- 使用伪目标可以模拟”函数调用”