Reputation: 3555
My Makefile is bundling recipes to process large numbers of files in parallel (make <recipe> -j8
, etc). But before files can be processed, they need to be found with find
. This is a time consuming operation, so I only want to run it for the exact recipe that the user invoked. I can do it like this:
test: FILES=$(shell find "$(SEARCHDIR)/" -mindepth 3 -maxdepth 3 -type f ! -regex $(SOMEREGEX))
test: $(FILES)
$(FILES):
echo "do thing with file $@ here"
The problem is that since the files inherently exist already, they need to be declared as .PHONY
in order for the recipe to run, like this:
.PHONY: $(FILES)
But in order for this to work, the FILES
variable needs to exist and be populated, which requires me to run the find
command. This goes against my goal of not performing the search to find FILES
until test
is invoked. What I need is something like this:
test: FILES=$(shell find "$(SEARCHDIR)/" -mindepth 3 -maxdepth 3 -type f ! -regex $(SOMEREGEX))
test: .PHONY: $(FILES)
test: $(FILES)
$(FILES):
echo "do thing with file $@ here"
But test: .PHONY: $(FILES)
is invalid syntax and does not work.
Upvotes: 0
Views: 234
Reputation: 100856
Your makefile already doesn't work, even without the .PHONY
thing; just:
test: FILES=$(shell find "$(SEARCHDIR)/" -mindepth 3 -maxdepth 3 -type f ! -regex $(SOMEREGEX))
$(FILES):
echo "do thing with file $@ here"
fails because $(FILES)
in the target of the rule expands to the empty string when make
parses the makefile, before it's started to run the test
target.
I recommend that you use recursive make here; write your makefile like this:
FIND_FILES :=
FILES :=
ifneq ($(FIND_FILES),)
FILES := $(shell find "$(SEARCHDIR)/" -mindepth 3 -maxdepth 3 -type f ! -regex $(SOMEREGEX))
endif
test:
$(MAKE) test-recurse FIND_FILES=1
test-recurse: $(FILES)
$(FILES):
echo "do thing with file $@ here"
.PHONY: test test-recurse $(FILES)
Upvotes: 2