Reputation: 247
Here is part of my makefile :
LISTEINC = $(DEST)/file.inc $(DEST)/otherfile.inc $(DEST)/anotherfile.inc
compteur = 1
$(DEST)/file: $(LISTEINC)
#action
$(DEST)/%.inc: $(DEST)/%.jpg
./script $< $compteur $(DEST) > $@
How to have the variable compteur at 1 for file, 2 for otherfile, 3 for anotherfile?
$((compteur++)) would work in bash script, but here I really don't know what the equivalent is. I tried many combination of $$ () ++ +1 etc... Nothing worked. Anyone could help me please?
Upvotes: 7
Views: 11265
Reputation: 401
Not sure if still relevant (the question is old...), but here is how you increment in GNU Make. Notes:
define inc $(if $(1),$(call inc-rec,$(next_$(firstword $(1))),$(wordlist 2,$(words $(1)),$(1))),1) endef define inc-rec $(if $(filter 0,$(1)),0 $(call inc,$(2)),$(1) $(2)) endef next_0 := 1 next_1 := 2 next_2 := 3 next_3 := 4 next_4 := 5 next_5 := 6 next_6 := 7 next_7 := 8 next_8 := 9 next_9 := 0
Upvotes: 1
Reputation: 66081
Every time a line of receipt for some target should be evaluated, it uses own shell instance. So you just cannot modify shell variable, used for building file $(DEST)/otherfile.inc
, while build file $(DEST)/file.inc
.
Instead of shell variable compteur
, you may use make variable:
$(DEST)/%.inc: $(DEST)/%.jpg
./script $< $(compteur) $(DEST) > $@
which has different values for different targets. It can be achieved by using target-specific variable values technique:
$(DEST)/file.inc: compteur = 1
$(DEST)/otherfile.inc: compteur = 2
$(DEST)/another.inc: compteur = 3
If you want to generate these variable-assignment rules, you are free to use any make facilities, working at parsing stage (as opposite to building stage, when make executes receipts for targets). E.g., you may change variable using shell
after each variable-assignment rule is generated:
# For target, given by the first parameter, set current *compteur* value.
# After issuing the rule, issue new value for being assigned to *compteur*.
define set_compteur
$(1): compteur = $(compteur) # Variable-assignment rule
compteur = $(shell echo $$(($(compteur)+1))) # Update variable's value
endef
$(foreach t,$(LISTEINC),$(eval $(call set_compteur, $(t))))
Alternatively, you may create list of possible compteur
values once, and use this list while generate variable-assignment rules:
# List of possible indicies in the list *LISTEINC*: 1 2 ...
indicies = $(shell seq $(words $(LISTEINC)))
# Corresponded *compteur* values actually are same as indicies.
compteurs = $(indicies)
# For target, specified with index, given by the first parameter, set corresponded *compteur* value.
define set_compteur
$(word $(1),$(LISTEINC)): compteur = $(word $(1),$(compteurs))
endef
$(foreach i,$(indicies),$(eval $(call set_compteur, $(i))))
Unlike to the first snippet, which parsing stage calls shell for every target in the list LISTEINC
, the second snippet calls shell only once (seq
command), which is faster.
Upvotes: 4
Reputation: 45432
It can be done with eval
:
$(eval compteur=$(shell echo $$(($(compteur)+1))))
From the manual :
The eval function is very special: it allows you to define new makefile constructs that are not constant; which are the result of evaluating other variables and functions. The argument to the eval function is expanded, then the results of that expansion are parsed as makefile syntax. The expanded results can define new make variables, targets, implicit or explicit rules, etc
Upvotes: 12