具有多个规则的Makefile与模式规则共享相同的配方?

时间:2014-03-23 01:49:21

标签: makefile gnu-make

我想删除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个替换,所以我无法展开目标)

- EDIT-- 我意识到解决这个问题的一种方法是:

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

1 个答案:

答案 0 :(得分: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中一样。所以它创造了规则。

  4. b文件也会发生第2步和第3步。它类似于a文件的情况,但此时$(2)设置为字符串%_b3

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