欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

make的隐式规则

时间:2023-09-01
问题

如果同一个目标的命令拆分写到不同地方,会发生什么?

下面的程序怎么执行?为什么?

makefile 中出现同名目标时

依赖:

所有的依赖合并在一起,成为目标的最终依赖

命令:

当多处出现同一目标的命令时,make 发出警告所有之前定义的命令被之后定义的命令取代 注意事项

当使用 include 关键字包含其他文件时,需要确定被包含文件中的同名目标只有依赖,没有命令;否则,同名目标的命令将被覆盖!

命令的拆分

makefile

.PHONY : allvar := test_varall :@echo "this is $(var)"include 1.mk

1.mk

.PHONY : allall :@echo "this is command from 1.mk"

include 将 1.mk 文件内容包含进来后,当前 makefile 中 all 目标对应的命令定义在2个不同的地方,前面 all 所定义的命令会被后面定义的命令所取代。

执行结果如下所示:

 make 首先发出警告,随后执行后面定义的 all 的命令。

什么是隐式规则 (built-in rules)

make 提供了一些常用的,例行的规则实现

当相应目标的规则未提供时,make 尝试使用隐式规则

下面的 makefile 能编译成功吗?为什么?

初探隐式规则 

make 提供了生成目标文件的隐式规则

隐式规则会使用预定义变量完成编译工作

改变预定义变量将部分改变隐式规则的行为

当存在自定义规则时,不再使用隐式规则

初探隐式规则

makefile

SRCS := $(wildcard *.c)OBJS := $(SRCS:.c=.o)TARGET := app.outCC := gccall :@echo "$(.VARIABLES)"$(TARGET) : $(OBJS)$(CC) -o $@ $^$(RM) $^@echo "succsee target => $@"%.o : %.c$(CC) -o $@ -c $^

在执行 make 的时候,make 发现我们并没有给 .VARIABLES 和 RM 变量赋值,所以 make 会通过隐式规则使用预定义变量完成编译工作。

深入理解隐式规则

当 make 发现目标的依赖不存在时

尝试通过依赖名逐一查找隐式规则并且通过依赖名推导可能需要的源文件

隐式规则的副作用 

编译行为难以控制

大量使用隐式规则可能产生意想不到的编译行为

编译效率低下

make 从隐式规则和自定义规则中选择最终使用的规则 隐式依赖链

当依赖的目标不存在时,make 会极力组合各种隐式规则对目标进行创建,进而产生意料之外的编译行为!

问题 

makefile 提供了多少隐式规则?如何查看隐式规则?

查看隐式规则

查看所有:make -p

查看具体规则:make -p | grep "XXX"

深入理解隐式规则 

makefile

app.out : main.o func.o$(CC) -lstdc++ -o $@ $^

当前目录下的文件如下所示:

app.out 依赖于 main.o 和 func.o,make 发现当前 makefile 中没有生成 main.o 和 func.o 的规则,所以 make 会使用隐式规则,尽力生成 main.o 和 func.o

执行结果如下所示:

 make 使用了隐式规则尽力去生成目标的依赖。

 

隐式规则的禁用

局部禁用

在 makefile 中自定义规则在 makefile 中定义模式 (如:%.o:%.p)

全局禁用

make -r 后缀规则简介

后缀规则是旧式的 "模式规则"

可以通过后缀描述的方式自定义规则

双后缀规则 

定义一对文件后缀 (依赖文件后缀和目标文件后缀)

如:.cpp.o <=> %.o : %.cpp 单后缀规则

定义单个文件后缀 (源文件后缀)

如:.c <=> % : %.c 关于后缀表达式的注意事项

后缀规则中不允许有依赖

后缀规则必须有命令,否则无意义

后缀规则将逐步被模式规则取代

后缀规则初体验

makefile

app.out : main func.o $(CC) -lstdc++ -o $@ $^.c.o :@echo "my suffix rule"$(CC) -o $@ -c $^.c :@echo "my suffix rule"$(CC) -o $@ -c $^

当前目录下的文件如下所示:

执行结果如下所示:

可以看出 main 是由当前 makefile 的后缀规则创建出来的,但是当前 makefile 没有生成 func.o 的规则,所以 make 使用隐式规则去生成 func.o。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。