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