-
Notifications
You must be signed in to change notification settings - Fork 472
/
makeSpec
executable file
·180 lines (160 loc) · 7.08 KB
/
makeSpec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/env python3
#
# Copyright 2020-2024 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
# Build a spec with requested extension sets and options.
#
# Usage: makeSpec script-options make-options
# Script options are parsed by this script before invoking 'make':
# -genpath path - directory for generated files and outputs
# -spec core - make a spec with no extensions (default)
# -spec khr - make a spec with all KHR extensions
# -spec ratified - make a spec with all ratified (KHR + some EXT) extensions
# -spec all - make a spec with all registered extensions
# -version {1.0 | 1.1 | 1.2 | 1.3 | 1.4 | sc1.0} - make a spec with this core version
# -ext name - add specified extension and its dependencies
# -clean - clean generated files before building
# -registry path - API XML to use instead of default
# -apiname name - API name to use instead of default
# -test - Build the test spec instead
# -v - verbose, print actions before executing them
# -n - dry-run, print actions instead of executing them
# make-options - all other options are passed to 'make', including
# requested build targets
import argparse, copy, io, os, re, string, subprocess, sys
def execute(args, results):
if results.verbose or results.dryrun:
print("'" + "' '".join(args) + "'")
if not results.dryrun:
subprocess.check_call(args)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-clean', action='store_true',
help='Clean generated files before building')
parser.add_argument('-extension', action='append',
default=[],
help='Specify a required extension or extensions to add to targets')
parser.add_argument('-genpath', action='store',
default='gen',
help='Path to directory containing generated files')
parser.add_argument('-spec', action='store',
choices=[ 'core', 'khr', 'ratified', 'all' ],
default='core',
help='Type of spec to generate')
parser.add_argument('-version', action='store',
choices=[ '1.0', '1.1', '1.2', '1.3', '1.4', 'sc1.0' ],
default='1.4',
help='Type of spec to generate')
parser.add_argument('-registry', action='store',
default=None,
help='Path to API XML registry file specifying version and extension dependencies')
parser.add_argument('-apiname', action='store',
default=None,
help='API name to generate')
parser.add_argument('-test', action='store_true',
help='Build the test spec instead of the Vulkan spec')
parser.add_argument('-n', action='store_true', dest='dryrun',
help='Only prints actions, do not execute them')
parser.add_argument('-v', action='store_true', dest='verbose',
help='Print actions before executing them')
(results, options) = parser.parse_known_args()
# Ensure genpath is an absolute path, not relative
if results.genpath[0] != '/':
results.genpath = os.getcwd() + '/' + results.genpath
# Look for scripts/extdependency.py
# This requires makeSpec to be invoked from the repository root, but we
# could derive that path.
sys.path.insert(0, 'scripts')
from extdependency import ApiDependencies
deps = ApiDependencies(results.registry, results.apiname)
# List of versions to build with from the requested -version
# This is constructed from the XML version dependencies
versionDict = {
'1.0' : [ 'VK_VERSION_1_0' ],
'1.1' : [ 'VK_VERSION_1_1' ],
'1.2' : [ 'VK_VERSION_1_2' ],
'1.3' : [ 'VK_VERSION_1_3' ],
'1.4' : [ 'VK_VERSION_1_4' ],
'sc1.0' : [ 'VKSC_VERSION_1_0' ],
}
depversions = set()
reqVer = versionDict[results.version][0]
if reqVer in deps.allVersions():
depversions.add(reqVer)
for dep in deps.versionChildren(reqVer):
if dep in deps.allVersions():
depversions.update({dep})
else:
apitype = f'default apiname' if results.apiname is None else f'requested apiname {results.apiname}'
raise Exception(f'ERROR: unknown version {results.version} for {apitype}')
versions = 'VERSIONS={}'.format(' '.join(sorted(depversions)))
# List of extensions to build with from the requested -spec
# Also construct a spec title
# This should respect version dependencies as well
if results.spec == 'core':
title = ''
exts = set()
elif results.spec == 'khr':
title = 'with all KHR extensions'
exts = set(deps.khrExtensions())
elif results.spec == 'ratified':
title = 'with all ratified extensions'
exts = set(deps.ratifiedExtensions())
elif results.spec == 'all':
title = 'with all registered extensions'
exts = set(deps.allExtensions())
# List of explicitly requested extension and all its supported dependencies
extraexts = set()
for name in results.extension:
if name in deps.allExtensions():
extraexts.add(name)
for dep in deps.children(name):
if dep in deps.allExtensions():
extraexts.update({dep})
else:
raise Exception(f'ERROR: unknown extension {name}')
# See if any explicitly requested extensions are not implicitly requested
# Add any such extensions to the spec title
extraexts -= exts
if len(extraexts) > 0:
exts.update(extraexts)
if title != '':
title += ' and ' + ', '.join(sorted(extraexts))
else:
title += 'with ' + ', '.join(sorted(extraexts))
if title != '':
title = '(' + title + ')'
# Finally, actually invoke make as needed for the targets
args = [ 'make', 'GENERATED=' + results.genpath ]
if results.clean:
# If OUTDIR is set on the command line, pass it to the 'clean'
# target so it is cleaned as well.
cleanopts = ['clean']
for opt in options:
if opt[:7] == 'OUTDIR=':
cleanopts.append(opt)
try:
execute(args + cleanopts, results)
except:
sys.exit(1)
# Use the test spec if specified. This is used solely by self tests.
rootdir = os.path.dirname(os.path.abspath(__file__))
if results.test:
# Set the spec source to the test spec
args.append(f'SPECSRC={rootdir}/build_tests/testspec.adoc')
args.append(f'SPECDIR={rootdir}/build_tests/')
# Make sure the build is invariant
args.append('SPECREVISION=1.2.3')
args.append('SPECDATE=\\"2100-11-22 00:33:44Z\\"')
args.append('SPECREMARK=\\"test build\\"')
args.append(versions)
# The actual target
if len(exts) > 0:
args.append(f'EXTENSIONS={" ".join(sorted(exts))}')
args.append(f'APITITLE={title}')
args += options
try:
execute(args, results)
except:
sys.exit(1)