2017-04-12 112 views
0

我有一个Makefile用于调用不同的子Makefiles。动态生成Makefile规则

我有几个规则:

  • 所有
  • 干净
  • fclean
  • 重新

我已经可以用这些规则,它将调用每个子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的帮助。

+0

而不是递归地调用'make',我建议看看非递归的'makefile'方法。有一篇关于递归make的缺点的文章:http://www.linux-mag.com/id/2101/。你可以尝试我的模板库的非递归生成文件:https://github.com/igagis/prorab/blob/master/wiki/TutorialBasicConcepts.md – igagis

回答

1

好了,我终于成功地做到这样说:

$(foreach _rule, $(RULES), $(addsuffix -$(_rule),$(PROJECTS))): 
      $(eval _rule := $(lastword $(subst -, ,[email protected]))) 
      $(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 -, ,[email protected]))) 

下面我们就目标(如果我叫项目2清洁,[email protected]project2-clean),我们用空格代替-获得project2 clean,走的最后一部作品,至极将clean这里。然后我们评估它将其存储到_rule

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

我们使用相同的技术将项目名称存储到_proj。我们只是使用模式替换来删除规则名称和短划线。

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

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

1

问题是,当你将线条与线条连续结合在一起时,它会压缩掉所有换行符和其他无关的空白(包括那些你试图插入的换行符),导致单一的大量混乱线,而不是多行与多个模式。为了正确地做到这一点,你需要写您的规则与参数的宏,然后调用它:

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

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

注意,所有这defineforeach东西在GNU做出具体的 - 让其他口味不支持它。

+0

它似乎并没有为我工作,它告诉我'多个目标pattern'。我知道你不能将多于一个模式作为目标(比如'%.o'),并且这一切都取决于它是否'$(1) - $(2)'是一个模式或不是。我猜是。我现在发现了一个“丑陋”的解决方案,但你的看起来更加美观。 – Ludonope

+0

是的,如果'$(PROJECTS)'或'$(RULES)'中有任何'%',这将不起作用,但是你的例子似乎并不需要'%'在任何地方,所以我不是确定它们来自哪里。 –