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