user5359531
user5359531

Reputation: 3555

Makefile: declare PHONY targets as recipe prerequiste

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

Answers (1)

MadScientist
MadScientist

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

Related Questions