#!/usr/bin/env python3 # # Copyright 2020-2022 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 all - make a spec with all registered extensions # -version {1.0 | 1.1 | 1.2 | 1.3} - 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 # -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', 'all' ], default='core', help='Type of spec to generate') parser.add_argument('-version', action='store', choices=[ '1.0', '1.1', '1.2', '1.3' ], default='1.3', 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('-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 should come from the extdependency module as well, eventually versionDict = { '1.0' : [ 'VK_VERSION_1_0' ], '1.1' : [ 'VK_VERSION_1_0', 'VK_VERSION_1_1' ], '1.2' : [ 'VK_VERSION_1_0', 'VK_VERSION_1_1', 'VK_VERSION_1_2' ], '1.3' : [ 'VK_VERSION_1_0', 'VK_VERSION_1_1', 'VK_VERSION_1_2', 'VK_VERSION_1_3' ], } versions = 'VERSIONS={}'.format(' '.join(versionDict[results.version])) # 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() if results.spec == 'khr': title = 'with all KHR extensions' exts = set(deps.khrExtensions()) elif results.spec == 'all': title = 'with all registered extensions' exts = set(deps.allExtensions()) # List of explicitly requested extension and all its dependencies extraexts = set() for name in results.extension: if name in deps.allExtensions(): extraexts.add(name) extraexts.update(deps.children(name)) 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) 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)