如何编写Makefile匹配未知子目录文件并生成对应目标文件
解决Makefile批量生成对应目录下HTML文件的问题
需求是将articles/*/source.txt(*为任意单级子目录)转换为同目录下的target.html,原代码的问题在于直接拼接$(SUBDIRS)/target.html会生成错误的路径格式,导致规则无法正确匹配每个子目录的文件。
推荐解决方案:使用模式规则
模式规则是Makefile中处理批量同类型文件转换的最优方式,用%作为通配符匹配子目录名称,自动关联对应源文件和目标文件:
.PHONY: build # 获取所有待处理的source.txt文件 SOURCE_FILES := $(wildcard articles/*/source.txt) # 将source.txt路径替换为对应的target.html路径 TARGET_FILES := $(SOURCE_FILES:articles/%/source.txt=articles/%/target.html) # 构建目标依赖所有target.html文件 build: $(TARGET_FILES) # 模式规则:匹配任意子目录下的target.html,依赖同目录的source.txt articles/%/target.html: articles/%/source.txt @echo "生成 $@ 从 $<..." # 此处替换为实际的转换命令,比如用pandoc、自定义脚本等 # 示例用cat模拟生成内容,实际根据需求修改 cat $< > $@
原代码问题分析
原代码中SUBDIRS := $(wildcard article/*)获取的是子目录列表,直接写成$(SUBDIRS)/target.html会展开成类似article/dir1 article/dir2/target.html的错误路径,Make无法识别这种格式的依赖,自然无法为每个子目录生成单独的规则。
备选方案:使用foreach遍历目录
如果更习惯显式遍历目录,也可以用foreach生成每个子目录的规则:
.PHONY: build # 获取所有articles下的子目录 SUBDIRS := $(wildcard articles/*) # 构建目标依赖每个子目录下的target.html build: $(foreach dir,$(SUBDIRS),$(dir)/target.html) # 为每个子目录生成单独的规则 define SUB_RULE $(1)/target.html: $(1)/source.txt @echo "生成 $(1)/target.html 从 $(1)/source.txt..." cat $$< > $$@ endef $(foreach dir,$(SUBDIRS),$(eval $(call SUB_RULE,$(dir))))
内容的提问来源于stack exchange,提问作者monkcs
相关产品推荐
相关产品推荐

