Makefile中%与*的区别:patsubst语句差异及适用场景咨询
Makefile中
%与*的区别及适用场景 在Makefile里,%和*是完全不同的符号,绝非作用相同,你遇到的现象正是二者本质差异的体现:
核心区别
1. %:Makefile模式匹配符
%是Makefile专为模式替换、模式规则设计的占位符,它的作用是匹配任意长度的非空字符串,并且在替换时可以引用匹配到的内容。
在你使用的patsubst函数中:
CXX_OBJECTS = $(patsubst $(SOURCE_DIR)/%.cc, $(BUILD_DIR)/%.o, $(CXX_SOURCES))
这里的%会匹配每个源文件路径中,$(SOURCE_DIR)/和.cc之间的部分。比如某个源文件是src/main.cc,%就匹配main,替换后就变成build/main.o,实现了路径和后缀的同步替换。
2. *:Shell通配符
*是Shell环境下的通配符,但在Makefile的函数(比如patsubst)中,它只是一个普通字符,不会被解析为匹配符号。
你第二条语句里的$(SOURCE_DIR)/*.cc,在patsubst的逻辑里就是字面意义的字符串,只有当CXX_SOURCES中存在完全等于$(SOURCE_DIR)/*.cc的条目时才会被替换——但你的源文件都是具体的文件名(比如src/main.cc),根本匹配不上,所以最终返回的还是原.cc文件列表。
适用场景
%的适用场景
- 模式替换:用
patsubst、vpath等功能时,对一批文件做结构化的路径/后缀替换,比如批量将源文件路径转为目标文件路径。 - 模式规则:编写批量编译规则时,比如:
一条规则就能匹配所有$(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.cc $(CXX) $(CXXFLAGS) -c $< -o $@.cc到.o的编译需求,无需为每个文件单独写规则。
*的适用场景
- 批量获取文件列表:配合
wildcard函数获取指定目录下的所有符合后缀的文件,比如:
这里的CXX_SOURCES = $(wildcard $(SOURCE_DIR)/*.cc)*会被解析为通配符,自动收集SOURCE_DIR下所有.cc文件。 - Shell命令中的批量操作:在规则的命令部分使用,比如清理所有目标文件:
这里的clean: rm -f $(BUILD_DIR)/*.o*会被Shell解析,删除BUILD_DIR下所有.o文件。
内容的提问来源于stack exchange,提问作者Rudransh Srivastava
相关产品推荐
相关产品推荐

