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)
相关推荐
星星码️1 小时前
C++选择题练习(一)
开发语言·c++
herinspace2 小时前
管家婆实用贴-如何分离和附加数据库
开发语言·前端·javascript·数据库·语音识别
不做无法实现的梦~2 小时前
Linux 上使用 CLion 开发嵌入式,并用 Codex CLI
linux·运维·服务器
ILYT NCTR3 小时前
搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程
开发语言·后端·golang
张3233 小时前
Ansible拆分大型Playbook
linux·ansible
小雅痞3 小时前
[Java][Leetcode simple] 28. 找出字符串中第一个匹配项的下标
java·开发语言·leetcode
likerhood3 小时前
java中的不可变类(Immutable)
java·开发语言
Ulyanov3 小时前
《PySide6 GUI开发指南:QML核心与实践》 第一篇:GUI新纪元——QML与PySide6生态系统全景
开发语言·python·qt·qml·雷达电子对抗
dgaf3 小时前
谢谢 AI (打靶测试用文)
c语言·gpt·ai编程·d3d12