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.
bash
tag in here at all? Even when you have a line in a makefile evaluated by a shell, that shell is/bin/sh
, not bash. – Israelisraelimake
invokes a shell command, it starts a new shell. Each such shell is a separate, distinct program invocation, so of course they don't share memory. – Israelisraeli