Search code examples
makefilelatexgnu-maketex

Makefile always builds even when no changes


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?


Solution

  • 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 $@