ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

make的隐式规则

2022-02-03 20:02:24  阅读:151  来源: 互联网

标签:%. 后缀 make makefile 规则 隐式


问题

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

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

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。

标签:%.,后缀,make,makefile,规则,隐式
来源: https://blog.csdn.net/qq_52484093/article/details/122777691

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有