栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

make的隐式规则

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

make的隐式规则

问题

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

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

makefile 中出现同名目标时

依赖:

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

命令:

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

注意事项

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

命令的拆分

makefile

.PHONY : all

var := test_var

all :
	@echo "this is $(var)"

include 1.mk

1.mk

.PHONY : all

all :
	@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.out
CC := gcc

all :
	@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。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/725177.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号