生成动态Makefile规则

时间:2017-04-12 21:21:03

标签: makefile

我有一个Makefile,我用它来调用不同的子Makefile。

我有几条规则:

  • 所有
  • 清洁
  • fclean
  • RE

我已经可以使用这些规则,它们将使用相同的规则调用每个子makefile。

我有几个项目,我想用这种格式生成规则:

$(PROJECT_NAME)-$(RULES)

有了这个,我想为每个项目制定每个规则:

project1-all

project1-clean

...

project2-all

project2-clean

...

通过这种方式,我可以针对特定项目调用特定规则,例如project1-fclean

我试过了:

RULES=    all clean fclean re

PROJECTS= project1 project2

define NEWLINE

endef

$(foreach _rule, $(RULES),                                              \
    $(foreach _proj, $(PROJECTS),                                           \
$(_proj)-$(_rule):                                           $(NEWLINE) \
            $(MAKE) $(ARGS) $(PROJECT_DIR)$(_proj) $(_rule) $(NEWLINE)  \
    )                                                                     \
)

但它似乎不起作用。我已经搜索过,但我还没有找到先进的makefile技术来实现这一目标。 Plz帮助。

2 个答案:

答案 0 :(得分:2)

问题在于,当您将线条与线条连续组合在一起时,它会压缩所有换行符和其他无关的空白(包括您尝试使用$(NEWLINE)插入的那些换行符),从而导致单行上的巨大混乱,而不是具有多个模式的多行。要正确执行此操作,您需要将规则编写为带参数的宏,然后调用它:

define PROJ_RULE
$(1)-$(2):
        $(MAKE) $(ARGS) $(PROJECT_DIR)$(1) $(2)
endef

$(foreach _rule, $(RULES),
    $(foreach _proj, $(PROJECTS),
        $(call PROJ_RULE, $(_proj), $(_rule))))

请注意,GNU中的所有defineforeach内容都是特定的 - 其他品牌风格不支持它。

答案 1 :(得分:2)

好的,所以我终于设法这样做了:

$(foreach _rule, $(RULES), $(addsuffix -$(_rule),$(PROJECTS))):
            $(eval _rule := $(lastword $(subst -, ,$@)))
            $(eval _proj := $(@:%-$(_rule)=%))
            @$(MAKE) $(ARGS) $(PROJECT_DIR)$(_proj) $(_rule)

我将分解它以获得更好的解释:

$(foreach _rule, $(RULES), ...)):

我们循环每个RULES并将其存储在_rule。

$(addsuffix -$(_rule),$(PROJECTS))

我们将该规则添加为每个项目的前缀。此部分生成一个包含每个“组合规则”的规则。 projet1project2会导致:

project1-all project2-all project1-clean project2-clean project1-fclean project2-fclean project1-re project2-re:

这样,对于这些规则名称中的任何一个,都将执行相同的规则。

$(eval _rule := $(lastword $(subst -, ,$@)))

我们采取目标(如果我调用project2-clean,$@ project2-clean),我们将-替换为空格以获取{ {1}}并完成最后的工作,这将是project2 clean。然后我们对其进行评估以将其存储到clean

_rule

我们使用相同的技术将项目名称存储到$(eval _proj := $(@:%-$(_rule)=%)) 中。我们只使用模式替换,删除规则名称和破折号。

_proj

最后,我们将submakefile称为正确的路径和正确的规则!