Makefile基础教程(make的隐式规则)

举报
yd_274589494 发表于 2023/05/26 19:51:46 2023/05/26
【摘要】 @TOC 前言本篇文章将给大家介绍make的隐式规则。 一、什么是make的隐式规则Make 的隐式规则是指 Make 在没有找到显式规则的情况下,会自动使用的一组规则。这些规则是预定义好的,可以被 Make 自动识别和调用,不需要用户指定具体的规则。隐式规则的使用可以大大简化 Makefile 的编写,特别是当需要编译大量源文件时。隐式规则可以根据不同的文件扩展名自动调用不同的编译命令。 ...

@TOC


前言

本篇文章将给大家介绍make的隐式规则。

一、什么是make的隐式规则

Make 的隐式规则是指 Make 在没有找到显式规则的情况下,会自动使用的一组规则。这些规则是预定义好的,可以被 Make 自动识别和调用,不需要用户指定具体的规则。

隐式规则的使用可以大大简化 Makefile 的编写,特别是当需要编译大量源文件时。隐式规则可以根据不同的文件扩展名自动调用不同的编译命令。

二、makefile中出现同名目标时

在 Makefile 中,如果出现了同名的目标,则后面出现的目标会覆盖前面同名的目标。这种情况可能会导致不可预期的错误,因此需要特别注意。

例如,以下 Makefile 中存在两个同名的目标 all:

all: target1
    @echo "build complete"

target1:
    @echo "building target1"

all: target2
    @echo "build complete"
    
target2:
    @echo "building target2"

在这个 Makefile 中,第二个 all 目标将覆盖前面的 all 目标,因此执行 make 命令时只会编译执行第二个all中的命令,而不会执行第一个all中的命令。

执行结果:
在这里插入图片描述

三、一些常见的隐式规则

大家觉得下面的makefile可以正确执行吗?在这里我们并没有生成对应的.o文件。

SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)


hello : $(OBJS)
	$(CC) -o $@ $^
	@echo craet file ok

执行结果:
执行结果却出乎我们的意料,明明没有生成对应的.o文件啊,为什么还是正确执行呢?这就是因为make的隐式规则。

在make中包含这样的一条隐式规则:C 源文件编译为目标文件:%.o: %.c。
当make发现没有对应的规则时就会调用到这个隐式规则。
在这里插入图片描述

四、查看隐式规则

使用make -p命令可以查看隐式规则:
这里隐式规则是有非常多的,这里就不一 一进行讲解。
在这里插入图片描述

五、隐式规则缺点

虽然隐式规则可以方便地简化 Makefile 的编写工作,但是使用隐式规则也存在一些缺点:

可能导致编译错误:隐式规则会自动推导源文件和目标文件之间的关系,但不一定符合实际情况。如果隐式规则的规则不适合当前项目的情况,则可能导致编译错误。

难以定制要求:隐式规则通常是基于一些默认的编译选项,而这些选项可能不符合用户的需求。通过隐式规则,用户难以对编译选项进行修改和自定义配置。

可读性较差:隐式规则隐藏了 Makefile 的具体细节,使 Makefile 更加难以理解和调试。由于隐式规则并不直接体现在 Makefile 中,因此难以准确理解每个目标和规则之间的关系。

综上所述,隐式规则虽然提高了 Makefile 编写的效率和可读性,但在一些情况下可能会导致编译错误、难以定制编译选项和可读性差等问题。因此,对于较大和复杂的项目,最好使用显式规则来更加精确地控制编译过程和生成的目标文件。

六、禁用隐式规则

1.全局禁用

使用make -r命令全局禁用隐式规则:

这里使用make -r命令来执行上面编写的makefile:

执行结果:
从结果可以看出隐式规则被禁用了,没有起作用了。
在这里插入图片描述

2.局部禁用

局部禁用的方法就是定义自己的规则和变量。
修改代码后:

CC := gcc

SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)


hello : $(OBJS)
	$(CC) -o $@ $^
	@echo craet file ok

$(OBJS) : %.o : %.c
	$(CC) -o $@ -c $^
	@echo this is myrule

运行结果:
在这里插入图片描述
跟上面的运行结果做一个对比后就知道在定义了自己的规则后就不会使用到make里面的隐式规则了。

总结

本篇文章我们介绍到了make中的隐式规则,使用隐式规则可以帮助我们节省代码的编写量,但是有的时候却会出现意想不到的错误,使用局部禁用和全局禁用的方法可以让make不使用隐式规则,希望大家牢牢记住这篇文章的内容防止以后在开发中遇到问题。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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