makefile make 的隐式规则

举报
糖果罐子 发表于 2023/07/21 19:45:29 2023/07/21
【摘要】 @TOC 前言 一、什么是隐式规则?make 提供了一些常用的,例行的规则实现。 当相应的规则未提供时 , make 尝试使用隐式规则。make 提供了生成目标文件 的隐式规则。隐式规则 会使用预定义变量完成编译工作。改变预定义变量将部分改变隐式规则的行为。当存在自定义规则时,不再使用隐式规则。 二、典型隐式规则情况1. makefile中出现同名目标命令:当多处出现同一目标的命令时,...

@TOC

前言


一、什么是隐式规则?

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 发现目标的依赖不存在时。

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

三、查看隐式规则

  1. 查看所有 : make -p

  2. 查看具体规则: make -p | grep “xxx”
    .o 文件的 生成 依赖于 .c .cc 等等。

四、隐式规则的禁用

  1. 局部禁用:
  • 在 makefile 中 自定义规则。
  • 在 makefile 中定义模式。( 如:%.o : %.p )
  1. 全局禁用:
  • make -r

五、隐式规则的副作用

  • 编译行为难以控制
    大量使用隐式规则可能产生意想不到编译行为

  • 编译效率低下
    make 从隐式规则和自定义规则中选择最终使用的规则。

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

在 实际工程 中 尽量不要使用 隐式规则。

例:
需要名为 A.o 的目标: N.y -> N.c ->N.o。


总结

下一篇介绍 make 的路径搜索。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。