makefile make 的隐式规则

简介: makefile make 的隐式规则

前言


一、什么是隐式规则?

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 的路径搜索。

相关文章
|
分布式计算 DataWorks API
一分钟“零代码”生成API,DataWorks数据服务快速上手指南
DataWorks数据服务提供了快速生成API的能力,可以一分钟“零代码”生成API,本文是一篇快速上手指南,帮助你快速认识数据服务。
12328 0
|
Linux 网络安全
掌握ls命令:完整指南、高级用法与常见问题解答 | 理解文件管理的关键工具
掌握ls命令:完整指南、高级用法与常见问题解答 | 理解文件管理的关键工具
2516 0
|
前端开发
Antd中Table列表行默认包含修改及删除功能的封装
Antd中Table列表行默认包含修改及删除功能的封装
377 0
|
jenkins Java Shell
jenkins实现持续集成、持续部署
想要利用jenkins实现持续集成、持续部署,首先我们先思考需要jenkins帮我们做些什么事情才能达到这个目的。首先开发人员提交了代码jenkins应该知道这个变动;其次jenkins知道代码变更后,想要拉取代码,此时要求jenkins服务器上也要有代码拉取的终端,比如git、gitee等;再其次拉取完代码后jenkins就需要打包这些代码成为jar包或者war包,这就需要maven、gradle等打包工具;再然后jenkins需要将这些jar包部署到目标服务器,那就需要相应的插件和脚本来部署这些jar或者war包。
725 1
jenkins实现持续集成、持续部署
|
10月前
|
网络协议 安全 网络性能优化
了解访问控制列表 (ACL):概念、类型与应用
了解访问控制列表 (ACL):概念、类型与应用
916 2
9-1| cp: 无法获取"884/*" 的文件状态(stat): 没有那个文件或目录 这是什么意思
9-1| cp: 无法获取"884/*" 的文件状态(stat): 没有那个文件或目录 这是什么意思
|
网络协议
wireshark过滤条件
wireshark过滤条件
999 0
|
消息中间件 安全 NoSQL
「架构」SOA(面向服务的架构)
**SOA**是构建灵活企业IT系统的架构模式,基于服务组件进行设计。它强调服务的自包含、模块化,通过服务识别、抽象、组合和交互实现业务流程。特点包括松耦合、重用性、互操作性和标准化。优点是灵活性、可维护性、可扩展性和成本效益,但也有复杂性、性能和治理问题。设计策略涉及业务能力识别、服务契约定义和服务目录建立。技术栈涵盖Java EE、.NET、SOAP、REST、服务治理工具和各种数据库、消息队列及安全标准。SOA旨在适应变化,但也需妥善管理和规划。
708 0
|
JavaScript 前端开发
Vue状态管理:请解释Vuex中的action是什么?它们有什么用途?
Vue状态管理:请解释Vuex中的action是什么?它们有什么用途?
607 2
|
监控 关系型数据库 MySQL
Flink cdc报错问题之读取mysql报错如何解决
Flink CDC报错指的是使用Apache Flink的Change Data Capture(CDC)组件时遇到的错误和异常;本合集将汇总Flink CDC常见的报错情况,并提供相应的诊断和解决方法,帮助用户快速恢复数据处理任务的正常运行。