前言
一、什么是隐式规则?
make 提供了一些常用的,例行的规则实现。 当相应的规则未提供时
, make 尝试使用隐式规则。
- make 提供了生成目标文件 的隐式规则。
- 隐式规则 会
使用预定义变量
完成编译工作。 - 改变预定义变量将部分改变隐式规则的行为。
当存在自定义规则时
,不再使用隐式规则。
二、典型隐式规则情况
1. makefile中出现同名目标
- 命令:
当多处出现同一目标的命令时,make 发出警告。
所有之前定义的命令被最后定义的命令取代。
- 依赖:
将所有的依赖合并在一起,成为目标的最终依赖。
示例:
.PHONY : all all : # 有 2 个 同名的目标 @echo "command -1" VAR := test all : @echo "all : $(VAR)"
注意:
当使用 include 关键字包含其他文件时,需要确保被包含文件中的同名目标只有依赖,没有命令
;否则,同名目标的命令将被覆盖。
2. 当 makefile 中未定义相关规则时,会尝试使用隐式规则。
示例:
下面的代码可以编译成功吗?答案是 当然可以。
虽然 代码中没有 gcc -c -o $(OBJS) $(SRC ) , 但是 会使用 隐式规则。
隐式规则 可能使用 make 中的预定义变量。
SRC := $(wildcard *.c) OBJS := $(SRC:c=o) hello.out : $(OBJS) gcc -o $@ $^ @echo "Target ==> $@" .PHONY : clean clean : $(RM) *.o *.out
3. 当 make 发现目标的依赖不存在时。
- 尝试通过
依赖名
逐一查找隐式规则。 - 并且通过
依赖名
推导可能需要的源文件。
三、查看隐式规则
- 查看所有 : make -p
- 查看具体规则: make -p | grep “xxx”
.o 文件的 生成 依赖于 .c .cc 等等。
四、隐式规则的禁用
- 局部禁用:
- 在 makefile 中 自定义规则。
- 在 makefile 中定义模式。( 如:%.o : %.p )
示例:
- 全局禁用:
- make -r
五、隐式规则的副作用
- 编译行为难以控制。
大量使用隐式规则可能产生意想不到编译行为
。 - 编译效率低下。
make 从隐式规则和自定义规则中选择最终使用的规则。 - 隐式规则链
当依赖的目标不存在时, make 会极力组合各种隐式规则对目标进行创建,进而产生意料之外的编译行为!
在 实际工程 中 尽量不要使用
隐式规则。
例:
需要名为 A.o 的目标: N.y -> N.c ->N.o。
总结
下一篇介绍 make 的路径搜索。