制作宏前缀和扩展

时间:2015-04-01 22:25:55

标签: gcc macros makefile gnu-make

考虑以下代码:

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

1 个答案:

答案 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目标。