Reputation: 2080
I have a Makefile which looks like this:
.PHONY: aws-deps
requirements.txt: Pipfile Pipfile.lock
pipenv lock -r > $@
aws-deps: requirements.txt
pip3 install --upgrade --target aws_src/ -r $<
If I run make requirements.txt
more than once, it correctly says it's up to date. But if I run make aws-deps
it doesn't behave as I expect a .PHONY
target to, it runs every time regardless of whether requirements.txt
has changed. For example, deleting requirements.txt first:
$ make aws-deps
pipenv lock -r > requirements.txt
pip3 install --upgrade --target aws_src/ -r requirements.txt
<snip>
$ make aws-deps
pip3 install --upgrade --target aws_src/ -r requirements.txt
<snip>
Am I mis-understanding what .PHONY
deps do? I want aws-deps to only do something if its prerequisite has changed, ie I have a change in requirements.txt - does anybody know what I'm missing in getting that to work?
Thanks!
Upvotes: 1
Views: 707
Reputation: 1206
I went through similar case. I wasn't too much of a fan of creating another file .hidden or visible. But that is what I've seen a lot around. I went to the GNU make manual [who does that ANYMORE?], hoping that the authors had considered something so obvious. I found the target .INTERMEDIATE
, which is not expecting a file update. So, your example would be then:
requirements.txt: Pipfile Pipfile.lock
pipenv lock -r > $@
.INTERMEDIATE: aws-deps
aws-deps: requirements.txt
pip3 install --upgrade --target aws_src/ -r $<
It works well and does not require writing an extra file as a flag. I used this .INTERMEDIATE
target type to print a message before a mass compilation of PDF files and another message for similar mass compilation of PNG files. If you try to use .PHONY
the compilation will repeat. If you print the message inside the rules block, it will print for every file that is being processed. Printing a one-time message is another use of .INTERMEDIATE
.
Upvotes: 1
Reputation: 38267
.PHONY
targets tell make to treat a target as not being a file, even though there might be a file that has a name identical to this target. As there is no file named aws-deps
here, .PHONY
has no real influence in your case. Instead, make has nothing to compare the timestamp of requirements.txt
to and assumes that the rule for aws-deps
must be run. You might change this behavior by
AWS_DEP = .aws-deps-done # hidden file to compare a timestamp against
.PHONY: aws-deps
aws-deps: $(AWS_DEP)
$(AWS_DEP): requirements.txt
pip3 install --upgrade --target aws_src/ -r $<
@touch $@
Upvotes: 5