Matthew Simoneau
Matthew Simoneau

Reputation: 6279

How do I define a variable which is a sequential list of integers in gmake?

Given a variable MAX, how do I create a variable LIST which contains the integers 1 to $(MAX)?

Using shell or similar is not possible for my context.

Upvotes: 0

Views: 386

Answers (3)

tripleee
tripleee

Reputation: 189679

Here is a simple recursive solution, I find it somewhat more understandable than the $(words ...) solution although I guess in the end they're not that different. For better or for worse, this is certainly more verbose.

The repeated call to $(wordlist 2,...) is a bit of a wart. Maybe it could be avoided.

count = $(call count0,$1,0 1 2 3 4 5 6 7 8 9)
count0 = $(if $(wordlist $1,$1,$(wordlist 2,1000000,$2)), \
        $(wordlist 1,$1,$(wordlist 2,1000000,$2)), \
        $(patsubst 0%,%,$(call count0,$1,$(patsubst %,0%,$2) \
                $(patsubst %,1%,$2) $(patsubst %,2%,$2) $(patsubst %,3%,$2) \
                $(patsubst %,4%,$2) $(patsubst %,5%,$2) $(patsubst %,6%,$2) \
                $(patsubst %,7%,$2) $(patsubst %,8%,$2) $(patsubst %,9%,$2))))

.PHONY: nst
nst:
        @echo 7: $(call count,7)
        @echo 51: $(call count,51)
        @echo 111: $(call count,111)

Upvotes: 0

bobbogo
bobbogo

Reputation: 15493

Looks good, though you don't need the $eval:

seq = $(if $(filter $1,$(words $2)),$2,$(call seq,$1,$2 $(words $2)))
$(error [$(call seq,10)])

or somesuch. Make will complain warning: undefined variable '2' under --warn, but you can avoid that by using $(value…).

[You probably want $(filter…) rather than $(findstring…)in your solution BTW.]

Upvotes: 1

Matthew Simoneau
Matthew Simoneau

Reputation: 6279

Here's a clumsy solution using eval:

UPTO = $(eval TEMP += $(words $(2))) \
       $(if $(findstring $(1),$(words $(2))),$(TEMP),$(call UPTO,$(1),$(2) x))
SEQUENCE_TO = $(eval TEMP := )$(strip $(call UPTO,$(1),x))

MAX := 50
LIST := $(call SEQUENCE_TO,$(MAX))

Upvotes: 0

Related Questions