The following make-based approach provides the automatic re-generation of the precompiled preamble if any of its dependents (transitive closure) have changed.
It is based on -recorder
option of pdflatex
that, when compiling a file generates a list of all INPUT and OUTPUT files that had been accessed during the process. This list is then transformed by some sed
script to extract a list of make-compatible dependencies. Using this list, make
automatically rebuild the preamble if one of its input files have changed.
Minimal Working Example
First, the source files needed to test the approach (MWE)
preamble.tex
:
\documentclass{article}
\usepackage{lipsum}
\usepackage{tikz}
\input{figure}
Note that, besides some packages, preamble.tex
also \input
's a local file figure.tex
:
\newcommand{\myfig}{%
\tikz \draw[thick,rounded corners=8pt]
(0,0) -- (0,2) -- (1,3.25) -- (2,2) -- (2,0) -- (0,2) -- (2,2) -- (0,0) -- (2,0);
}
In the example this serves a local dependency for the precompiled preamble. Hence, editing figure.tex
or a simple touch figure.tex
should cause the precompiled preamble to be re-generated.
Finally, we have our main.tex
\begin{document}
\myfig
\lipsum
\end{document}
So here comes the Makefile
that puts it all together. Just do a make
and it will generate the precompiled preamble main.fmt
and then main.pdf
. Subsequent changes to main.tex
will not trigger a regeneration of main.fmt
. If, however, you touch preamble.tex
or figure.tex
, this will be detected and main.fmt
will be re-generated:
#####################################################################
#
# Generate depencendcies for precompiled preamble
#
#####################################################################
# standard options passed to sed: include only lines beginning with INPUT,
# remove the INPUT as well as trailing ./ from paths
CREATE_DEPS_OPTIONS = -e '/^INPUT /!d' -e 's/^INPUT //' -e 's/^\.//'
# in order to not check large parts of the local/global texmf-tree we exclude all paths that start with:
# / or texmf/
DEPS_EXCLUDE ?= ^/ ^texmf/
CREATE_DEPS_OPTIONS += $(foreach d,$(DEPS_EXCLUDE), -e '/$(subst /,\/,$(d))/d')
# This includes the extracted deps
MAIN_DEPS= $(shell touch main.fls ; \
cat main.fls | \
sed $(CREATE_DEPS_OPTIONS) | \
sort -u | \
xargs)
all: main.pdf
main.fmt : $(MAIN_DEPS)
@echo "****************************************"
@echo $? changed, hence recompiling precompiled preamble
@echo "****************************************"
@pdflatex -recorder -ini -jobname=main "&pdflatex preamble.tex\dump"
main.pdf : main.fmt main.tex
@pdflatex -fmt ./main main
clean :
@rm *.log *.aux *.pdf *.fmt *.fls
Implementation Details
The command
pdflatex -recorder -ini -jobname=main "&pdflatex preamble.tex\dump"
builds the precompiled preamble main.fmt
with the -recorder
option. With this option, pdflatex
generates a list of input and output files main.fls
it accessed during the run that looks as follows:
PWD /Users/lohmann/projects/stackexchange/precompiled
INPUT /opt/local/etc/texmf/texmf.cnf
INPUT /opt/local/var/db/texmf/web2c/pdftex/pdflatex.fmt
INPUT preamble.tex
OUTPUT main.log
INPUT /opt/local/share/texmf-texlive-dist/tex/latex/base/article.cls
INPUT /opt/local/share/texmf-texlive-dist/tex/latex/base/article.cls
INPUT /opt/local/share/texmf-texlive-dist/tex/latex/base/size10.clo
INPUT /opt/local/share/texmf-texlive-dist/tex/latex/base/size10.clo
INPUT /opt/local/share/texmf-texlive-dist/tex/latex/lipsum/lipsum.sty
INPUT /opt/local/share/texmf-texlive-dist/tex/latex/lipsum/lipsum.sty
... <lots of more data>
INPUT figure.tex
INPUT figure.tex
OUTPUT main.fmt
In the definition of the MAIN_DEPS
variable, the INPUT
lines from this list are extracted (via sed
and xargs
) into a sequence of file names that can be used as make dependencies. With DEPS_EXCLUDE
one can pass regular expressions of patterns that should be ignored; in the example I use this to ignore dependencies from the global texmf tree to speed up the deduction process within make. If you really want all dependencies to be checked every time, just set it to an empty string.
make
know, out of the box, how to track dependencies or how to build LaTeX custom format files? – krlmlr Mar 27 '12 at 21:16