如何编写Makefile实现目录镜像结构的多扩展名文件转换
Makefile规则修正方案
问题根源
你写的模式规则$(B)/%.bar.baz: %.foo里,%会匹配2014/05/x这类路径片段,但依赖%.foo会被解析成当前目录下的2014/05/x.foo,而实际源文件在$(A)目录下,所以Make找不到对应的依赖,才会报错。
两种可行的修正写法
写法一:调整模式规则的依赖路径
直接把依赖指向$(A)目录下的对应文件,让模式匹配能正确对应源文件路径:
AF := $(shell find $(A) -name \*.foo) BF := $(patsubst $(A)/%.foo,$(B)/%.bar.baz,$(AF)) all: $(BF) .PHONY: all $(B)/%.bar.baz: $(A)/%.foo mkdir -p $(@D) ./convert $< $@ || rm $@
写法二:使用静态模式规则
如果想要更明确的文件映射关系,用静态模式规则直接关联生成文件和源文件:
AF := $(shell find $(A) -name \*.foo) BF := $(patsubst $(A)/%.foo,$(B)/%.bar.baz,$(AF)) all: $(BF) .PHONY: all $(BF): $(B)/%.bar.baz: $(A)/%.foo mkdir -p $(@D) ./convert $< $@ || rm $@
补充说明
find命令会递归遍历$(A)下所有.foo文件,包括year/month子目录里的,完全符合你的目录结构需求。mkdir -p $(@D)会自动创建目标文件需要的所有父目录,不用手动提前创建$(B)下的year/month结构。- 转换命令末尾的
|| rm $@是为了在转换失败时自动删除生成的无效文件,避免残留垃圾文件。
内容的提问来源于stack exchange,提问作者Darko Veberic
相关产品推荐
相关产品推荐

