Nicolas Hamblenne
Nicolas Hamblenne

Reputation: 111

Target-specific recursive variable preprending

I know how to prepend a recursive variable without loosing its recursive characteristic at the top level of a Makefile. But I don't know how to do that when giving a target specific value. In code form

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

displays

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

while I'd like

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

Something which gives

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

would be acceptable but I'd prefer the previous output. I really need only the final expansion, the flavor and the un-expanded value are just an hint of how I think this should work.

Although a more widely applicable solution would be nice, I need only one which works with GNU Make.

Upvotes: 0

Views: 94

Answers (1)

raspy
raspy

Reputation: 4261

I believe the only supported approach for such recursive variables is appending new values with += operator. This is specially handled by make when dealing with recursive variables not to expand variable contents and not to complain about circular reference. You might want to use this approach, while reversing the actual generated values, which may also be defined once, i.e.:

$ 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

Note defining VAR2 which would reverse VAR when expanded. The idea is to add to VAR, but expand VAR2 instead. Output:

$ 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

Edit: Removed unnecessary .SECONDEXPANSION

Upvotes: 2

Related Questions