There is no simple straightforward way to force a rule to be evaluated before a variable gets assigned. There are more complex ways. The following is for GNU make.
Let's first assume that you want to run the (slow) find
command only if the file all_mp3s
does not exist, else use its content. You can use GNU make conditionals:
ifeq ($(wildcard all_mp3s),all_mp3s)
MP3S := $(shell cat all_mp3s)
else
MP3S := $(shell $(MAKE) all_mp3s ; cat all_mp3s)
endif
all_mp3s:
find / -name "*.mp3" > $@
But I if your Makefile is more complex than this, uses MP3S
several times, and what you really want is:
- avoid running your super-slow
find
several times,
- run it only if needed (and only once),
- get the result in a file (
all_mp3s
) plus a make variable (MP3S
),
MadScientist has a wonderful GNU make trick that can be used here:
MP3S = $(eval MP3S := $$(shell find / -name "*.mp3"))$(MP3S)
all_mp3s:
printf '%s\n' '$(MP3S)' > all_mp3s
.PHONY: help clean
help:
printf 'MP3 finder\n'
clean:
rm -f all_mp3s
If the MP3S
recursively expanded make variable is expanded because some part of your Makefile is evaluated and needs its value (e.g. if you run make all_mp3s
while all_mp3s
does not exist), the find command will be run, its result stored in the variable... and the variable will be turned into a simply expanded make variable, which further expansions, if any, will reuse the same, already computed, value.
Else, if your invocation of make (e.g. make clean
or make help
) does not need MP3S
value, the find
command will not even be run.
The all_mp3s
file is generated from the value of MP3S
(instead of the opposite in the other solution).
However, there is another important thing to decide: do you want to declare all_mp3s
as a phony target:
.PHONY: all_mp3s
or not?
If you declare it as phony, the find
command will be run once and only once each time you invoke make all_mp3s
(or another goal that depends on all_mp3s
). But targets depending on all_mp3s
will always be rebuilt too, which is not necessarily what you want.
If you don't declare it as phony, and the file exists already, the find
command will not be run at all (unless the value of MP3S
is needed elsewhere in your Makefile), and the content of all_mp3s
will not be updated, which is not necessarily what you want.
As you do not give enough information in your question to decide, it is up to you.