]> gitweb.michael.orlitzky.com - mjotex.git/commitdiff
Update the makefile with my new sedative approach to finding a fixed point.
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 28 Apr 2016 20:20:27 +0000 (16:20 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 28 Apr 2016 20:20:27 +0000 (16:20 -0400)
makefile

index 6cd7eee13b7153b014dd4076b7463f6fa11fc4e8..db6de3f740e5891d921fbc6cd5cc76d81c611d9f 100644 (file)
--- a/makefile
+++ b/makefile
@@ -27,42 +27,76 @@ SRCS = $(PN).tex $(shell kpsewhich $(BIBS)) $(shell kpsewhich $(MJOTEX))
 
 # The first target is the default, so put the PDF document first.
 #
-# The voodoo here is to avoid rebuilding the project when nothing has
-# changed. Each compilation pass with pdflatex will produce a new aux
-# file, even if nothing has changed. That cases Make to think that we
-# need to regenerate the bbl file, which in turn means we need to
-# rebuild the whole project...
+# This voodoo is all designed to find a "fixed point" of calling
+# $(LATEX). When you build a LaTeX document, it requires an unknown
+# number of compilation passes. How do you know when to stop? Easy,
+# stop when the output file stops changing! But how to encode that
+# in a makefile?
 #
-# To avoid that, we save a copy of the current aux file and compare it
-# to the new one afterwards. If the files are the same, great, put the
-# old one (with the old timestamp) back. If not, we need to compile
-# again, so we just invoke $(MAKE) again on this target.
+# At the start of this target, we call $(LATEX) to compile $(PN).tex.
+# If you ignore the "sed" for now, then the next step is to check for
+# the existence of a "previous" file. If there isn't one, this is the
+# first time that we've tried to build the PDF. In that case, take the
+# PDF that we've just built and make *that* the previous file. Then
+# start all over. If there is a previous file, then this is the second
+# (or more) time that we've tried to build the PDF. We diff the PDF
+# file that we've just built against the previous file; if they're the
+# same, then we've succeeded and stop. Otherwise, we make the new PDF
+# the previous file, and start all over. The end result is that we
+# will loop until the newly-created PDF and the previous file are
+# identical.
 #
-# The process is kind of like finding a fixpoint of `make` with
-# respect to the contents of the aux file.
+# But what about the "sed" call? By default, pdflatex will compile the
+# creation date, modification date, and a unique ID into the output
+# PDF. That means that two otherwise-identical documents, created
+# seconds apart, will look different. We only need to know when the
+# *contents* of the document are the same -- we don't care about the
+# metadata -- so sed is used to remove those three nondeterministic
+# pieces of information.
 #
-# Why use the aux file and not the PDF, which is what we really care
-# about? The pdflatex tool currently embeds the creation/modification
-# time into the PDF, so every new version will differ from the last,
-# making comparisons meaningless. This is fixed in pdftex v1.40.17
-# thanks to Debian's SOURCE_DATE_EPOCH initiative. When that version
-# of pdflatex makes it into TeX Live 2016, we can replace this junk
-# with something smarter
+# The creation and modification dates should become optional in pdftex
+# v1.40.17 thanks to Debian's SOURCE_DATE_EPOCH initiative. When that
+# version of pdflatex makes it into TeX Live 2016, we can replace
+# those two sed scripts with something smarter.
 #
-$(PN).pdf: $(SRCS) $(PN).aux $(PN).bbl
-       mv $(PN).aux $(PN).aux.bak
-       $(LATEX) $< && $(LATEX) $<
-       if cmp -s $(PN).aux $(PN).aux.bak; then \
-               mv $(PN).aux.bak $(PN).aux; \
+$(PN).pdf: $(SRCS) $(PN).bbl
+       $(LATEX) $(PN).tex
+
+       sed --in-place \
+           -e '/^\/ID \[<.*>\]/d' \
+            -e "s/^\/\(ModDate\) (.*)/\/\1 (D:19700101000000Z00'00')/" \
+            -e "s/^\/\(CreationDate\) (.*)/\/\\1 (D:19700101000000Z00'00')/" \
+            $@
+
+       if [ ! -f $@.previous ]; then \
+               mv $@ $@.previous; \
+               $(MAKE) $@; \
+       fi;
+
+       if cmp -s $@ $@.previous; then \
+               rm $@.previous; \
        else \
+               mv $@ $@.previous; \
                $(MAKE) $@; \
        fi;
 
+
 $(PN).aux: $(SRCS)
-       $(LATEX) $<
+       $(LATEX) $(PN).tex
+
 
-$(PN).bbl: $(PN).aux
-       bibtex $<
+# The pipe below indicates an "order-only dependency" on the aux file.
+# Without it, every compilation of $(PN).tex would produce a new
+# $(PN).aux, and thus $(PN).bbl would be rebuild. This in turn causes
+# $(PN).pdf to appear out-of-date, which leads to a recompilation of
+# $(PN).tex... and so on. The order-only dependency means we won't
+# rebuild $(PN).bbl if $(PN).aux changes.
+#
+# As a side effect, we now need to depend on $(SRCS) here, since we
+# won't pick it up transitively from $(PN).aux.
+#
+$(PN).bbl: $(SRCS) | $(PN).aux
+       bibtex $(PN).aux
 
 
 # Clean up leftover junk.