• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014-2021 The Khronos Group Inc.
2#
3# SPDX-License-Identifier: Apache-2.0
4
5# Vulkan Specification makefile
6#
7# To build the spec with a specific version included, set the
8# $(VERSIONS) variable on the make command line to a space-separated
9# list of version names (e.g. VK_VERSION_1_2) *including all previous
10# versions of the API* (e.g. VK_VERSION_1_1 must also include
11# VK_VERSION_1_0). $(VERSIONS) is converted into asciidoc and generator
12# script arguments $(VERSIONATTRIBS) and $(VERSIONOPTIONS)
13#
14# To build the specification / reference pages (refpages) with optional
15# extensions included, set the $(EXTENSIONS) variable on the make
16# command line to a space-separated list of extension names.
17# $(EXTENSIONS) is converted into asciidoc and generator script
18# arguments $(EXTATTRIBS) and $(EXTOPTIONS).
19
20# If a recipe fails, delete its target file. Without this cleanup, the leftover
21# file from the failed recipe can falsely satisfy dependencies on subsequent
22# runs of `make`.
23.DELETE_ON_ERROR:
24
25VERSIONS := VK_VERSION_1_0 VK_VERSION_1_1 VK_VERSION_1_2
26VERSIONATTRIBS := $(foreach version,$(VERSIONS),-a $(version))
27VERSIONOPTIONS := $(foreach version,$(VERSIONS),-feature $(version))
28
29EXTS := $(sort $(EXTENSIONS) $(DIFFEXTENSIONS))
30EXTATTRIBS := $(foreach ext,$(EXTS),-a $(ext))
31EXTOPTIONS := $(foreach ext,$(EXTS),-extension $(ext))
32
33# APITITLE can be set to extra text to append to the document title,
34# normally used when building with extensions included.
35APITITLE =
36
37# IMAGEOPTS is normally set to generate inline SVG images, but can be
38# overridden to an empty string, since the inline option does not work
39# well with our HTML diffs.
40IMAGEOPTS = inline
41
42# The default 'all' target builds the following sub-targets:
43#  html - HTML single-page API specification
44#  pdf - PDF single-page API specification
45#  styleguide - HTML5 single-page "Documentation and Extensions" guide
46#  registry - HTML5 single-page XML Registry Schema documentation
47#  manhtml - HTML5 single-page reference guide - NOT SUPPORTED
48#  manpdf - PDF reference guide - NOT SUPPORTED
49#  manhtmlpages - HTML5 separate per-feature refpages
50#  allchecks - Python sanity checker for script markup and macro use
51
52all: alldocs allchecks
53
54alldocs: allspecs allman proposals
55
56allspecs: html pdf styleguide registry
57
58allman: manhtmlpages
59
60# CHECK_CONTRACTIONS looks for disallowed contractions
61# check_spec_links.py looks for proper use of custom markup macros
62#   --ignore_count 0 can be incremented if there are unfixable errors
63# xml_consistency.py performs various XML consistency checks
64# check_undefined looks for untagged use of 'undefined' in spec sources
65# reflow.py looks for asciidoctor conditionals inside VU statements;
66#   and for duplicated VUID numbers, but only in spec sources.
67CHECK_CONTRACTIONS = git grep -i -F -f config/CI/contractions | egrep -v -E -f config/CI/contractions-allowed
68allchecks:
69	if test `$(CHECK_CONTRACTIONS) | wc -l` != 0 ; then \
70	    echo "Contractions found that are not allowed:" ; \
71	    $(CHECK_CONTRACTIONS) ; \
72	    exit 1 ; \
73	fi
74	$(PYTHON) $(SCRIPTS)/check_spec_links.py -Werror --ignore_count 0
75	$(PYTHON) $(SCRIPTS)/xml_consistency.py
76	$(SCRIPTS)/ci/check_undefined
77	$(PYTHON) $(SCRIPTS)/reflow.py -nowrite -noflow -check FAIL -checkVUID FAIL $(SPECFILES)
78
79# Note that the := assignments below are immediate, not deferred, and
80# are therefore order-dependent in the Makefile
81
82QUIET	 ?= @
83VERYQUIET?= @
84PYTHON	 ?= python3
85ASCIIDOC ?= asciidoctor
86RUBY	 = ruby
87NODEJS	 = node
88PATCH	 = patch
89RM	 = rm -f
90RMRF	 = rm -rf
91MKDIR	 = mkdir -p
92CP	 = cp
93ECHO	 = echo
94GS_EXISTS := $(shell command -v gs 2> /dev/null)
95
96# Path to scripts used in generation
97SCRIPTS  = $(CURDIR)/scripts
98
99# Target directories for output files
100# HTMLDIR - 'html' target
101# PDFDIR - 'pdf' target
102# CHECKDIR - 'allchecks' target
103OUTDIR	  = $(GENERATED)/out
104HTMLDIR   = $(OUTDIR)/html
105VUDIR	  = $(OUTDIR)/validation
106PDFDIR	  = $(OUTDIR)/pdf
107CHECKDIR  = $(OUTDIR)/checks
108PROPOSALDIR = $(OUTDIR)/proposals
109
110# PDF Equations are written to SVGs, this dictates the location to store those files (temporary)
111PDFMATHDIR:=$(OUTDIR)/equations_temp
112
113# Set VERBOSE to -v to see what asciidoc is doing.
114VERBOSE =
115
116# asciidoc attributes to set (defaults are usually OK)
117# NOTEOPTS sets options controlling which NOTEs are generated
118# PATCHVERSION must equal VK_HEADER_VERSION from vk.xml
119# ATTRIBOPTS sets the API revision and enables KaTeX generation
120# VERSIONATTRIBS sets attributes for enabled API versions (set above
121#	     based on $(VERSIONS))
122# EXTATTRIBS sets attributes for enabled extensions (set above based on
123#	     $(EXTENSIONS))
124# EXTRAATTRIBS sets additional attributes, if passed to make
125# ADOCMISCOPTS miscellaneous options controlling error behavior, etc.
126# ADOCEXTS asciidoctor extensions to load
127# ADOCOPTS options for asciidoc->HTML5 output
128
129NOTEOPTS     = -a editing-notes -a implementation-guide
130PATCHVERSION = 201
131
132ifneq (,$(findstring VK_VERSION_1_2,$(VERSIONS)))
133SPECMINOR = 2
134else
135ifneq (,$(findstring VK_VERSION_1_1,$(VERSIONS)))
136SPECMINOR = 1
137else
138SPECMINOR = 0
139endif
140endif
141
142SPECREVISION = 1.$(SPECMINOR).$(PATCHVERSION)
143
144# Spell out ISO 8601 format as not all date commands support --rfc-3339
145SPECDATE     = $(shell echo `date -u "+%Y-%m-%d %TZ"`)
146
147# Generate Asciidoc attributes for spec remark
148# Could use `git log -1 --format="%cd"` to get branch commit date
149# This used to be a dependency in the spec html/pdf targets,
150# but that is likely to lead to merge conflicts. Just regenerate
151# when pushing a new spec for review to the sandbox.
152# The dependency on HEAD is per the suggestion in
153# http://neugierig.org/software/blog/2014/11/binary-revisions.html
154SPECREMARK = from git branch: $(shell echo `git symbolic-ref --short HEAD 2> /dev/null || echo Git branch not available`) \
155	     commit: $(shell echo `git log -1 --format="%H" 2> /dev/null || echo Git commit not available`)
156
157# Base path to SPIR-V extensions on the web.
158SPIRVPATH = https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions
159
160# Some of the attributes used in building all spec documents:
161#   chapters - absolute path to chapter sources
162#   appendices - absolute path to appendix sources
163#   images - absolute path to images
164#   generated - absolute path to generated sources
165#   refprefix - controls which generated extension metafiles are
166#	included at build time. Must be empty for specification,
167#	'refprefix.' for refpages (see ADOCREFOPTS below).
168ATTRIBOPTS   = -a revnumber="$(SPECREVISION)" \
169	       -a revdate="$(SPECDATE)" \
170	       -a revremark="$(SPECREMARK)" \
171	       -a apititle="$(APITITLE)" \
172	       -a stem=latexmath \
173	       -a imageopts="$(IMAGEOPTS)" \
174	       -a config=$(CURDIR)/config \
175	       -a appendices=$(CURDIR)/appendices \
176	       -a chapters=$(CURDIR)/chapters \
177	       -a images=$(IMAGEPATH) \
178	       -a generated=$(GENERATED) \
179	       -a spirv="$(SPIRVPATH)" \
180	       -a refprefix \
181	       $(VERSIONATTRIBS) \
182	       $(EXTATTRIBS) \
183	       $(EXTRAATTRIBS)
184ADOCMISCOPTS = --failure-level ERROR
185# Non target-specific Asciidoctor extensions and options
186# Look in $(GENERATED) for explicitly required non-extension Ruby, such
187# as api.rb
188ADOCEXTS     = -I$(GENERATED) -r $(CURDIR)/config/spec-macros.rb -r $(CURDIR)/config/tilde_open_block.rb
189ADOCOPTS     = -d book $(ADOCMISCOPTS) $(ATTRIBOPTS) $(NOTEOPTS) $(VERBOSE) $(ADOCEXTS)
190
191# HTML target-specific Asciidoctor extensions and options
192ADOCHTMLEXTS = -r $(CURDIR)/config/katex_replace.rb \
193	       -r $(CURDIR)/config/loadable_html.rb \
194	       -r $(CURDIR)/config/vuid-expander.rb \
195	       -r $(CURDIR)/config/rouge-extend-css.rb
196
197# ADOCHTMLOPTS relies on the relative runtime path from the output HTML
198# file to the katex scripts being set with KATEXDIR. This is overridden
199# by some targets.
200# ADOCHTMLOPTS also relies on the absolute build-time path to the
201# 'stylesdir' containing our custom CSS.
202KATEXSRCDIR  = $(CURDIR)/katex
203KATEXDIR     = katex
204ADOCHTMLOPTS = $(ADOCHTMLEXTS) -a katexpath=$(KATEXDIR) \
205	       -a stylesheet=khronos.css \
206	       -a stylesdir=$(CURDIR)/config \
207	       -a sectanchors
208
209# PDF target-specific Asciidoctor extensions and options
210ADOCPDFEXTS  = -r asciidoctor-pdf \
211	       -r asciidoctor-mathematical \
212	       -r $(CURDIR)/config/asciidoctor-mathematical-ext.rb \
213	       -r $(CURDIR)/config/vuid-expander.rb
214ADOCPDFOPTS  = $(ADOCPDFEXTS) -a mathematical-format=svg \
215	       -a imagesoutdir=$(PDFMATHDIR) \
216	       -a pdf-fontsdir=config/fonts,GEM_FONTS_DIR \
217	       -a pdf-stylesdir=config/themes -a pdf-style=pdf
218
219# Valid usage-specific Asciidoctor extensions and options
220ADOCVUEXTS = -r $(CURDIR)/config/vu-to-json.rb -r $(CURDIR)/config/quiet-include-failure.rb
221ADOCVUOPTS = $(ADOCVUEXTS)
222
223.PHONY: directories
224
225# Images used by the spec. These are included in generated HTML now.
226IMAGEPATH = $(CURDIR)/images
227SVGFILES  = $(wildcard $(IMAGEPATH)/*.svg)
228
229# Top-level spec source file
230SPECSRC := vkspec.txt
231# Static files making up sections of the API spec.
232SPECFILES = $(wildcard chapters/[A-Za-z]*.txt chapters/*/[A-Za-z]*.txt appendices/[A-Za-z]*.txt)
233# Shorthand for where different types generated files go.
234# All can be relocated by overriding GENERATED in the make invocation.
235GENERATED      = $(CURDIR)/gen
236REFPATH        = $(GENERATED)/refpage
237APIPATH        = $(GENERATED)/api
238VALIDITYPATH   = $(GENERATED)/validity
239HOSTSYNCPATH   = $(GENERATED)/hostsynctable
240METAPATH       = $(GENERATED)/meta
241INTERFACEPATH  = $(GENERATED)/interfaces
242SPIRVCAPPATH   = $(GENERATED)/spirvcap
243FORMATSPATH    = $(GENERATED)/formats
244PROPOSALPATH   = $(CURDIR)/proposals
245# timeMarker is a proxy target created when many generated files are
246# made at once
247APIDEPEND      = $(APIPATH)/timeMarker
248VALIDITYDEPEND = $(VALIDITYPATH)/timeMarker
249HOSTSYNCDEPEND = $(HOSTSYNCPATH)/timeMarker
250METADEPEND     = $(METAPATH)/timeMarker
251INTERFACEDEPEND = $(INTERFACEPATH)/timeMarker
252SPIRVCAPDEPEND = $(SPIRVCAPPATH)/timeMarker
253FORMATSDEPEND = $(FORMATSPATH)/timeMarker
254RUBYDEPEND     = $(GENERATED)/api.rb
255# All generated dependencies
256GENDEPENDS     = $(APIDEPEND) $(VALIDITYDEPEND) $(HOSTSYNCDEPEND) $(METADEPEND) $(INTERFACEDEPEND) $(SPIRVCAPDEPEND) $(FORMATSDEPEND) $(RUBYDEPEND)
257# All non-format-specific dependencies
258COMMONDOCS     = $(SPECFILES) $(GENDEPENDS)
259
260# Script to add href to anchors
261GENANCHORLINKS = $(SCRIPTS)/genanchorlinks.py
262# Script to translate math on build time
263TRANSLATEMATH = $(NODEJS) $(SCRIPTS)/translate_math.js $(KATEXSRCDIR)/katex.min.js
264
265# Install katex in $(OUTDIR)/katex for reference by all HTML targets
266katexinst: KATEXDIR = katex
267katexinst: $(OUTDIR)/$(KATEXDIR)
268
269$(OUTDIR)/$(KATEXDIR): $(KATEXSRCDIR)
270	$(QUIET)$(MKDIR) $(OUTDIR)
271	$(QUIET)$(RMRF)  $(OUTDIR)/$(KATEXDIR)
272# We currently only need the css and fonts, but copy it whole anyway
273	$(QUIET)$(CP) -rf $(KATEXSRCDIR) $(OUTDIR)
274
275# Spec targets
276# There is some complexity to try and avoid short virtual targets like 'html'
277# causing specs to *always* be regenerated.
278
279CHUNKER = $(CURDIR)/scripts/asciidoctor-chunker/asciidoctor-chunker.js
280CHUNKINDEX = $(CURDIR)/config/chunkindex
281# Only the $(CHUNKER) step is required unless the search index is to be
282# generated and incorporated into the chunked spec.
283#
284# Dropped $(QUIET) for now
285# Should set NODE_PATH=/usr/local/lib/node_modules or wherever, outside Makefile
286# Copying chunked.js into target avoids a warning from the chunker
287chunked: $(HTMLDIR)/vkspec.html $(SPECSRC) $(COMMONDOCS)
288	$(QUIET)$(CHUNKINDEX)/addscripts.sh $(HTMLDIR)/vkspec.html $(HTMLDIR)/prechunked.html
289	$(QUIET)$(CP) $(CHUNKINDEX)/chunked.css $(CHUNKINDEX)/chunked.js \
290	    $(CHUNKINDEX)/lunr.js $(HTMLDIR)
291	$(QUIET)$(NODEJS) $(CHUNKER) $(HTMLDIR)/prechunked.html -o $(HTMLDIR)
292	$(QUIET)$(RM) $(HTMLDIR)/prechunked.html
293	$(QUIET)$(RUBY) $(CHUNKINDEX)/generate-index.rb $(HTMLDIR)/chap*html | \
294	    $(NODEJS) $(CHUNKINDEX)/build-index.js > $(HTMLDIR)/search.index.js
295
296# This is a temporary target while the new chunker is pre-release.
297# Eventually we will either pull the chunker into CI, or permanently
298# store a copy of the short JavaScript chunker in this repository.
299CHUNKERVERSION = asciidoctor-chunker_v1.0.0
300CHUNKURL = https://github.com/wshito/asciidoctor-chunker/releases/download/v1.0.0/$(CHUNKERVERSION).zip
301getchunker:
302	wget $(CHUNKURL) -O $(CHUNKERVERSION).zip
303	unzip $(CHUNKERVERSION).zip
304	mv $(CHUNKERVERSION)/* scripts/asciidoctor-chunker/
305	rm -rf $(CHUNKERVERSION).zip $(CHUNKERVERSION)
306
307html: $(HTMLDIR)/vkspec.html $(SPECSRC) $(COMMONDOCS)
308
309$(HTMLDIR)/vkspec.html: KATEXDIR = ../katex
310$(HTMLDIR)/vkspec.html: $(SPECSRC) $(COMMONDOCS) katexinst
311	$(QUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) -o $@ $(SPECSRC)
312	$(QUIET)$(PYTHON) $(GENANCHORLINKS) $@ $@
313	$(QUIET)$(TRANSLATEMATH) $@
314
315diff_html: $(HTMLDIR)/diff.html $(SPECSRC) $(COMMONDOCS)
316
317$(HTMLDIR)/diff.html: KATEXDIR = ../katex
318$(HTMLDIR)/diff.html: $(SPECSRC) $(COMMONDOCS) katexinst
319	$(QUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) \
320	    -a diff_extensions="$(DIFFEXTENSIONS)" \
321	    -r $(CURDIR)/config/extension-highlighter.rb --trace \
322	    -o $@ $(SPECSRC)
323	$(QUIET)$(TRANSLATEMATH) $@
324
325# PDF optimizer - usage $(OPTIMIZEPDF) in.pdf out.pdf
326# OPTIMIZEPDFOPTS=--compress-pages is slightly better, but much slower
327OPTIMIZEPDF = hexapdf optimize $(OPTIMIZEPDFOPTS)
328
329pdf: $(PDFDIR)/vkspec.pdf $(SPECSRC) $(COMMONDOCS)
330
331$(PDFDIR)/vkspec.pdf: $(SPECSRC) $(COMMONDOCS)
332	$(QUIET)$(MKDIR) $(PDFDIR)
333	$(QUIET)$(MKDIR) $(PDFMATHDIR)
334	$(QUIET)$(ASCIIDOC) -b pdf $(ADOCOPTS) $(ADOCPDFOPTS) -o $@ $(SPECSRC)
335	$(QUIET)$(OPTIMIZEPDF) $@ $@.out.pdf && mv $@.out.pdf $@
336	$(QUIET)rm -rf $(PDFMATHDIR)
337
338validusage: $(VUDIR)/validusage.json $(SPECSRC) $(COMMONDOCS)
339
340$(VUDIR)/validusage.json: $(SPECSRC) $(COMMONDOCS)
341	$(QUIET)$(MKDIR) $(VUDIR)
342	$(QUIET)$(ASCIIDOC) $(ADOCOPTS) $(ADOCVUOPTS) --trace \
343	    -a json_output=$@ -o $@ $(SPECSRC)
344
345# Vulkan Documentation and Extensions, a.k.a. "Style Guide" documentation
346
347STYLESRC = styleguide.txt
348STYLEFILES = $(wildcard style/[A-Za-z]*.txt)
349
350styleguide: $(OUTDIR)/styleguide.html
351
352$(OUTDIR)/styleguide.html: KATEXDIR = katex
353$(OUTDIR)/styleguide.html: $(STYLESRC) $(STYLEFILES) $(GENDEPENDS) katexinst
354	$(QUIET)$(MKDIR) $(OUTDIR)
355	$(QUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) -o $@ $(STYLESRC)
356	$(QUIET)$(TRANSLATEMATH) $@
357
358
359# Vulkan API Registry (XML Schema) documentation
360# Currently does not use latexmath / KaTeX
361
362REGSRC = registry.txt
363
364registry: $(OUTDIR)/registry.html
365
366$(OUTDIR)/registry.html: $(REGSRC) $(GENDEPENDS)
367	$(QUIET)$(MKDIR) $(OUTDIR)
368	$(QUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) -o $@ $(REGSRC)
369	$(QUIET)$(TRANSLATEMATH) $@
370
371# Build proposal documents
372PROPOSALSOURCES   = $(filter-out $(PROPOSALPATH)/template.asciidoc, $(wildcard $(PROPOSALPATH)/*.asciidoc))
373PROPOSALDOCS	  = $(PROPOSALSOURCES:$(PROPOSALPATH)/%.asciidoc=$(PROPOSALDIR)/%.html)
374proposals: $(PROPOSALDOCS) $(PROPOSALSOURCES)
375
376# Proposal documents are built outside of the main specification
377$(PROPOSALDIR)/%.html: $(PROPOSALPATH)/%.asciidoc
378	$(QUIET)$(ASCIIDOC) --failure-level ERROR -b html5 -o $@ $<
379	$(QUIET) if egrep -q '\\[([]' $@ ; then \
380	    $(TRANSLATEMATH) $@ ; \
381    fi
382
383# Reflow text in spec sources
384REFLOW = $(SCRIPTS)/reflow.py
385REFLOWOPTS = -overwrite
386
387reflow:
388	$(QUIET) echo "Warning: please verify the spec outputs build without changes!"
389	$(PYTHON) $(REFLOW) $(REFLOWOPTS) $(SPECSRC) $(SPECFILES) $(STYLESRC) $(STYLEFILES)
390
391# Clean generated and output files
392
393clean: clean_html clean_pdf clean_man clean_checks clean_generated clean_validusage
394
395clean_html:
396	$(QUIET)$(RMRF) $(HTMLDIR) $(OUTDIR)/katex
397	$(QUIET)$(RM) $(OUTDIR)/apispec.html $(OUTDIR)/styleguide.html \
398	    $(OUTDIR)/registry.html
399
400clean_pdf:
401	$(QUIET)$(RMRF) $(PDFDIR) $(OUTDIR)/apispec.pdf
402
403clean_man:
404	$(QUIET)$(RMRF) $(MANHTMLDIR)
405
406clean_checks:
407	$(QUIET)$(RMRF) $(CHECKDIR)
408
409# Generated directories and files to remove
410CLEAN_GEN_PATHS = \
411    $(APIPATH) \
412    $(HOSTSYNCPATH) \
413    $(VALIDITYPATH) \
414    $(METAPATH) \
415    $(INTERFACEPATH) \
416    $(SPIRVCAPPATH) \
417    $(FORMATSPATH) \
418    $(REFPATH) \
419    $(GENERATED)/include \
420    $(GENERATED)/__pycache__ \
421    $(PDFMATHDIR) \
422    $(GENERATED)/api.py \
423    $(GENERATED)/api.rb
424
425clean_generated:
426	$(QUIET)$(RMRF) $(CLEAN_GEN_PATHS)
427
428clean_validusage:
429	$(QUIET)$(RM) $(VUDIR)/validusage.json
430
431
432# Generated refpage sources. For now, always build all refpages.
433MANSOURCES   = $(filter-out $(REFPATH)/apispec.txt, $(wildcard $(REFPATH)/*.txt))
434
435# Generation of refpage asciidoctor sources by extraction from the
436# specification.
437#
438# Should have a proper dependency causing the man page sources to be
439# generated by running genRef (once), but adding $(MANSOURCES) to the
440# targets causes genRef to run once/target.
441#
442# Should pass in $(EXTOPTIONS) to determine which pages to generate.
443# For now, all core and extension refpages are extracted by genRef.py.
444GENREF = $(SCRIPTS)/genRef.py
445LOGFILE = $(REFPATH)/refpage.log
446refpages: $(REFPATH)/apispec.txt
447$(REFPATH)/apispec.txt: $(SPECFILES) $(GENREF) $(SCRIPTS)/reflib.py $(GENERATED)/api.py
448	$(QUIET)$(MKDIR) $(REFPATH)
449	$(PYTHON) $(GENREF) -genpath $(GENERATED) -basedir $(REFPATH) \
450	    -log $(LOGFILE) -extpath $(CURDIR)/appendices \
451	    $(EXTOPTIONS) $(SPECFILES)
452
453# These targets are HTML5 refpages
454#
455# The recursive $(MAKE) is an apparently unavoidable hack, since the
456# actual list of man page sources is not known until after
457# $(REFPATH)/apispec.txt is generated. $(GENDEPENDS) is generated before
458# running the recursive make, so it does not trigger twice
459# $(SUBMAKEOPTIONS) suppresses the redundant "Entering / leaving"
460# messages make normally prints out, similarly to suppressing make
461# command output logging in the individual refpage actions below.
462SUBMAKEOPTIONS = --no-print-directory
463manhtmlpages: $(REFPATH)/apispec.txt $(GENDEPENDS)
464	$(QUIET) echo "manhtmlpages: building HTML refpages with these options:"
465	$(QUIET) echo $(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) \
466	    $(ADOCREFOPTS) -d manpage -o REFPAGE.html REFPAGE.txt
467	$(MAKE) $(SUBMAKEOPTIONS) -e buildmanpages
468
469# Build the individual refpages, then the symbolic links from aliases
470MANHTMLDIR  = $(OUTDIR)/man/html
471MANHTML     = $(MANSOURCES:$(REFPATH)/%.txt=$(MANHTMLDIR)/%.html)
472buildmanpages: $(MANHTML)
473	$(MAKE) $(SUBMAKEOPTIONS) -e manaliases
474
475# Asciidoctor options to build refpages
476#
477# ADOCREFOPTS *must* be placed after ADOCOPTS in the command line, so
478# that it can override spec attribute values.
479#
480# cross-file-links makes custom macros link to other refpages
481# refprefix includes the refpage (not spec) extension metadata.
482# isrefpage is for refpage-specific content
483# html_spec_relative is where to find the full specification
484ADOCREFOPTS = -a cross-file-links -a refprefix='refpage.' -a isrefpage \
485	      -a html_spec_relative='../../html/vkspec.html'
486
487# The refpage build process normally generates far too much output, so
488# use VERYQUIET instead of QUIET
489# Running translate_math.js on every refpage is slow and most of them
490# do not contain math, so do a quick search for latexmath delimiters.
491$(MANHTMLDIR)/%.html: KATEXDIR = ../../katex
492$(MANHTMLDIR)/%.html: $(REFPATH)/%.txt $(GENDEPENDS) katexinst
493	$(VERYQUIET)echo "Building $@ from $< using default options"
494	$(VERYQUIET)$(MKDIR) $(MANHTMLDIR)
495	$(VERYQUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) $(ADOCREFOPTS) \
496	    -d manpage -o $@ $<
497	$(VERYQUIET)if egrep -q '\\[([]' $@ ; then \
498	    $(TRANSLATEMATH) $@ ; \
499	fi
500
501# The 'manhtml' and 'manpdf' targets are NO LONGER SUPPORTED by Khronos.
502# They generate HTML5 and PDF single-file versions of the refpages.
503# The generated refpage sources are included by $(REFPATH)/apispec.txt,
504# and are always generated along with that file. Therefore there is no
505# need for a recursive $(MAKE) or a $(MANHTML) dependency, unlike the
506# manhtmlpages target.
507
508manpdf: $(OUTDIR)/apispec.pdf
509
510$(OUTDIR)/apispec.pdf: $(SPECVERSION) $(REFPATH)/apispec.txt $(SVGFILES) $(GENDEPENDS)
511	$(QUIET)$(MKDIR) $(OUTDIR)
512	$(QUIET)$(MKDIR) $(PDFMATHDIR)
513	$(QUIET)$(ASCIIDOC) -b pdf -a html_spec_relative='html/vkspec.html' \
514	    $(ADOCOPTS) $(ADOCPDFOPTS) -o $@ $(REFPATH)/apispec.txt
515	$(QUIET)$(OPTIMIZEPDF) $@ $@.out.pdf && mv $@.out.pdf $@
516
517manhtml: $(OUTDIR)/apispec.html
518
519$(OUTDIR)/apispec.html: KATEXDIR = katex
520$(OUTDIR)/apispec.html: ADOCMISCOPTS =
521$(OUTDIR)/apispec.html: $(SPECVERSION) $(REFPATH)/apispec.txt $(SVGFILES) $(GENDEPENDS) katexinst
522	$(QUIET)$(MKDIR) $(OUTDIR)
523	$(QUIET)$(ASCIIDOC) -b html5 -a html_spec_relative='html/vkspec.html' \
524	    $(ADOCOPTS) $(ADOCHTMLOPTS) -o $@ $(REFPATH)/apispec.txt
525	$(QUIET)$(TRANSLATEMATH) $@
526
527# Create links for refpage aliases
528
529MAKEMANALIASES = $(SCRIPTS)/makemanaliases.py
530manaliases: $(GENERATED)/api.py
531	$(PYTHON) $(MAKEMANALIASES) -genpath $(GENERATED) -refdir $(MANHTMLDIR)
532
533# Targets generated from the XML and registry processing scripts
534#   $(GENERATED)/api.py - Python encoding of the registry
535# The $(...DEPEND) targets are files named 'timeMarker' in generated
536# target directories. They serve as proxies for the multiple generated
537# files written for each target:
538#   apiinc / proxy $(APIDEPEND) - API interface include files in $(APIPATH)
539#   hostsyncinc / proxy $(HOSTSYNCDEPEND) - host sync table include files in $(HOSTSYNCPATH)
540#   validinc / proxy $(VALIDITYDEPEND) - API validity include files in $(VALIDITYPATH)
541#   extinc / proxy $(METADEPEND) - extension appendix metadata include files in $(METAPATH)
542#
543# $(VERSIONOPTIONS) specifies the core API versions which are included
544# in these targets, and is set above based on $(VERSIONS)
545#
546# $(EXTOPTIONS) specifies the extensions which are included in these
547# targets, and is set above based on $(EXTENSIONS).
548#
549# $(GENVKEXTRA) are extra options that can be passed to genvk.py, e.g.
550# '-diag diag'
551
552REGISTRY   = xml
553VKXML	   = $(REGISTRY)/vk.xml
554GENVK	   = $(SCRIPTS)/genvk.py
555GENVKOPTS  = $(VERSIONOPTIONS) $(EXTOPTIONS) $(GENVKEXTRA) -registry $(VKXML)
556GENVKEXTRA =
557
558scriptapi: pyapi rubyapi
559
560pyapi $(GENERATED)/api.py: $(VKXML) $(GENVK)
561	$(QUIET)$(MKDIR) $(GENERATED)
562	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(GENERATED) api.py
563
564rubyapi $(GENERATED)/api.rb: $(VKXML) $(GENVK)
565	$(QUIET)$(MKDIR) $(GENERATED)
566	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(GENERATED) api.rb
567
568apiinc: $(APIDEPEND)
569
570$(APIDEPEND): $(VKXML) $(GENVK) $(GENERATED)/api.py
571	$(QUIET)$(MKDIR) $(APIPATH)
572	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(APIPATH) -genpath $(GENERATED) apiinc
573
574hostsyncinc: $(HOSTSYNCDEPEND)
575
576$(HOSTSYNCDEPEND): $(VKXML) $(GENVK)
577	$(QUIET)$(MKDIR) $(HOSTSYNCPATH)
578	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(HOSTSYNCPATH) hostsyncinc
579
580validinc: $(VALIDITYDEPEND)
581
582$(VALIDITYDEPEND): $(VKXML) $(GENVK)
583	$(QUIET)$(MKDIR) $(VALIDITYPATH)
584	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(VALIDITYPATH) validinc
585
586extinc: $(METAPATH)/timeMarker
587
588$(METADEPEND): $(VKXML) $(GENVK)
589	$(QUIET)$(MKDIR) $(METAPATH)
590	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(METAPATH) extinc
591
592interfaceinc: $(INTERFACEPATH)/timeMarker
593
594$(INTERFACEDEPEND): $(VKXML) $(GENVK)
595	$(QUIET)$(MKDIR) $(INTERFACEPATH)
596	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(INTERFACEPATH) interfaceinc
597
598# This generates a single file, so SPIRVCAPDEPEND is the full path to
599# the file, rather than to a timeMarker in the same directory.
600spirvcapinc: $(SPIRVCAPDEPEND)
601
602$(SPIRVCAPDEPEND): $(VKXML) $(GENVK)
603	$(QUIET)$(MKDIR) $(SPIRVCAPPATH)
604	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(SPIRVCAPPATH) spirvcapinc
605
606# This generates a single file, so FORMATSDEPEND is the full path to
607# the file, rather than to a timeMarker in the same directory.
608formatsinc: $(FORMATSDEPEND)
609
610$(FORMATSDEPEND): $(VKXML) $(GENVK)
611	$(QUIET)$(MKDIR) $(FORMATSPATH)
612	$(QUIET)$(PYTHON) $(GENVK) $(GENVKOPTS) -o $(FORMATSPATH) formatsinc
613
614# Debugging aid - generate all files from registry XML
615generated: $(GENERATED)/api.py $(GENDEPENDS)
616