我有一个Makefile,可用来调用不同的子Makefile。
我有几个规则:
我已经可以使用这些规则,它将使用相同的规则调用每个子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技术来实现这一目标。请帮助。
问题是,当您将这样的行与连续行合并在一起时,它会压缩所有换行符和其他多余的空格(包括您尝试用$(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中的所有define
和foreach
这些东西都是特定的-其他make风味不支持。
好,所以我终于设法做到了:
$(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))
我们将该规则添加为每个项目的前缀。这部分生成包含每个“组合规则”的规则。使用projet1
和project2
,结果应为:
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文件称为正确的路径和正确的规则!