C语言16-makefile(3)——makefile的模式规则

1.模式规则

上一节我们的makefile文件如下:

makefile 复制代码
src = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(src))

app:$(obj)
	gcc $(obj) -o app
hello.o:hello.c
	gcc -c hello.c -o hello.o
add.o:add.c
	gcc -c add.c -o add.o
sub.o:sub.c
	gcc -c sub.c -o sub.o
mul.o:mul.c
	gcc -c mul.c -o mul.o 

我们目前只有4个c文件,可以生成4个o文件,那如果我们有200个呢,2000个呢,要咋办?make里面提供了一种模式规则,来对一类规则进行匹配并简化。

2.基本语法

makefile 复制代码
目标模式: 依赖模式1 依赖模式2 
    命令
  • 目标模式 包含一个 %,匹配目标文件名的一部分。必须含且仅含一个 %(如 %.o、build/%.o)
  • 依赖模式 也包含 %,匹配时 % 的值与目标中的 % 相同。
  • % 匹配非空字符串(不能空),可以出现在任何位置,但通常出现在文件名末尾(如 %.o)或中间(如 build/%.exe)。

核心机制:当 Make 需要生成一个目标(比如 foo.o)且没有显式规则时,会查找模式规则。如果 foo.o 匹配 %.o(% = foo),则依赖变为 foo.c(若模式是 %.o: %.c)。然后 Make 会尝试生成或找到 foo.c,如果成功则执行命令。

3.自动变量

  • $@:表示规则中的目标
  • $<:表示规则中的第一个条件
  • $^:表示规则中的所有条件,组成一个列表,以空格隔开,如果列表中有重复项,则消除重复项

到此,makefile可以修改为

makefile 复制代码
src = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(src))

app:$(obj)
	gcc $^ -o app
%.o:%.c
	gcc -c $^ -o $@

4.内置变量

  • CC:默认是cc指令,可以改成gcc
  • CPPFLAGS:C语言预处理的选项 -I(大写的i)
  • CFLAGS:C编译器的选项
  • LDFLAGS:链接器选项 -L -l(小写的l)

到此,makefile可以修改为

makefile 复制代码
src = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(src))

target=app
CC=gcc
CPPFLAGS=-I ./

$(target):$(obj)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) -c $^ -o $@ $(CPPFLAGS)

5.伪目标

5.1.clean

我们每次make后都会产生.o文件以及可执行文件,当我们需要重新编译的时候,我们需要手动清理,make为我们提供了清理的机制,我们在makefile中编写clean即可。因为只有目标,没有依赖,又被称为伪目标

当我们clean的命令出错时应该如何处理呢?在指令前加上"-"

写法如下:

makefile 复制代码
clean:
	-rm -rf *.o $(target)

5.2. .PHONY

如果目录中存在名为 clean 的文件,make 会认为它们已经是最新的而不执行规则。

为避免这种情况,可以将它们声明为伪目标:

makefile 复制代码
.PHONY:clean
clean:
	-rm -rf *.o $(target)

6.最终的makefile

makefile 复制代码
src = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(src))
target=app

CC=gcc
CPPFLAGS=-I ./

.PHONY: clean

$(target):$(obj)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) -c $^ -o $@ $(CPPFLAGS)
clean:
	-rm -rf *.o $(target)
相关推荐
百万蹄蹄向前冲14 分钟前
密码都对Node.js却连不上Linux数据库
linux·mysql
彧azz15 分钟前
Linux 网络编程学习总结
linux·网络·笔记·学习·面试
aramae1 小时前
MySQL内置函数(7)
开发语言·笔记·后端·mysql·其他
susplus1 小时前
【ARM 裸机开发 (IMX6ULL-mini)】GNU工具、Makefile 工程构建、链接脚本详解|C 语言点灯 + 蜂鸣器驱动
linux·arm·makefile·imx6ull
Shadow(⊙o⊙)1 小时前
Linux进阶知识1.0
linux·运维·服务器
>Andre<2 小时前
UFS5.0标准中文全译·卷一:范围、术语与架构
android·linux·嵌入式硬件
用户0510122572962 小时前
Linux下有关QT显示环境变量设置
linux·嵌入式
闲云自留地2 小时前
告别命令恐惧症,openEuler 基础操作 + 文本 + 网络管理实战
linux·运维·云计算
剑指offer.2 小时前
ARM裸机开发-点亮LED灯
linux·服务器·嵌入式硬件
GeW2 小时前
工作忙.基础弱,也能快速拿RHCE?这套方法亲测有效
linux