I have the following Makefile for running pdflatex on tex source files:
MAKEFLAGS += --warn-undefined-variables
deps := mydoc.tex mydoc.cls
mydoc.pdf: $(deps)
.PHONY: build
build: $(deps)
pdflatex mydoc.tex mydoc.pdf
.PHONY: build
clean: ## Delete misc
rm -f mydoc.out mydoc.pdf mydoc.aux mydoc.log
When I run make build
it always runs pdflatex even though mydoc.tex
has not changed.
My understanding is make build
should say there is nothing to do if mydoc.tex
has not changed. What am I doing wrong?
First, you've declared the target build
to be .PHONY
. The entire point of a phony target is that it will always be considered out of date and its recipe will be invoked. So, of course the recipe is always run.
Even if you remove the .PHONY
though, the recipe will always be run. You say make should do nothing is mydoc.tex
has not changed... well, how can make know that mydoc.tex
has not changed? Not changed compared to what? Make doesn't have its own database that tells it the last time it ran, and what all the timestamps on the files were at some time in the past. It simply relies on comparing timestamps of files on the filesystem as they exist now.
When you write a rule it tells make, if any of the prerequisites have a newer modification time than the target, then the target is out of date and the recipe should be run to bring it up to date.
So if you write a rule build: mydoc.tex
make will look to see if the prerequisite mydoc.tex
is newer than the target build
. Since there is no file build
and one is never created, mydoc.tex
will always be considered newer than a non-existent file, and the recipe will always be run.
You need to be sure that the target of the rule is the file that is updated by the recipe. Best practice is to ensure that every recipe you write (that updates a file) updates the file contained in the $@
automatic variable:
mydoc.pdf: $(deps)
pdflatex mydoc.tex $@