动态生成Makefile规则

问题描述 投票:2回答:2

我有一个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技术来实现这一目标。请帮助。

makefile
2个回答
3
投票

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

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

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

请注意,GNU中的所有defineforeach这些东西都是特定的-其他make风味不支持。


2
投票

好,所以我终于设法做到了:

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

为了更好的解释,我将其分解:

$(foreach _rule, $(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,$@be project2-clean),我们用空格替换-以获取project2 clean并进行最后的工作,直到在此处为clean。然后,我们对其进行评估以将其存储到_rule

$(eval _proj := $(@:%-$(_rule)=%))

我们使用相同的技术将项目名称存储到_proj中。我们只使用模式替换来删除规则名称和破折号。

@$(MAKE) $(ARGS) $(PROJECT_DIR)$(_proj) $(_rule)

最后,我们将我们的子makefile文件称为正确的路径和正确的规则!

© www.soinside.com 2019 - 2024. All rights reserved.