]> gitweb.michael.orlitzky.com - beamer-mjo.git/commitdiff
GNUmakefile: use a build directory
authorMichael Orlitzky <michael@orlitzky.com>
Mon, 14 Apr 2025 17:10:30 +0000 (13:10 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Mon, 14 Apr 2025 17:10:30 +0000 (13:10 -0400)
The corresponding change to mjotex was made a while ago.

GNUmakefile

index 7d800b9766fc7dc916b248de30eb0cae401e9e14..69c35e4cfece916b316d639c3a0a16fa2c2fdba1 100644 (file)
@@ -1,13 +1,26 @@
 #
 # 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.
 #
@@ -59,30 +72,35 @@ SRCS += $(BEAMERMJOPATHS)
 # 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
+# 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
        $(LATEX) $(PN).tex
 
-       if [ -f $@.previous ] && cmp -s $@ $@.previous; then \
-               rm $@.previous; \
-       else \
-               mv $@ $@.previous; \
-               $(MAKE) $@; \
+       if [ -f $@ ]; then \
+         while ! cmp -s $@ $(BUILDDIR)/$(PN).pdf; do \
+           mv $(BUILDDIR)/$(PN).pdf $@; \
+           $(LATEX) $(PN).tex; \
+         done; \
        fi;
 
+       if grep -q 'Rerun to get' $(BUILDDIR)/$(PN).log; then \
+         $(LATEX) $(PN).tex; \
+       fi;
+
+       mv $(BUILDDIR)/$(PN).pdf $@
+
+$(BUILDDIR):
+       mkdir $@
 
-$(PN).aux: $(SRCS)
+$(BUILDDIR)/$(PN).aux: $(SRCS) | $(BUILDDIR)
        $(LATEX) $(PN).tex
 
 
@@ -102,9 +120,9 @@ $(PN).aux: $(SRCS)
 # 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
@@ -112,14 +130,14 @@ endif
 # If the output PDF exists but the log file does not, then an attempt
 # to "build the log file" (i.e. build the PDF) would do nothing. Thus
 # whenever the log file does not exist, we do a fresh build.
-$(PN).log: $(SRCS)
+$(BUILDDIR)/$(PN).log: $(SRCS)
        $(MAKE) clean
        $(MAKE)
 
 # Ensure that there are no overfull or underfull boxes in the output
 # document by parsing the log for said warnings.
 .PHONY: check-boxes
-check-boxes: $(PN).log
+check-boxes: $(BUILDDIR)/$(PN).log
        @! grep -i 'overfull\|underfull' $<
 
 # Run chktex to find silly mistakes. There is some exit code weirdness
@@ -133,7 +151,7 @@ check-chktex:
 # Ensure that there are no undefined references in the document by
 # parsing the log file for said warnings.
 .PHONY: check-undefined
-check-undefined: $(PN).log
+check-undefined: $(BUILDDIR)/$(PN).log
        @! grep -i 'undefined' $<
 
 # Run a suite of checks.
@@ -148,3 +166,4 @@ JUNK_EXTENSIONS += snm spl toc xml
 .PHONY: clean
 clean:
        for ext in $(JUNK_EXTENSIONS); do rm -f *.$$ext; done;
+       rm -rf $(BUILDDIR)/