我有一个 Makefile,我用它来调用不同的子 Makefile。
我有几个规则:
我已经可以使用这些规则,它们将使用相同的规则调用每个子 makefile。
我有几个项目,我想用这种格式生成规则:
$(PROJECT_NAME)-$(RULES)
有了这个,我想为每个项目制定每个规则:
project1-all
project1-clean
...
project2-all
project2-clean
...
Run Code Online (Sandbox Code Playgroud)
这样,我就可以为特定项目调用特定规则,例如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) \
) \
)
Run Code Online (Sandbox Code Playgroud)
但它似乎不起作用。我已经搜索过了,但我还没有找到高级的 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)))))
Run Code Online (Sandbox Code Playgroud)
请注意,GNU中的所有这些define和foreach内容都是特定的——其他 make 风格不支持它。
好吧,我终于设法这样做了:
$(foreach _rule, $(RULES), $(addsuffix -$(_rule),$(PROJECTS))):
$(eval _rule := $(lastword $(subst -, ,$@)))
$(eval _proj := $(@:%-$(_rule)=%))
@$(MAKE) $(ARGS) $(PROJECT_DIR)$(_proj) $(_rule)
Run Code Online (Sandbox Code Playgroud)
我将对其进行分解以获得更好的解释:
$(foreach _rule, $(RULES), ...)):
Run Code Online (Sandbox Code Playgroud)
我们循环每个规则并将其存储在 _rule 中。
$(addsuffix -$(_rule),$(PROJECTS))
Run Code Online (Sandbox Code Playgroud)
我们将该规则作为前缀添加到每个项目中。这部分为每个“组合规则”生成一个规则。与projet1和project2它应该导致:
project1-all project2-all project1-clean project2-clean project1-fclean project2-fclean project1-re project2-re:
Run Code Online (Sandbox Code Playgroud)
这样,对于任何这些规则名称,都将执行相同的规则。
$(eval _rule := $(lastword $(subst -, ,$@)))
Run Code Online (Sandbox Code Playgroud)
这里我们获取目标(如果我调用project2-clean,$@将会是 project2-clean),我们-用一个空格替换来获取project2 clean并获取最后的工作,它将在clean这里。然后我们评估它并将其存储到_rule.
$(eval _proj := $(@:%-$(_rule)=%))
Run Code Online (Sandbox Code Playgroud)
我们使用相同的技术将项目名称存储到_proj. 我们只是使用模式替换来删除规则名称和破折号。
@$(MAKE) $(ARGS) $(PROJECT_DIR)$(_proj) $(_rule)
Run Code Online (Sandbox Code Playgroud)
最后,我们称我们的子makefile为正确的路径和正确的规则!