1#
2# Copyright 2014, General Dynamics C4 Systems
3#
4# SPDX-License-Identifier: GPL-2.0-only
5#
6
7# $Id: Makefile,v 1.26 2009-04-21 05:40:29 gernot Exp $
8#
9#  To create a LaTeX diff against the CVS HEAD revision, use the target
10#  "diff" (or "viewdiff").
11#  To use a revision other than HEAD, speciff DIFF=x on the 
12#  make command line to choose the revision x.
13#
14
15# This Makefile contains bash'isms.
16SHELL=bash
17
18.PHONY: all
19
20BIBDIR     ?= /home/disy/lib/BibTeX:../../../bibtex
21LaTeXEnv   = TEXINPUTS=".:/home/disy/lib/TeX:/home/disy/lib/ps:${TEXINPUTS}:"
22BibTexEnv  = BIBINPUTS=".:${BIBDIR}:${BIBINPUTS}:"
23BibFiles   = defs,extra,combined,theses,os-other
24
25LaTeX      = ${LaTeXEnv} pdflatex -interaction=nonstopmode
26BibTeX     = ${BibTexEnv} bibtex
27Fig2Eps    = fig2dev -L eps
28Dia2Eps    = dia -t eps -e
29GnuPlot	   = gnuplot
30Eps2Pdf	   = epstopdf --outfile
31PdfView	   = xpdf
32#PdfView    = open -a preview
33#PdfView    = acroread 
34Lpr 	   = lpr
35mv	   = mv
36awk	   = awk
37R	   = R
38doxygen = doxygen
39PYTHON ?= python3
40
41# To add a second target, simply append the basename of the .tex file here
42Targets    = manual
43
44
45# CONFIGURATION OPTIONS
46# =====================
47
48# Extra figures that aren't supplied as dia, gnuplot or fig sources
49# (eg figures already supplied in PDF, or supplied in EPS).
50# List with PDF extensions:
51ExtraFigs= #imgs/eps-fig.pdf
52
53# Any other stuff that may be needed
54
55# END CONFIGURATION OPTIONS
56# =========================
57
58Optional = $(addsuffix -diff, $(Targets))
59All = $(Targets) $(Optional)
60Diffopts=--type=BWUNDERLINE #-c .latexdiffconfig --append-safecmd="Comment"
61
62Perf_Sources = $(wildcard imgs/*.perf)
63Dia_Sources = $(wildcard imgs/*.dia)
64Fig_Sources = $(wildcard imgs/*.fig)
65Gnuplot_Sources = $(wildcard imgs/*.gnuplot)
66R_Sources = $(wildcard imgs/*.r)
67Figures = $(Perf_Sources:.perf=.pdf) $(Dia_Sources:.dia=.pdf) $(Fig_Sources:.fig=.pdf) $(Gnuplot_Sources:.gnuplot=.pdf)  $(R_Sources:.r=.pdf) $(ExtraFigs)
68
69Pdf = $(addsuffix .pdf, $(Targets))
70Bib = references.bib
71Tex = $(addsuffix .tex, $(Targets))
72Diff_Pdf = $(addsuffix .pdf, $(Optional))
73
74DoxygenOutput = doxygen-output
75DoxygenXml = $(DoxygenOutput)/xml
76Stage = stage
77Libsel4Dir = ../libsel4
78
79GeneratedLatexDir = generated
80GeneratedLatex = $(wildcard $(GeneratedLatexDir)/*.tex)
81
82GeneratedMarkdownDir = generated_markdown
83GeneratedMarkdown = $(wildcard $(GeneratedMarkdownDir)/*.md)
84
85GenerationTool = tools/parse_doxygen_xml.py
86
87GenerateObjectInvocationTool = tools/gen_invocations.py
88
89InterfaceDtd = $(Libsel4Dir)/tools/sel4_idl.dtd
90
91.PHONY: FORCE
92
93all: pdf
94diff: diff_pdf
95FORCE:
96ps: $(Ps)
97pdf: generated-latex $(Figures) Makefile $(Pdf)
98diff_pdf: $(Figures) Makefile $(Diff_Pdf)
99markdown: generated-markdown
100
101# Verbosity.
102ifeq (${V},1)
103Q:=
104else
105Q:=@
106endif
107
108.PHONY: doxygen generated-headers generated-latex generated-markdown
109
110# We call doxygen twice below while excluding either syscalls_master.h or syscalls_mcs.h.
111# Without excluding one of the two files, the doc strings get merged in inconsistent ways
112# and lead to bad output in the manual. If there is a better way to support duplicates
113# then it could be used instead.
114doxygen: generated-headers
115	( cat Doxyfile ; echo "EXCLUDE = ./../libsel4/include/sel4/syscalls_master.h" ) | $(doxygen) -
116	( cat Doxyfile ; echo "EXCLUDE = ./../libsel4/include/sel4/syscalls_mcs.h" ) | $(doxygen) -
117
118# Xml files generated by doxygen
119${DoxygenXml}/%.xml: doxygen
120	@echo "====> Generating $@"
121
122# Latex files translated from doxygen-generated xml
123${GeneratedLatexDir}/%SystemCalls.tex: ${DoxygenXml}/group__%SystemCalls.xml
124	@echo "====> Generating $@"
125	${Q}${PYTHON} ${GenerationTool} --level 3 --input $< --output $@
126
127${GeneratedLatexDir}/%.tex: ${DoxygenXml}/group__%.xml
128	@echo "====> Generating $@"
129	${Q}${PYTHON} ${GenerationTool} --level 2 --input $< --output $@
130
131# Collect generated latex files into single rule
132generated-latex: ${GeneratedLatexDir}/GeneralSystemCalls.tex \
133                 ${GeneratedLatexDir}/MCSSystemCalls.tex \
134                 ${GeneratedLatexDir}/DebuggingSystemCalls.tex \
135                 ${GeneratedLatexDir}/BenchmarkingSystemCalls.tex \
136                 ${GeneratedLatexDir}/X86SystemCalls.tex \
137                 ${GeneratedLatexDir}/ObjectApi.tex \
138                 ${GeneratedLatexDir}/ObjectApiX86.tex \
139                 ${GeneratedLatexDir}/ObjectApiArm.tex \
140                 ${GeneratedLatexDir}/ObjectApiAarch32.tex \
141                 ${GeneratedLatexDir}/ObjectApiAarch64.tex \
142                 ${GeneratedLatexDir}/ObjectApiIa32.tex \
143                 ${GeneratedLatexDir}/ObjectApiX64.tex \
144                 ${GeneratedLatexDir}/ObjectApiRISCV.tex
145
146# Markdown files translated from doxygen-generated xml
147${GeneratedMarkdownDir}/%.md: ${DoxygenXml}/group__%.xml Makefile
148	@echo "====> Generating $@"
149	${Q}${PYTHON} ${GenerationTool} --format markdown --level 2 --input $< --output $@
150
151# Collect generated markdown files into single rule
152generated-markdown: ${GeneratedMarkdownDir}/GeneralSystemCalls.md \
153                 ${GeneratedMarkdownDir}/MCSSystemCalls.md \
154                 ${GeneratedMarkdownDir}/DebuggingSystemCalls.md \
155                 ${GeneratedMarkdownDir}/BenchmarkingSystemCalls.md \
156                 ${GeneratedMarkdownDir}/X86SystemCalls.md \
157                 ${GeneratedMarkdownDir}/ObjectApi.md \
158                 ${GeneratedMarkdownDir}/ObjectApiX86.md \
159                 ${GeneratedMarkdownDir}/ObjectApiArm.md \
160                 ${GeneratedMarkdownDir}/ObjectApiAarch32.md \
161                 ${GeneratedMarkdownDir}/ObjectApiAarch64.md \
162                 ${GeneratedMarkdownDir}/ObjectApiIa32.md \
163                 ${GeneratedMarkdownDir}/ObjectApiX64.md \
164                 ${GeneratedMarkdownDir}/ObjectApiRISCV.md
165
166# Generate object invocation prototypes
167${Stage}/object_invocations.h: ${Libsel4Dir}/include/interfaces/sel4.xml \
168                               ${Libsel4Dir}/arch_include/x86/interfaces/sel4arch.xml \
169                               ${Libsel4Dir}/arch_include/arm/interfaces/sel4arch.xml \
170                               ${Libsel4Dir}/sel4_arch_include/aarch32/interfaces/sel4arch.xml \
171                               ${Libsel4Dir}/sel4_arch_include/aarch64/interfaces/sel4arch.xml \
172                               ${Libsel4Dir}/sel4_arch_include/ia32/interfaces/sel4arch.xml \
173                               ${Libsel4Dir}/sel4_arch_include/x86_64/interfaces/sel4arch.xml \
174                               ${Libsel4Dir}/arch_include/riscv/interfaces/sel4arch.xml
175	@echo "====> Generating documented object invocation header"
176	${Q}${PYTHON} ${GenerateObjectInvocationTool} --dtd ${InterfaceDtd} --output $@ $^
177
178# Collect generated headers into single rule
179generated-headers: ${Stage}/object_invocations.h
180
181# Fetch information from the environment that needs to go into the document.
182env.tex: FORCE
183	@echo 'ENV ->' $@
184	${Q}${PYTHON} tools/gen_env.py $@
185
186manual.pdf: VERSION env.tex manual.tex parts/*.tex parts/api/*.tex
187
188%.pdf: %.perf tools/bargraph.pl
189	@echo $< '->' $@
190	${Q}${BarGraph} -pdf $< > $@
191
192%.pdf: %.eps
193	@echo $< '->' $@
194	${Q}${Eps2Pdf} $@ $<
195
196%.pdf: %.ps
197	@echo $< '->' $@
198	${Q}${Eps2Pdf} $@ $<
199
200%.eps: %.dia
201	@echo $< '->' $@
202	${Q}${Dia2Eps} $@ $<
203
204%.eps: %.fig
205	@echo $< '->' $@
206	${Q}${Fig2Eps} $< $@
207
208%.eps: %.gnuplot
209	@echo $< '->' $@
210	${Q}${GnuPlot} $<
211
212%.eps: %.r
213	@echo $< '->' $@
214	${Q}${R} --vanilla < $<
215
216view: pdf
217	${Q}for i in $(Pdf); do \
218		$(PdfView) $$i & \
219	done
220
221viewdiff: diff
222	${Q}for i in $(Diff_Pdf); do \
223		$(PdfView) $$i & \
224	done
225
226print: pdf
227	${Q}for i in $(Pdf); do \
228		$(Lpr) $$i \
229	done
230
231clean:
232	rm -f *.aux *.toc *.bbl *.blg *.dvi *.log *.pstex* *.eps *.cb *.brf \
233		*.out *.ps *-diff.tex *.mps .log *.pdf *.tgz *~ *.lof *.lot env.tex
234	rm -rf ${DoxygenOutput} ${GeneratedLatexDir} ${GeneratedMarkdownDir}
235	rm -rf ${Stage}
236
237tar:	clean
238	( p=`pwd` && d=`basename "$$p"` && cd .. && \
239	  tar cfz $$d.tgz $$d && \
240	  mv $$d.tgz $$d )
241
242help:
243	@echo "Main targets: all diff view viewdiff print clean tar"
244	@echo "'make diff' will show changes to head revision"
245	@echo "'make DIFF=<rev> diff' will show changes to revision <rev>"
246
247##############################################################################
248
249DIFF ?= tip
250
251%-diff.dvi: %-diff.tex
252
253%-diff.tex: %.tex FORCE
254	@echo "====> Retrieving revision $(DIFF) of $<"
255	${Q}hg cat -r $(DIFF) $<  > $(@:-diff.tex=-$(DIFF)-diff.tex)
256	@echo "====> Creating diff of revision $(DIFF) of $<"
257	${Q}./tools/latexdiff $(Diffopts) $(@:-diff.tex=-$(DIFF)-diff.tex) $< > $@
258
259.PHONY: FORCE
260FORCE:
261
262# don't delete %.aux intermediates
263.SECONDARY:
264
265##############################################################################
266
267Rerun = '(There were undefined references|Rerun to get (cross-references|the bars) right)'
268Rerun_Bib = 'No file.*\.bbl|Citation.*undefined'
269Undefined = '((Reference|Citation).*undefined)|(Label.*multiply defined)'
270Error = '^! '
271
272# combine citation commands from all targets into tmp.aux, generate references.bib from this
273references.bib: $(addsuffix .tex, $(Targets)) env.tex
274	@echo "====> Parsing targets for references";
275	${Q}for i in $(Targets); do \
276		$(LaTeX) $$i.tex >>.log; \
277		cat $$i.aux | grep -e "\(citation\|bibdata\|bibstyle\)" | sed 's/bibdata{references}/bibdata{$(BibFiles)}/g' >> all_refs.aux; \
278	done
279	@echo "====> Removing duplicate bib entries";
280	${Q}cat all_refs.aux | uniq > tmp.aux;
281	${Q}diff references.aux tmp.aux > references.diff 2> /dev/null; \
282	if [ -s references.diff ] && [ -e references.bib ]; then \
283		echo "====> Changed references:"; \
284		cat references.diff | grep "citation"; \
285		echo -n "These will cause changes to references.bib, do you want to rebuild this file? (yes/no): "; \
286		read rebuild_refs; \
287	fi; \
288	if [ "$$rebuild_refs" == "yes" ] || [ \! -e references.bib ]; then \
289		echo "====> Building references.bib"; \
290		$(BibTexEnv) ./tools/bibexport.sh -t -o references.bib tmp.aux > /dev/null 2> /dev/null; \
291		cp tmp.aux references.aux; \
292	fi; 
293	${Q}rm all_refs.aux tmp.aux references.diff
294
295%.pdf: %.tex references.bib $(Figures) Makefile
296	${Q}if ! test -e $*.bbl || test $(Bib) -nt $*.bbl; then rm -f $*.bbl; fi
297	@echo "====> LaTeX first pass: $(<)"
298	${Q}$(LaTeX) $< >.log || if egrep -q $(Error) $*.log ; then cat .log; rm $@; false ; fi
299	${Q}if egrep -q $(Rerun_Bib) $*.log ; then echo "====> BibTex" && $(BibTeX) $* > /dev/null && echo "====> LaTeX BibTeX pass" && $(LaTeX) >.log $< ; fi
300	${Q}if egrep -q $(Rerun) $*.log ; then echo "====> LaTeX rerun" && $(LaTeX) >.log $<; fi
301	${Q}if egrep -q $(Rerun) $*.log ; then echo "====> LaTeX rerun" && $(LaTeX) >.log $<; fi
302	${Q}if egrep -q $(Rerun) $*.log ; then echo "====> LaTeX rerun" && $(LaTeX) >.log $<; fi
303	@echo "====> Undefined references and citations in $(<):"
304	${Q}egrep -i $(Undefined) $*.log || echo "None."
305	@echo "====> Dimensions:"
306	${Q}grep "dimension:" $*.log || echo "None."
307
308##############################################################################
309# Generate a list of FIXMEs 
310fixmes: 
311	${Q}for i in $(Tex); do \
312		echo "FIXMEs in $$i:"; \
313		nl -b a $$i | grep "FIXME{" | nl -b a; \
314		echo -n "Total FIXMES: " && grep "FIXME{" $$i | wc -l; \
315		echo; \
316	done
317