前言
本篇文章将给大家介绍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不使用隐式规则,希望大家牢牢记住这篇文章的内容防止以后在开发中遇到问题。