I've got a latex project that looks like this:
project/
|-- main.tex
|-- main.bib
|-- preamble.tex
|-- preamble.fmt
|-- makefile
The preamble (preamble.tex
) is being precompiled into preamble.fmt
. main.bib
is generated using the file contents
environment in main.tex
.
This is what is in my makefile
TEX = pdflatex -shell-escape -interaction=nonstopmode -file-line-error
PRE = $(TEX) -ini -job-name="preamble" "&pdflatex preamble.tex\dump"
BIB = bibtex
.PHONY: all view
all : main.pdf
view :
open main.pdf
main.pdf : main.tex preamble.fmt main.bbl main.blg
$(TEX) main.tex
main.bbl main.blg : main.bib main.aux
$(BIB) main
main.aux : main.tex
$(TEX) main.tex
main.bib : main.tex
$(TEX) main.tex
preamble.fmt : preamble.tex
$(PRE) preamble.tex
The problem is here that bibtex
relies on main.aux
to be generated, and main.aux
is regenerated every pdftex
run. This leads to regeneration of the bibtex files every run, which causes makefile to run $(TEX) main.tex
a second time (it thinks the .bbl
and .blg
files are changed, because it looks at their edit time).
So, basically every time I call make all
latex is compiled twice, even if there are no changes to references made anywhere in the document (thus making this unnecessary).
Is there a way I can tell make
that it only compiles twice if there is an actual change to the .aux
and the .bib
files. Perhaps by checking of md5 sums?
I'm kind of new to the whole makefile thing, so I thought I'd ask here. It could be off-topic, but I thought the latex gurus that reside on this site might have an answer.
Best Answer
latexmk
is the answer you are looking for.LaTeX is notoriously difficult to "get right" using a Makefile, because it might take multiple compiler passes - updating e.g.
.aux
files - to get the finished results. Getting this right in a general Makefile (as opposed to one tailored to a specific document) is very hard, which is why there are pre-made solutions. Of these,latexmk
comes included with your average LaTeX distribution, which is why I consider it first choice.The trick is to provide a Makefile rule for every custom step x-to-TeX (or x-to-PDF or whatever) you might have, and having
latexmk
figure out all the LaTeX-related stuff while relying on the Makefile for the rest (via-use-make
).This setup works flawlessly for anything referenced via
\include
.However,
\include
might not be appropriate in every case. For one, it is not nestable (i.e. an\include
d file may not\include
another). It also adds an automatic\clearpage
to your document, i.e.\include
d content starts a new page. It also has advantages, like resulting in shorter re-build times if contents are modified, but sometimes you need nesting, or the referenced file's contents should be embedded in a page.You need
\input
for this.Sadly,
\input
breaks the build. Ifpdflatex
encounters a missing\input
file, it generates an error (instead of a warning like with\include
), and stops compiling. Yes,latexmk
will generate the file and re-startpdflatex
, but this is inefficient, and breaks completely if you have multiple such file references, because eventually the compile will end with a "too many re-runs" message.John Collins' answer to a question by me regarding this problem provides a workaround:
This macro generates a warning instead of the error of a straight
\input
, and allowslatexmk
to generate all missing files in the first pass.Note: A rule with the generic target
%.pdf: %.tex
gives you trouble once you start using\includeonly
in your document, for reasons internal and complex. That's why I used a specific rule instead of a generic one.There is actually one alternative to
latexmk
that I can also recommend. In case you are looking at a more involved project setup, you might consider CMake, for which Kenneth Moreland has done the excellent UseLATEX.cmake module.This, however, is a bit too involved to give a how-to in the scope of this answer.