制作宏前缀和扩展

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 目标的名称。