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.texNote 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 allIf 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).