如何调整Makefile实现目标文件输出到指定目录并关联对应依赖
问题:调整Makefile实现输出路径重定向
现有Makefile代码
configs = $(filter-out $(wildcard ./configs/project/*/root.yaml), $(wildcard ./configs/project/*/*.yaml)) .PHONY: compile compile: $(configs:.yaml=.sql) %.sql: %.yaml @echo "target: $@ prerequisite: $<"
执行现有代码后的输出
target: configs/project/balance/inventory.sql
prerequisite: configs/project/balance/inventory.yaml
target: configs/project/sales/order.sql
prerequisite: configs/project/sales/order.yaml
期望实现的输出
target: output/sql/inventory.sql
prerequisite: configs/project/balance/inventory.yaml
target: output/sql/order.sql
prerequisite: configs/project/sales/order.yaml
尝试的错误写法及问题
我尝试了以下写法,但未能正常工作:
configs = $(filter-out $(wildcard ./configs/project/*/root.yaml), $(wildcard ./configs/project/*/*.yaml)) outputs = $(addprefix ./output/sql/,$(notdir $(configs:.yaml=.sql))) .PHONY: compile compile: $(outputs) output/sql/%.sql: $(configs) @echo "target: $@ prerequisite: $<"
执行后仅输出:
target: output/sql/inventory.sql
prerequisite: configs/project/balance/inventory.yaml
存在的问题
- 缺少
output/sql/order.sql与configs/project/sales/order.yaml的对应输出; - 变量
$^包含两个依赖文件,但$<仅取第一个; - 最终计划将
echo命令替换为python utils/parser.py $< > $@,通过Python脚本将YAML文件转换为SQL文件输出。
解决方案
问题出在规则output/sql/%.sql: $(configs)——这个规则把所有configs都作为每个输出SQL的依赖,Make只需要找到第一个依赖就能生成目标,不会处理第二个。正确的做法是建立每个输出SQL和对应的源YAML的一对一映射,通过动态生成规则实现。
正确的Makefile写法
configs = $(filter-out $(wildcard ./configs/project/*/root.yaml), $(wildcard ./configs/project/*/*.yaml)) # 生成输出文件列表 outputs = $(addprefix output/sql/,$(notdir $(configs:.yaml=.sql))) .PHONY: compile compile: $(outputs) # 为每个输出SQL创建对应的依赖规则 define generate_rule output/sql/$(notdir $(1:.yaml=.sql)): $(1) @echo "target: $$@ prerequisite: $$<" # 后续替换为实际的Python命令:python utils/parser.py $$< > $$@ endef $(foreach cfg,$(configs),$(eval $(generate_rule $(cfg))))
写法说明
- 使用
$(foreach)遍历每个configs里的YAML文件,通过$(eval)动态生成每个输出SQL对应的规则; - 每个规则明确对应单个源YAML文件,确保
$<能正确获取到当前目标对应的依赖文件; - 后续可以直接把
echo行替换为你的Python转换命令,无需修改规则结构。
内容的提问来源于stack exchange,提问作者Ari
相关产品推荐
相关产品推荐

