Makefile 特定于目标的递归变量预处理

Makefile 特定于目标的递归变量预处理,makefile,gnu-make,Makefile,Gnu Make,我知道如何在不丢失Makefile顶层递归特性的情况下预先编写递归变量。但我不知道在给出特定于目标的值时如何做到这一点。以代码形式 ALT1=a1 ALT2=a2 ALT3=a3 ALT4=a4 ALT5=a5 VAR=$(ALT1) $(eval VAR=$$(ALT2) $(value VAR)) ALT1=b1 ALT2=b2 ALT3=b3 ALT4=b4 ALT5=b5 top: sub1 @echo 'In top VAR is $(flavor VAR)=$(valu

我知道如何在不丢失Makefile顶层递归特性的情况下预先编写递归变量。但我不知道在给出特定于目标的值时如何做到这一点。以代码形式

ALT1=a1
ALT2=a2
ALT3=a3
ALT4=a4
ALT5=a5

VAR=$(ALT1)
$(eval VAR=$$(ALT2) $(value VAR))

ALT1=b1
ALT2=b2
ALT3=b3
ALT4=b4
ALT5=b5

top: sub1
    @echo 'In top VAR is $(flavor VAR)=$(value VAR)=$(VAR)'

sub1: VAR:=$$(ALT3) $$(VAR)
sub1: sub2
    @echo 'In sub1 VAR is $(flavor VAR)=$(value VAR)=$(VAR)'

sub2: VAR:=$(ALT4) $(VAR)
sub2:
    @echo 'In sub2 VAR is $(flavor VAR)=$(value VAR)=$(VAR)'

VAR+= $(ALT5)
ALT1=c1
ALT2=c2
ALT3=c3
ALT4=c4
ALT5=c5
显示

In sub2 VAR is simple=b4 b2 b1=b4 b2 b1
In sub1 VAR is simple=$(ALT3) $(VAR)=$(ALT3) $(VAR)
In top VAR is recursive=$(ALT2) $(ALT1)=c2 c1 c5
当我想

In sub2 VAR is recursive=$(ALT4) $(ALT3) $(ALT2) $(ALT1)=c4 c3 c2 c1 c5
In sub1 VAR is recursive=$(ALT3) $(ALT2) $(ALT1)=c3 c2 c1 c5
In top VAR is recursive=$(ALT2) $(ALT1)=c2 c1 c5
给予

In sub2 VAR is recursive=$(ALT4) $(ALT2) $(ALT1)=c4 c2 c1 c5
In sub1 VAR is recursive=$(ALT3) $(ALT2) $(ALT1)=c3 c2 c1 c5
In top VAR is recursive=$(ALT2) $(ALT1)=c2 c1 c5
可以接受,但我更喜欢以前的输出。我真的只需要最后的扩展,味道和未扩展的值只是我认为应该如何工作的一个提示


尽管有一个更广泛适用的解决方案会更好,但我只需要一个与GNU Make一起工作的解决方案。

我相信,对于此类递归变量,唯一受支持的方法是使用
+=
运算符附加新值。make在处理递归变量时特别处理了这一点,它不扩展变量内容,也不抱怨循环引用。您可能希望使用这种方法,同时反转实际生成的值,这些值也可以定义一次,即:

$ cat Makefile
ALT1=a1
ALT2=a2
ALT3=a3
ALT4=a4

VAR=$(ALT1)
$(eval VAR=$(value VAR) $$(ALT2))

define reverse
$(strip $(eval REVERSED=)$(foreach item,$(1),$(eval REVERSED=$(item) $(REVERSED)))$(REVERSED))
endef

VAR2 = $(call reverse,$(VAR))

ALT1=b1
ALT2=b2
ALT3=b3
ALT4=b4

top: sub1
        @echo 'In top VAR is $(flavor VAR)=$(value VAR)=$(VAR)'
        @echo 'In top VAR2 is $(flavor VAR2)=$(value VAR2)=$(VAR2)'

sub1: VAR += $(ALT3)
sub1: sub2
        @echo 'In sub1 VAR is $(flavor VAR)=$(value VAR)=$(VAR)'
        @echo 'In sub1 VAR2 is $(flavor VAR2)=$(value VAR2)=$(VAR2)'

sub2: VAR += $(ALT4)
sub2:
        @echo 'In sub2 VAR is $(flavor VAR)=$(value VAR)=$(VAR)'
        @echo 'In sub2 VAR2 is $(flavor VAR2)=$(value VAR2)=$(VAR2)'

ALT1=c1
ALT2=c2
ALT3=c3
ALT4=c4
请注意,定义
VAR2
,展开时会反转
VAR
。其想法是添加到
VAR
,而是扩展
VAR2
。输出:

$ make
In sub2 VAR is recursive=$(ALT4)=c1 c2 c3 c4
In sub2 VAR2 is recursive=$(call reverse,$(VAR))=c4 c3 c2 c1
In sub1 VAR is recursive=$(ALT3)=c1 c2 c3
In sub1 VAR2 is recursive=$(call reverse,$(VAR))=c3 c2 c1
In top VAR is recursive=$(ALT1) $(ALT2)=c1 c2
In top VAR2 is recursive=$(call reverse,$(VAR))=c2 c1

编辑:删除不必要的。第二次扩展

我认为这种递归变量唯一受支持的方法是使用
+=
运算符附加新值。make在处理递归变量时特别处理了这一点,它不扩展变量内容,也不抱怨循环引用。您可能希望使用这种方法,同时反转实际生成的值,这些值也可以定义一次,即:

$ cat Makefile
ALT1=a1
ALT2=a2
ALT3=a3
ALT4=a4

VAR=$(ALT1)
$(eval VAR=$(value VAR) $$(ALT2))

define reverse
$(strip $(eval REVERSED=)$(foreach item,$(1),$(eval REVERSED=$(item) $(REVERSED)))$(REVERSED))
endef

VAR2 = $(call reverse,$(VAR))

ALT1=b1
ALT2=b2
ALT3=b3
ALT4=b4

top: sub1
        @echo 'In top VAR is $(flavor VAR)=$(value VAR)=$(VAR)'
        @echo 'In top VAR2 is $(flavor VAR2)=$(value VAR2)=$(VAR2)'

sub1: VAR += $(ALT3)
sub1: sub2
        @echo 'In sub1 VAR is $(flavor VAR)=$(value VAR)=$(VAR)'
        @echo 'In sub1 VAR2 is $(flavor VAR2)=$(value VAR2)=$(VAR2)'

sub2: VAR += $(ALT4)
sub2:
        @echo 'In sub2 VAR is $(flavor VAR)=$(value VAR)=$(VAR)'
        @echo 'In sub2 VAR2 is $(flavor VAR2)=$(value VAR2)=$(VAR2)'

ALT1=c1
ALT2=c2
ALT3=c3
ALT4=c4
请注意,定义
VAR2
,展开时会反转
VAR
。其想法是添加到
VAR
,而是扩展
VAR2
。输出:

$ make
In sub2 VAR is recursive=$(ALT4)=c1 c2 c3 c4
In sub2 VAR2 is recursive=$(call reverse,$(VAR))=c4 c3 c2 c1
In sub1 VAR is recursive=$(ALT3)=c1 c2 c3
In sub1 VAR2 is recursive=$(call reverse,$(VAR))=c3 c2 c1
In top VAR is recursive=$(ALT1) $(ALT2)=c1 c2
In top VAR2 is recursive=$(call reverse,$(VAR))=c2 c1

编辑:删除不必要的。第二次扩展

有趣的方法。我认为不需要
.SECONDEXPANSION
(至少我不理解这里的目的,在一个简单的例子中,它不需要)。遗憾的是,如果我想预先结束,那是因为在构造最终值时也使用了追加,而反转没有帮助。你是对的,这个
。SECONDEXPANSION
是一些实验的遗留。有趣的方法。我认为不需要
.SECONDEXPANSION
(至少我不理解这里的目的,在一个简单的例子中,它不需要)。不幸的是,如果我想预先结束,那是因为在构造最终值时也使用了追加,而反向也没有帮助。你是对的,这个
。SECONDEXPANSION
是一些实验的遗留物。