考虑以下代码:
all: model_aaa model_bbb model_ccc
.PHONY: all model_aaa model_bbb model_ccc
model_aaa: files/aaa.csv
@bash ./startup/aaa.sh
model_bbb: files/bbb.csv
@bash ./startup/bbb.sh
model_ccc: files/ccc.csv
@bash ./startup/ccc.sh
现在我需要做一些改变:
MODELS:= aaa bbb ccc
FUNCTIONS:= startup1 startup2 finalize1 postcode
all: model_$(MODELS) # it does not convert to what I need
.PHONY: all model_$(MODELS) # it does not convert to what I need
model_%: files/%.csv
@bash ./$(FUNCTIONS)/$*.sh #it does not do what I need.
当宏MODELS
扩展时,其前缀不会重复。我还需要在所有模型startup1
startup2
finalize1
postcode
aaa
bbb
ccc
答案 0 :(得分:1)
您的Makefile语法表明您已经依赖于GNU Make。在Make的特定实现中,您可以通过模式替换获得所需的内容。这种情况的简短形式是
all: $(MODELS:%=model_%)
等等。
您可以通过扩展到按顺序运行每个脚本的单个bash命令,对多个脚本应用相同的方法。将模式生成的目标与所需规则相匹配还有一些技巧,但只要你已经依赖于GNU make,你就可以全部使用模式规则:
$(MODELS:%=model_%): model_%: files/%.csv
bash -c "$(FUNCTIONS:%=./%/$*.sh; ) :"
<强>更新强>:
如果你需要使这些目标依赖于shell脚本,那么你可以这样做。您需要了解模式替换与%
左侧的第一个 =
匹配作为通配符,并替换第一个外观=
的右侧与匹配的任何内容。其他%
个字符保留在结果中,可以根据模式规则语法进行解释。因此,您可以这样做:
$(MODELS:%=model_%): model_%: files/%.csv $(FUNCTIONS:%=./%/%.sh)
bash -c "$(FUNCTIONS:%=./%/$*.sh; ) :"
根据您对$(FUNCTIONS)
的定义,表达式$(FUNCTIONS:%=./%/%.sh)
会扩展为./startup1/%.sh ./startup2/%.sh ./finalize1/%.sh ./postcode/%.sh
,保留模式规则以匹配剩余的%
通配符到名称的尾部每个model_foo
目标。