blob: 5421d4176b16bff6ec78ef7535c210d7289bd406 [file] [log] [blame]
Mike Stroyandee76ef2016-01-07 15:35:37 -07001#!/usr/bin/env python
2#
3# Copyright (c) 2013-2015 The Khronos Group Inc.
4#
5# Permission is hereby granted, free of charge, to any person obtaining a
6# copy of this software and/or associated documentation files (the
7# "Materials"), to deal in the Materials without restriction, including
8# without limitation the rights to use, copy, modify, merge, publish,
9# distribute, sublicense, and/or sell copies of the Materials, and to
10# permit persons to whom the Materials are furnished to do so, subject to
11# the following conditions:
12#
13# The above copyright notice and this permission notice shall be included
14# in all copies or substantial portions of the Materials.
15#
16# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
23
24import sys, time, pdb, string, cProfile
25from reg import *
26from generator import write, CGeneratorOptions, COutputGenerator, DocGeneratorOptions, DocOutputGenerator, PyOutputGenerator, ValidityOutputGenerator, HostSynchronizationOutputGenerator
27
28# debug - start header generation in debugger
29# dump - dump registry after loading
30# profile - enable Python profiling
31# protect - whether to use #ifndef protections
32# registry <filename> - use specified XML registry instead of gl.xml
33# target - string name of target header, or all targets if None
34# timeit - time length of registry loading & header generation
35# validate - validate return & parameter group tags against <group>
36debug = False
37dump = False
38profile = False
39protect = True
40target = None
41timeit = False
42validate= False
43# Default input / log files
44errFilename = None
45diagFilename = 'diag.txt'
46regFilename = 'vk.xml'
47
48if __name__ == '__main__':
49 i = 1
50 while (i < len(sys.argv)):
51 arg = sys.argv[i]
52 i = i + 1
53 if (arg == '-debug'):
54 write('Enabling debug (-debug)', file=sys.stderr)
55 debug = True
56 elif (arg == '-dump'):
57 write('Enabling dump (-dump)', file=sys.stderr)
58 dump = True
59 elif (arg == '-noprotect'):
60 write('Disabling inclusion protection in output headers', file=sys.stderr)
61 protect = False
62 elif (arg == '-profile'):
63 write('Enabling profiling (-profile)', file=sys.stderr)
64 profile = True
65 elif (arg == '-registry'):
66 regFilename = sys.argv[i]
67 i = i+1
68 write('Using registry ', regFilename, file=sys.stderr)
69 elif (arg == '-time'):
70 write('Enabling timing (-time)', file=sys.stderr)
71 timeit = True
72 elif (arg == '-validate'):
73 write('Enabling group validation (-validate)', file=sys.stderr)
74 validate = True
75 elif (arg[0:1] == '-'):
76 write('Unrecognized argument:', arg, file=sys.stderr)
77 exit(1)
78 else:
79 target = arg
80 write('Using target', target, file=sys.stderr)
81
82# Simple timer functions
83startTime = None
84def startTimer():
85 global startTime
86 startTime = time.clock()
87def endTimer(msg):
88 global startTime
89 endTime = time.clock()
90 if (timeit):
91 write(msg, endTime - startTime)
92 startTime = None
93
94# Load & parse registry
95reg = Registry()
96
97startTimer()
98tree = etree.parse(regFilename)
99endTimer('Time to make ElementTree =')
100
101startTimer()
102reg.loadElementTree(tree)
103endTimer('Time to parse ElementTree =')
104
105if (validate):
106 reg.validateGroups()
107
108if (dump):
109 write('***************************************')
110 write('Performing Registry dump to regdump.txt')
111 write('***************************************')
112 reg.dumpReg(filehandle = open('regdump.txt','w'))
113
114# Turn a list of strings into a regexp string matching exactly those strings
115def makeREstring(list):
116 return '^(' + '|'.join(list) + ')$'
117
118# Descriptive names for various regexp patterns used to select
119# versions and extensions
120allVersions = allExtensions = '.*'
121noVersions = noExtensions = None
122
123# Copyright text prefixing all headers (list of strings).
124prefixStrings = [
125 '/*',
126 '** Copyright (c) 2015 The Khronos Group Inc.',
127 '**',
128 '** Permission is hereby granted, free of charge, to any person obtaining a',
129 '** copy of this software and/or associated documentation files (the',
130 '** "Materials"), to deal in the Materials without restriction, including',
131 '** without limitation the rights to use, copy, modify, merge, publish,',
132 '** distribute, sublicense, and/or sell copies of the Materials, and to',
133 '** permit persons to whom the Materials are furnished to do so, subject to',
134 '** the following conditions:',
135 '**',
136 '** The above copyright notice and this permission notice shall be included',
137 '** in all copies or substantial portions of the Materials.',
138 '**',
139 '** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,',
140 '** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF',
141 '** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.',
142 '** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY',
143 '** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,',
144 '** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE',
145 '** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.',
146 '*/',
147 ''
148]
149
150# Text specific to Vulkan headers
151vkPrefixStrings = [
152 '/*',
153 '** This header is generated from the Khronos Vulkan XML API Registry.',
154 '**',
155 '*/',
156 ''
157]
158
159# Defaults for generating re-inclusion protection wrappers (or not)
160protectFile = protect
161protectFeature = protect
162protectProto = protect
163
164buildList = [
165 # Vulkan 1.0 - core API + extensions. To generate just the core API,
166 # change to 'defaultExtensions = None' below.
167 [ COutputGenerator,
168 CGeneratorOptions(
169 filename = '../vulkan/vulkan.h',
170 apiname = 'vulkan',
171 profile = None,
172 versions = allVersions,
173 emitversions = allVersions,
174 defaultExtensions = 'vulkan',
175 addExtensions = None,
176 removeExtensions = None,
177 prefixText = prefixStrings + vkPrefixStrings,
178 genFuncPointers = True,
179 protectFile = protectFile,
180 protectFeature = False,
181 protectProto = '#ifndef',
182 protectProtoStr = 'VK_NO_PROTOTYPES',
183 apicall = 'VKAPI_ATTR ',
184 apientry = 'VKAPI_CALL ',
185 apientryp = 'VKAPI_PTR *',
186 alignFuncParam = 48)
187 ],
188 # Vulkan 1.0 draft - core API include files for spec
189 # Overwrites include subdirectories in spec source tree
190 # The generated include files do not include the calling convention
191 # macros (apientry etc.), unlike the header files.
192 [ DocOutputGenerator,
193 DocGeneratorOptions(
194 filename = 'vulkan-docs',
195 apiname = 'vulkan',
196 profile = None,
197 versions = allVersions,
198 emitversions = allVersions,
199 defaultExtensions = 'vulkan',
200 addExtensions = None,
201 removeExtensions = None,
202 prefixText = prefixStrings + vkPrefixStrings,
203 apicall = '',
204 apientry = '',
205 apientryp = '*',
206 genDirectory = '../../doc/specs/vulkan',
207 alignFuncParam = 48,
208 expandEnumerants = False)
209 ],
210 # Vulkan 1.0 draft - API names to validate man/api spec includes & links
211 # filename = 'vkapi.py',
212 [ PyOutputGenerator,
213 DocGeneratorOptions(
214 filename = '../../doc/specs/vulkan/vkapi.py',
215 apiname = 'vulkan',
216 profile = None,
217 versions = allVersions,
218 emitversions = allVersions,
219 defaultExtensions = None,
220 addExtensions = None,
221 removeExtensions = None)
222 ],
223 # Vulkan 1.0 draft - core API include files for spec
224 # Overwrites include subdirectories in spec source tree
225 [ ValidityOutputGenerator,
226 DocGeneratorOptions(
227 filename = 'validity',
228 apiname = 'vulkan',
229 profile = None,
230 versions = allVersions,
231 emitversions = allVersions,
232 defaultExtensions = None,
233 addExtensions = None,
234 removeExtensions = None,
235 genDirectory = '../../doc/specs/vulkan')
236 ],
237 # Vulkan 1.0 draft - core API include files for spec
238 # Overwrites include subdirectories in spec source tree
239 [ HostSynchronizationOutputGenerator,
240 DocGeneratorOptions(
241 filename = 'hostsynctable',
242 apiname = 'vulkan',
243 profile = None,
244 versions = allVersions,
245 emitversions = allVersions,
246 defaultExtensions = None,
247 addExtensions = None,
248 removeExtensions = None,
249 genDirectory = '../../doc/specs/vulkan')
250 ],
251 None
252]
253
254# create error/warning & diagnostic files
255if (errFilename):
256 errWarn = open(errFilename,'w')
257else:
258 errWarn = sys.stderr
259diag = open(diagFilename, 'w')
260
261def genHeaders():
262 # Loop over targets, building each
263 generated = 0
264 for item in buildList:
265 if (item == None):
266 break
267 createGenerator = item[0]
268 genOpts = item[1]
269 if (target and target != genOpts.filename):
270 # write('*** Skipping', genOpts.filename)
271 continue
272 write('*** Building', genOpts.filename)
273 generated = generated + 1
274 startTimer()
275 gen = createGenerator(errFile=errWarn,
276 warnFile=errWarn,
277 diagFile=diag)
278 reg.setGenerator(gen)
279 reg.apiGen(genOpts)
280 write('** Generated', genOpts.filename)
281 endTimer('Time to generate ' + genOpts.filename + ' =')
282 if (target and generated == 0):
283 write('Failed to generate target:', target)
284
285if (debug):
286 pdb.run('genHeaders()')
287elif (profile):
288 import cProfile, pstats
289 cProfile.run('genHeaders()', 'profile.txt')
290 p = pstats.Stats('profile.txt')
291 p.strip_dirs().sort_stats('time').print_stats(50)
292else:
293 genHeaders()