#
# Example makefile using mjotex and a BibTeX references database.
#
+# After defining $(PN) to be the name of your document, this will
+# compile the source file $(PN).tex to $(PN).pdf.
+#
+# To support workflows where the document is kept open in a PDF reader
+# during recompilation, the build process takes place in a separate
+# $(BUILDDIR) directory that defaults to "build". Only when the build
+# has completed do we move the resulting $(PN).pdf to the current
+# directory. This avoids renaming or modifying the open document in
+# place, which in turn helps prevent flickering, loss of bookmarks, et
+# cetera, in several PDF readers.
+
+# The build directory. Not broken? Don't fix.
+BUILDDIR=build
# The latex compiler. The SOURCE_DATE_EPOCH=0 prevents the creation
# and modification dates from being embedded as metadata into the
# output file; that in turn is important because it allows us to tell
# when the output stops changing (that is, when we are done). The
# variable is supported in pdftex v1.40.17 and later.
-LATEX = SOURCE_DATE_EPOCH=0 pdflatex -file-line-error -halt-on-error
+LATEX = SOURCE_DATE_EPOCH=0 pdflatex -file-line-error -halt-on-error --output-directory $(BUILDDIR)
# The name of this document.
#
endif
ifdef INDICES
-INDEX_SRCS = $(addsuffix .idx,$(INDICES))
-INDEX_DSTS = $(addsuffix .ind,$(INDICES))
+INDEX_SRCS = $(addprefix $(BUILDDIR)/,$(addsuffix .idx,$(INDICES)))
+INDEX_DSTS = $(addprefix $(BUILDDIR)/,$(addsuffix .ind,$(INDICES)))
endif
# The first target is the default, so put the PDF document first.
# stop when the output file stops changing! But how to encode that
# in a makefile?
#
-# At the start of this target, we call $(LATEX) to compile $(PN).tex.
-# Afterwards, we check for the existence of a "previous" file. If
-# there isn't one, then this is the first time that we've built the
-# PDF. In that case, we take the PDF that we've just built and make it
-# the "previous" file before starting all over. If, on the other hand,
-# there already *was* a "previous" file, then this is the second (or
-# third...) time that we've built the PDF. We diff the newly-built PDF
-# against the "previous" file; if they're the same, then we've
-# succeeded and stop. Otherwise, we make the new PDF the "previous"
-# one, and start all over. The end result is that we will loop until
-# the newly-created PDF and the "previous" one are identical.
-#
-$(PN).pdf: $(SRCS) $(PN).bbl $(INDEX_DSTS)
+# At the start of this rule, we call $(LATEX) to compile $(PN).tex.
+# It stores the resulting PDF in a separate "build" directory, so this
+# will not actually create or overwrite the target $(PN).pdf. If there
+# is no $(PN).pdf already, then we rename the new one to $(PN).pdf and
+# we are done. But if there was a previous version, then we compare
+# the two (new & old) versions. In either case, we rename the new one
+# over the old one. But if the two differ, then we repeat this process
+# in a loop until the just-built PDF is identical to the one from the
+# previous iteration.
+$(PN).pdf: $(SRCS) $(BUILDDIR)/$(PN).bbl $(INDEX_DSTS)
$(LATEX) $(PN).tex
- if [ -f $@.previous ] && cmp -s $@ $@.previous; then \
- rm $@.previous; \
- else \
- mv $@ $@.previous; \
- $(REMAKE_INDICES); \
- $(MAKE) $@; \
+ if [ -f $@ ]; then \
+ while ! cmp -s $@ $(BUILDDIR)/$(PN).pdf; do \
+ mv $(BUILDDIR)/$(PN).pdf $@; \
+ $(REMAKE_INDICES); \
+ $(LATEX) $(PN).tex; \
+ done; \
fi;
+ mv $(BUILDDIR)/$(PN).pdf $@
-$(PN).aux: $(SRCS)
+$(BUILDDIR):
+ mkdir $@
+
+$(BUILDDIR)/$(PN).aux: $(SRCS) | $(BUILDDIR)
$(LATEX) $(PN).tex
# the main $(PN).pdf rule, in order to avoid a chicken-and-egg problem.
# This is similar to the $(PN).aux rule above, except that an index is
# optional and there might be more than one of them.
-$(INDEX_SRCS): $(PN).tex
+$(INDEX_SRCS): $(PN).tex | $(BUILDDIR)
$(LATEX) $(PN).tex
endif
# define $BIBS but don't cite anything, you'll run into a similar
# problem. Don't do that.
#
-$(PN).bbl: $(SRCS) | $(PN).aux
+$(BUILDDIR)/$(PN).bbl: $(SRCS) | $(BUILDDIR)/$(PN).aux
ifdef BIBS
- bibtex $(PN).aux
+ bibtex $(BUILDDIR)/$(PN).aux
else
printf '' > $@
endif
.PHONY: clean
clean:
for ext in $(JUNK_EXTENSIONS); do rm -f *.$$ext; done;
- rm -rf dist/
+ rm -rf dist/ $(BUILDDIR)/
rm -f $(SAGE_LISTING_DSTS) $(INDEX_SRCS) $(INDEX_DSTS)
# If this document will be published, the publisher isn't going to
# will create a "dist" directory and copy the necessary stuff there.
#
.PHONY: dist
-dist: $(PN).bbl
+dist: $(BUILDDIR)/$(PN).bbl
mkdir -p dist
- cp $(SRCS) $(PN).bbl dist/
+ cp $(SRCS) $(BUILDDIR)/$(PN).bbl dist/
+