mamacdon
mamacdon

Reputation: 3179

Unexpected execution order when pattern rule depends on another pattern rule

I'm having trouble getting targets to execute in the order I expect. This is my Makefile:

.PHONY: deploy.%
deploy.%: DEPLOY_ENV=$*
deploy.%: fetch.% publish
    @echo "[deploy] $(DEPLOY_ENV)"

.PHONY: publish
publish:
    @echo "[publish]"

.PHONY: fetch.%
fetch.%: DEPLOY_ENV=$*
fetch.%:
    @echo "[fetch] $(DEPLOY_ENV)"

This is the command I'm running:

make deploy.dev

Desired output

I want the fetch target to run before publish, like this:

[fetch] dev
[publish]
[deploy] dev

Actual output

Make always runs the publish target first:

[publish]
[fetch] dev
[deploy] dev

Debug output

$ make --debug=i deploy.dev
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin11.3.0
Reading makefiles...
Updating goal targets....
 File `deploy.dev' does not exist.
 Looking for an implicit rule for `deploy.dev'.
 Trying pattern rule with stem `dev'.
 Trying implicit prerequisite `fetch.dev'.
 Trying pattern rule with stem `deploy.dev'.
 Trying implicit prerequisite `deploy.dev,v'.
 Trying pattern rule with stem `deploy.dev'.
 Trying implicit prerequisite `RCS/deploy.dev,v'.
 Trying pattern rule with stem `deploy.dev'.
 Trying implicit prerequisite `RCS/deploy.dev'.
 Trying pattern rule with stem `deploy.dev'.
 Trying implicit prerequisite `s.deploy.dev'.
 Trying pattern rule with stem `deploy.dev'.
 Trying implicit prerequisite `SCCS/s.deploy.dev'.
 Trying pattern rule with stem `dev'.
 Trying implicit prerequisite `fetch.dev'.
 Looking for a rule with intermediate file `fetch.dev'.
  Avoiding implicit rule recursion.
  Trying pattern rule with stem `dev'.
 Trying rule prerequisite `publish'.
 Found an implicit rule for `deploy.dev'.
   File `publish' does not exist.
  Must remake target `publish'.
[publish]
  Successfully remade target file `publish'.
  File `fetch.dev' does not exist.
 Must remake target `fetch.dev'.
[fetch] dev
 Successfully remade target file `fetch.dev'.
Must remake target `deploy.dev'.
[deploy] dev
Successfully remade target file `deploy.dev'.

Upvotes: 2

Views: 56

Answers (1)

Vroomfondel
Vroomfondel

Reputation: 2898

The problem is that it is impossible to formulate the dependency of publish on the deploy-selected fetch target as a pattern rule. You can help yourself here tho, with a bit of programming. We select those given goals (from the command line) which match a deploy.% pattern and substitute them to make fetch.% prerequisites of them:

.PHONY: deploy.%
deploy.%: DEPLOY_ENV=$*
deploy.%: fetch.% publish
    @echo "[deploy] $(DEPLOY_ENV)"

.PHONY: publish
publish: $(patsubst deploy.%,fetch.%,$(filter deploy.%,$(MAKECMDGOALS)))
    @echo "[publish]" $^

.PHONY: fetch.%
fetch.%: DEPLOY_ENV=$*
fetch.%:
    @echo "[fetch] $(DEPLOY_ENV)"

Upvotes: 1

Related Questions