如何用GNU Make自动构建所有特定后缀的目标?
Makefile自动构建所有特定后缀目标的实现方法
场景说明
你现在有这样的Makefile,每个.zip目标对应同目录下的.txt源文件:
./foo/foo.zip: ./foo/foo.txt do_something -i ./foo/foo.txt -o ./foo/foo.zip ./bar/bar.zip: ./bar/bar.txt do_something -i ./bar/bar.txt -o ./bar/bar.zip
手动指定all-zips目标的方式需要逐个列出所有.zip文件:
all-zips: ./foo/foo.zip ./bar/bar.zip .PHONY: all-zips
但你希望能像all-zips: *.zip这样自动匹配所有.zip目标,无需手动逐个添加。
实现方法
直接用*.zip不行,因为Makefile的通配符*只会匹配已存在的文件,如果.zip文件还没生成,就无法被识别。正确的做法是先找到所有.txt源文件,再转换成对应的.zip目标:
完整示例Makefile
# 匹配指定目录下的所有.txt源文件 TXT_FILES := $(wildcard ./foo/*.txt ./bar/*.txt) # 将每个.txt路径替换为对应的.zip路径 ZIP_FILES := $(patsubst %.txt, %.zip, $(TXT_FILES)) # 自动生成all-zips目标的依赖列表 all-zips: $(ZIP_FILES) # 用静态模式规则统一处理所有.zip目标的构建逻辑,替代重复的规则 %.zip: %.txt do_something -i $< -o $@ .PHONY: all-zips
关键说明
$(wildcard ...):匹配指定路径下的所有.txt文件(源文件一般预先存在,可正常识别)$(patsubst %.txt, %.zip, $(TXT_FILES)):批量将.txt后缀替换为.zip,生成完整的待构建目标列表%.zip: %.txt:静态模式规则,定义所有.zip目标的通用构建逻辑,$<代表依赖的.txt文件,$@代表当前要构建的.zip目标,避免重复编写相同命令
后续新增类似./baz/baz.txt的源文件时,all-zips会自动识别并构建对应的./baz/baz.zip,无需修改all-zips目标的依赖列表。
内容的提问来源于stack exchange,提问作者Ramón J Romero y Vigil
相关产品推荐
相关产品推荐

