在makepp中加倍“foreach”

时间:2015-09-11 22:26:21

标签: makefile

我正在尝试使用makepp执行与嵌套循环类似的操作,但无法弄清楚如何执行此操作。

这基本上就是我想做的事情。

MODULES= A B C
TEMPLATES = X Y Z


#I'd like to make a target which needs both the MODULE and TEMPLATE:

$(MODULE)/$(TEMPLATE) :
  @echo The Module is $(MODULE) and the Template is $(TEMPLATE)


#I've tried foreach, and can do something like:
$(MODULE)/$(foreach) : : foreach $(TEMPLATES)
  @echo The Module is $(MODULE) and the Template is $(foreach)

#Or I can do:
$(foreach)/$(TEMPLATE) : : foreach $(MODULES)
  @echo The Module is $(foreach) and the Template is $(TEMPLATE)

如何创建一组适用于任何MODULE / TEMPLATE目标的规则?

我希望用户能够拥有如下目标:

makepp A/Z

不是

makepp MODULE=A TEMPLATE=Z

然后如何制作一个能够完成所有模块和模板的交叉产品的目标:

makepp all
The Module is A and the Template is X
The Module is A and the Template is Y
The Module is A and the Template is Z
... 
The Module is C and the Template is X
The Module is C and the Template is Y
The Module is C and the Template is Z

1 个答案:

答案 0 :(得分:0)

这个很棘手。我不是一个makepp专家,但如果它与GNU make充分兼容,正如它声称的那样,以下内容应该与你想要的东西很接近:

MODULES     := A B C
TEMPLATES   := X Y Z
ALL         :=

define MODULE_TEMPLATE_rule
$(1)/$(2):
    @echo The Module is $(1) and the Template is $(2)

ALL += $(1)/$(2)
endef

define MODULE_rule
$(foreach template,$(TEMPLATES),$(eval $(call MODULE_TEMPLATE_rule,$(1),$(template))))
endef

$(foreach module,$(MODULES),$(eval $(call MODULE_rule,$(module))))

all: $(ALL)

这里的魔杖是foreachcalleval的混合物。 call的第一个参数是变量名。在我的示例中,这些变量是使用define-endef构造定义的,但它没有任何区别。 call扩展变量,将其下一个参数分配给$(1), $(2)... 本地变量。所以:

$(call MODULE_TEMPLATE_rule,A,X)
例如,

将返回:

A/X:
    @echo The Module is A and the Template is X

ALL += A/X

但回归并非实例化。这是eval进入场景的地方:它扩展了它的参数,结果被解析为任何make语句。 foreach用于迭代模块和模板,但您已经知道了。

请注意,ALL变量由迭代器通过模块和模板逐步构建。因此,如果您输入make all,make会在ALL中构建所有单词,即打印所有组合:

The Module is A and the Template is X
The Module is A and the Template is Y
The Module is A and the Template is Z
The Module is B and the Template is X
The Module is B and the Template is Y
The Module is B and the Template is Z
The Module is C and the Template is X
The Module is C and the Template is Y
The Module is C and the Template is Z

这就是全部。但请注意:为了有效地使用它,您必须了解make的工作原理,工作原理以及顺序。在这里,手册是强制性的。