Still running pdflatex
(or equivalent) every time you want to recompile your document? There’s a simpler way using make
and latexmk
. All you need is a simple Makefile
and you can tell to automatically recompile your document every time you change a file, and run pdflatex
the sufficient number of times to get cross-references right.
So I recently discovered latexmk
, a utility that simplifies compilation by automatically rerunning whatever compilation command you use to compile your documents (i.e. pdflatex
, xelatex
or whatever) the sufficient number of times in order to make sure cross-references resolve themselves fully.This in itself is super useful, but you can leverage the power of GNU make
in addition to this to make compilation easy, continual and targeted only at changed files.
For the purposes of this article, I assume that you’re using pdflatex
, but all of this equally applies to xelatex
or similar by simply replacing the pdflatex
command with whichever you use.
latexmk
The basic syntax of latexmk
is as follows:
1$ latexmk $OPTIONS -pdflatex="$COMPILATION_COMMAND $PDFLATEX_OPTIONS %O %S" yourtexfile.tex
Note that %O
is replaced by latexmk
with the options given to latexmk
, and %S
is replaced with the source file name, in this example yourtexfile.tex
. Some useful options to give to latexmk
include -pdf
, which tells latexmk
that your final produced document is a pdf
, and -pvc
, which will be discussed shortly. latexmk
also summarises the errors and warnings incurred throughout the compilation, which is very useful considering they’re usually lost in a sea of output during normal pdflatex
compilation.
This will automatically run pdflatex
enough times to get those references resolved. But we can make this even more useful using the pdflatex
option, --interaction=nonstopmode
. This means that pdflatex
automatically goes through the compilation, not requiring any user input. This importantly means that it goes right through any errors, not requiring the user to type X
in to quit the compilation on error. If you prefer less verbose output, you can change --interaction=nonstopmode
to --interaction=batchmode
, which does the same thing, but outputs only succint, important information.
The next useful option to pass to latexmk
in combination with this is -pvc
. It’s purpose is to run continuously, and update your pdf viewer every time it updates your document.
make
Finally, we can wrap all this in a Makefile
so we don’t have to type the long latexmk
command in, and to detect changes in files so you’re not recompiling your file on no change.
Here’s a basic template for using make
to simply this whole thing:
1LATEX=pdflatex2LATEXOPT=--shell-escape3NONSTOP=--interaction=nonstopmode4
5LATEXMK=latexmk6LATEXMKOPT=-pdf7CONTINUOUS=-pvc8
9MAIN=yourtexfile10SOURCES=$(MAIN).tex Makefile yourothertexfiles11FIGURES := $(shell find figures/* images/* -type f)12
13all: $(MAIN).pdf14
15.refresh:16 touch .refresh17
18$(MAIN).pdf: $(MAIN).tex .refresh $(SOURCES) $(FIGURES)19 $(LATEXMK) $(LATEXMKOPT) $(CONTINUOUS) \20 -pdflatex="$(LATEX) $(LATEXOPT) $(NONSTOP) %O %S" $(MAIN)21
22force:23 touch .refresh24 rm $(MAIN).pdf25 $(LATEXMK) $(LATEXMKOPT) $(CONTINUOUS) \26 -pdflatex="$(LATEX) $(LATEXOPT) %O %S" $(MAIN)27
28clean:29 $(LATEXMK) -C $(MAIN)30 rm -f $(MAIN).pdfsync31 rm -rf *~ *.tmp32 rm -f *.bbl *.blg *.aux *.end *.fls *.log *.out *.fdb_latexmk33
34once:35 $(LATEXMK) $(LATEXMKOPT) -pdflatex="$(LATEX) $(LATEXOPT) %O %S" $(MAIN)36
37debug:38 $(LATEX) $(LATEXOPT) $(MAIN)39
40.PHONY: clean force once all
If you don’t like latexmk
running continuously, and want to run make manually, or use something like watch -n 1 make
to update your document, then just get rid of the -pvc
option in LATEXMKOPT
. Otherwise, if you only need to compile the document once and don’t need to run latexmk
continuously for recompilation, just run make once
.
Using this template and copying it across your documents hugely saves time on continually retyping in the compilation command, and means you can leave latexmk
running in the background and ignore it (unless there’s an error, in which case you can run make debug
to view the errors).