制作宏前缀和扩展
Make macro prefix and expansion
考虑以下代码:
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
您的 Makefile 语法表明您已经在依赖 GNU Make。在 Make 的那个特定实现中,您可以通过模式替换获得您想要的东西。这种情况的缩写形式是
all: $(MODELS:%=model_%)
等等。
您可以将相同的方法应用于多个脚本,方法是扩展为按顺序运行每个脚本的单个 bash 命令。将模式生成的目标与所需规则相匹配有一些技巧,但只要您已经依赖 GNU make,您也可以完全使用模式规则:
$(MODELS:%=model_%): model_%: files/%.csv
bash -c "$(FUNCTIONS:%=./%/$*.sh; ) :"
更新:
如果您需要使这些目标也依赖于 shell 脚本,那么您可以这样做。需要理解的是模式替换匹配=
左边的first%
作为通配符,替换掉first 出现在右侧的 =
与任何匹配。其他 %
个字符保留在结果中,并且可以根据模式规则语法进行解释。因此,您可以这样做:
$(MODELS:%=model_%): model_%: files/%.csv $(FUNCTIONS:%=./%/%.sh)
bash -c "$(FUNCTIONS:%=./%/$*.sh; ) :"
根据您对 $(FUNCTIONS)
的定义,表达式 $(FUNCTIONS:%=./%/%.sh)
扩展为 ./startup1/%.sh ./startup2/%.sh ./finalize1/%.sh ./postcode/%.sh
,保留模式规则以将剩余的 %
通配符匹配到每个 model_foo
目标的名称。
考虑以下代码:
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
您的 Makefile 语法表明您已经在依赖 GNU Make。在 Make 的那个特定实现中,您可以通过模式替换获得您想要的东西。这种情况的缩写形式是
all: $(MODELS:%=model_%)
等等。
您可以将相同的方法应用于多个脚本,方法是扩展为按顺序运行每个脚本的单个 bash 命令。将模式生成的目标与所需规则相匹配有一些技巧,但只要您已经依赖 GNU make,您也可以完全使用模式规则:
$(MODELS:%=model_%): model_%: files/%.csv
bash -c "$(FUNCTIONS:%=./%/$*.sh; ) :"
更新:
如果您需要使这些目标也依赖于 shell 脚本,那么您可以这样做。需要理解的是模式替换匹配=
左边的first%
作为通配符,替换掉first 出现在右侧的 =
与任何匹配。其他 %
个字符保留在结果中,并且可以根据模式规则语法进行解释。因此,您可以这样做:
$(MODELS:%=model_%): model_%: files/%.csv $(FUNCTIONS:%=./%/%.sh)
bash -c "$(FUNCTIONS:%=./%/$*.sh; ) :"
根据您对 $(FUNCTIONS)
的定义,表达式 $(FUNCTIONS:%=./%/%.sh)
扩展为 ./startup1/%.sh ./startup2/%.sh ./finalize1/%.sh ./postcode/%.sh
,保留模式规则以将剩余的 %
通配符匹配到每个 model_foo
目标的名称。