【问题标题】:Makefile with multiple rules sharing same recipe with patternrules?具有多个规则的 Makefile 与 patternrules 共享相同的配方?
【发布时间】:2014-04-30 10:23:56
【问题描述】:

我想删除 makefile 中重复的配方,如下所示

SHELL := /bin/bash
a_% : a1_% a2_%       
          cat $^ > $@                                                                                                                             
b_% : b1_% b2_%   %_b3                                                                                                                         
          cat $^ > $@   

但是以下方法不起作用。我猜this SO question 中的技巧不适用于模式规则。

SHELL := /bin/bash
a_% : a1_% a2_%       
b_% : b1_% b2_%   %_b3                                                                                                                         
a_% b_%:
          cat $^ > $@   

有什么建议吗? (在我原来的 makefile 中,配方重复发生在 4 个目标中,每个目标需要 3 个替换,所以我无法展开目标)

--编辑-- 我意识到解决此问题的一种方法如下。

CMD1 = cat $^ > $@
a_% : a1_% a2_%       
         $(CMD1)
b_% : b1_% b2_%   %_b3
        $(CMD1)

【问题讨论】:

  • 没有办法组合模式规则。您能做的最好的事情就是像您所做的那样:对配方使用相同的变量。

标签: makefile gnu-make


【解决方案1】:

我相信这可以满足您的要求:

SHELL := /bin/bash

define STUFF
$(1)_%: $(1)1_% $(1)2_% $(2)
    cat $$^ > $$@
endef

$(eval $(call STUFF,a))
$(eval $(call STUFF,b,%_b3))

这是如何工作的:

  1. 规则的一般形式定义为STUFF。 (您显然希望在自己的 Makefile 中有一个更好的名称。)请注意 $$^$$@ 中美元符号的两倍。这可以保护它们在执行 $(call ...) 时免于评估。 $(1)$(2) 将替换为带有位置参数的 $(call ...)

  2. $(call STUFF,a)“调用”STUFF$(1) 设置为字符串 a$(2) 设置为空字符串。返回值为:

    a_%: a1_% a2_% 
        cat $^ > $@
    

    注意一个$ 是如何从其余变量中删除的。

  3. $(eval ...) 评估在上一步中获得的返回值,就好像该字符串已放入 Makefile 中一样。所以它创建了规则。

步骤 2 和 3 也适用于 b 文件。它类似于 a 文件所发生的情况,只是这次 $(2) 设置为字符串 %_b3

这本质上是我过去使用的方法,以避免在规则相当复杂的情况下重复规则。对于您在问题中显示的特定案例,我将使用您在问题中提到的共享命令变量。

【讨论】:

    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 2018-02-18
    • 2014-12-08
    相关资源
    最近更新 更多