]> gitweb.michael.orlitzky.com - mjotex.git/blob - GNUmakefile
GNUmakefile: use SOURCE_DATE_EPOCH=0 instead of "sed" to prevent rebuilds.
[mjotex.git] / GNUmakefile
1 #
2 # Example makefile using mjotex and a BibTeX references database.
3 #
4
5 # The latex compiler. The SOURCE_DATE_EPOCH=0 prevents the creation
6 # and modification dates from being embedded as metadata into the
7 # output file; that in turn is important because it allows us to tell
8 # when the output stops changing (that is, when we are done). The
9 # variable is supported in pdftex v1.40.17 and later.
10 LATEX = SOURCE_DATE_EPOCH=0 pdflatex -file-line-error -halt-on-error
11
12 # The name of this document.
13 #
14 # For example, to use the name of our parent directory:
15 #
16 # PN = $(notdir $(realpath .))
17 #
18 PN = examples
19
20 # A space-separated list of bib files. These must all belong to paths
21 # contained in your $BIBINPUTS environment variable.
22 #
23 # Leave commented if you don't use a bibliography database.
24 #
25 BIBS = local-references.bib
26
27 # A space-separated list of the mjotex files that you use. The path to
28 # mjotex must be contain in your $TEXINPUTS environment variable.
29 #
30 # MJOTEX = mjotex.sty
31 #
32 MJOTEX = mjo-algebra.tex mjo-algorithm.tex mjo-arrow.tex mjo-calculus.tex
33 MJOTEX += mjo-common.tex mjo-complex.tex mjo-cone.tex mjo-convex.tex
34 MJOTEX += mjo-eja.tex mjo-font.tex mjo-linear_algebra.tex mjo-listing.tex
35 MJOTEX += mjo-proof_by_cases.tex mjo-set.tex mjo-theorem.tex
36 MJOTEX += mjo-theorem-star.tex mjo-topology.tex mjo.bst
37
38 # Compile a list of raw source code listings (*.listing) and their
39 # associated output files (*.py) that will be tested by check-sage.
40 SAGE_LISTING_SRCS = $(wildcard sage_listings/*.listing)
41 SAGE_LISTING_DSTS = $(patsubst %.listing,%.py,$(SAGE_LISTING_SRCS))
42
43 # A space-separated list of indices (just their names). Usually you'll
44 # have just one, and it will be named the same thing as your document,
45 # because that's what the makeidx package does.
46 #
47 # Leave commented if you don't use an index.
48 #
49 INDICES = $(PN)
50
51 # We have to rebuild the index whenever the contents of the document
52 # change, because page numbers get moved around. But when no INDICES
53 # are defined, rebuilding them should be a no-op. This next definition
54 # ensures that.
55 ifdef INDICES
56 REMAKE_INDICES = makeindex $(INDEX_SRCS)
57 else
58 REMAKE_INDICES = true
59 endif
60
61 # Use kpsewhich (from the kpathsea suite) to find the absolute paths
62 # of the bibtex/mjotex files listed in in $(BIBS)/$(MJOTEX). The SRCS
63 # variable should contain all (Bib)TeX source files for the document.
64 SRCS = $(PN).tex
65 ifdef BIBS
66 BIBPATHS = $(shell kpsewhich $(BIBS))
67 SRCS += $(BIBPATHS)
68 endif
69 ifdef MJOTEX
70 MJOTEXPATHS = $(shell kpsewhich $(MJOTEX))
71 SRCS += $(MJOTEXPATHS)
72 endif
73 ifdef SAGE_LISTING_DSTS
74 SRCS += $(SAGE_LISTING_DSTS)
75 endif
76
77 ifdef INDICES
78 INDEX_SRCS = $(addsuffix .idx,$(INDICES))
79 INDEX_DSTS = $(addsuffix .ind,$(INDICES))
80 endif
81
82 # The first target is the default, so put the PDF document first.
83 #
84 # This voodoo is all designed to find a "fixed point" of calling
85 # $(LATEX). When you build a LaTeX document, it requires an unknown
86 # number of compilation passes. How do you know when to stop? Easy,
87 # stop when the output file stops changing! But how to encode that
88 # in a makefile?
89 #
90 # At the start of this target, we call $(LATEX) to compile $(PN).tex.
91 # The first step is to check for the existence of a "previous"
92 # file. If there isn't one, this is the first time that we've tried to
93 # build the PDF. In that case, take the PDF that we've just built and
94 # make *that* the previous file. Then start all over. If there is a
95 # previous file, then this is the second (or more) time that we've
96 # tried to build the PDF. We diff the PDF file that we've just built
97 # against the previous file; if they're the same, then we've succeeded
98 # and stop. Otherwise, we make the new PDF the previous file, and
99 # start all over. The end result is that we will loop until the
100 # newly-created PDF and the previous file are identical.
101 #
102 $(PN).pdf: $(SRCS) $(PN).bbl $(INDEX_DSTS)
103 $(LATEX) $(PN).tex
104
105 if [ ! -f $@.previous ]; then \
106 mv $@ $@.previous; \
107 $(MAKE) $@; \
108 fi;
109
110 if cmp -s $@ $@.previous; then \
111 rm $@.previous; \
112 else \
113 mv $@ $@.previous; \
114 $(REMAKE_INDICES); \
115 $(MAKE) $@; \
116 fi;
117
118
119 $(PN).aux: $(SRCS)
120 $(LATEX) $(PN).tex
121
122
123 ifdef INDICES
124 # We need to be able to build the index source files without involving
125 # the main $(PN).pdf rule, in order to avoid a chicken-and-egg problem.
126 # This is similar to the $(PN).aux rule above, except that an index is
127 # optional and there might be more than one of them.
128 $(INDEX_SRCS): $(PN).tex
129 $(LATEX) $(PN).tex
130 endif
131
132 ifdef INDICES
133 # Create real indices from source files by running "makeindex" on
134 # them. We depend on SRCS here because we *do* want to rebuild the
135 # index if the source document changes, but we use an order-only
136 # dependency (see the bbl rule below) on the idx files to prevent us
137 # from going into a rebuild loop when the idx files are regenerated.
138 %.ind: $(SRCS) | %.idx
139 makeindex $|
140 endif
141
142 # The pipe below indicates an "order-only dependency" on the aux file.
143 # Without it, every compilation of $(PN).tex would produce a new
144 # $(PN).aux, and thus $(PN).bbl would be rebuilt. This in turn causes
145 # $(PN).pdf to appear out-of-date, which leads to a recompilation of
146 # $(PN).tex... and so on. The order-only dependency means we won't
147 # rebuild $(PN).bbl if $(PN).aux changes.
148 #
149 # As a side effect, we now need to depend on $(SRCS) here, since we
150 # won't pick it up transitively from $(PN).aux.
151 #
152 # If the $BIBS variable is undefined, we presume that there are no
153 # references and create an empty bbl file. Otherwise, we risk trying
154 # to run biblatex on an aux file containing no citations. If you do
155 # define $BIBS but don't cite anything, you'll run into a similar
156 # problem. Don't do that.
157 #
158 $(PN).bbl: $(SRCS) | $(PN).aux
159 ifdef BIBS
160 bibtex $(PN).aux
161 else
162 echo -n '' > $@
163 endif
164
165 # If the output PDF exists but the log file does not, then an attempt
166 # to "build the log file" (i.e. build the PDF) would do nothing. Thus
167 # whenever the log file does not exist, we do a fresh build.
168 $(PN).log: $(SRCS)
169 $(MAKE) clean
170 $(MAKE)
171
172 # How do we convert a raw listing into something testable by sage? We
173 # append/prepend triple quotes to make the whole thing into a doctest,
174 # and then we replace any blank lines by "<BLANKLINE>".
175 sage_listings/%.py: sage_listings/%.listing
176 echo '"""' > $@ && cat $< >> $@ && echo '"""' >> $@ && sed -i 's/^[[:space:]]*$$/<BLANKLINE>/' $@
177
178 # Ensure that there are no overfull or underfull boxes in the output
179 # document by parsing the log for said warnings.
180 .PHONY: check-boxes
181 check-boxes: $(PN).log
182 @! grep -i 'overfull\|underfull' $<
183
184 # Run chktex to find silly mistakes. There is some exit code weirdness
185 # (Savannah bug 53129), so we just look for empty output.
186 .PHONY: check-chktex
187 CHKTEX = chktex --localrc .chktexrc --quiet --inputfiles=0
188 check-chktex:
189 @chktexout=$$($(CHKTEX) $(PN).tex); \
190 test -z "$${chktexout}" || { echo "$${chktexout}" 1>&2; exit 1; }
191
192 # Ensure that there are no undefined references in the document by
193 # parsing the log file for said warnings.
194 .PHONY: check-undefined
195 check-undefined: $(PN).log
196 @! grep -i 'undefined' $<
197
198 # Use sage to doctest any \sagelisting{}s in SAGE_LISTING_DSTS.
199 # The actuall command is ifdef'd so that we can comment out
200 # the definition of SAGE_LISTING_DSTS without breaking the
201 # default definition of the "check" target.
202 .PHONY: check-sage
203 check-sage: $(SAGE_LISTING_DSTS)
204 ifdef SAGE_LISTING_DSTS
205 sage -t --timeout=0 --memlimit=0 $^
206 endif
207
208 # Run a suite of checks.
209 .PHONY: check
210 check: check-boxes check-chktex check-undefined check-sage
211
212 # Clean up leftover junk. This only looks overcomplicated because
213 # the *.{foo,bar} syntax supported by Bash is not POSIX, and Make
214 # will execute these commands using /bin/sh (which should be POSIX).
215 JUNK_EXTENSIONS = aux bbl bcf blg glo ilg ist listing lof log nav out pdf
216 JUNK_EXTENSIONS += snm spl toc xml
217 .PHONY: clean
218 clean:
219 for ext in $(JUNK_EXTENSIONS); do rm -f *.$$ext; done;
220 rm -rf dist/
221 rm -f $(SAGE_LISTING_DSTS) $(INDEX_SRCS) $(INDEX_DSTS)
222
223 # If this document will be published, the publisher isn't going to
224 # have your BibTeX database or your mjotex files. So, you need to
225 # package them up along with the code for your document. This target
226 # will create a "dist" directory and copy the necessary stuff there.
227 #
228 .PHONY: dist
229 dist: $(PN).bbl
230 mkdir -p dist
231 cp $(SRCS) $(PN).bbl dist/