• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3# Copyright 2020-2021 The Khronos Group Inc.
4#
5# SPDX-License-Identifier: Apache-2.0
6
7# Build a spec with requested extension sets and options.
8#
9# Usage: makeSpec script-options make-options
10# Script options are parsed by this script before invoking 'make':
11#   -genpath path - directory for generated files and outputs
12#   -spec core - make a spec with no extensions (default)
13#   -spec khr - make a spec with all KHR extensions
14#   -spec all - make a spec with all registered extensions
15#   -version {1.0 | 1.1 | 1.2} - make a spec with this core version
16#   -ext name - add specified extension and its dependencies
17#   -clean - clean generated files before building
18#   -v - verbose, print actions before executing  them
19#   -n - dry-run, print actions instead of executing them
20# make-options - all other options are passed to 'make', including
21# requested build targets
22
23import argparse, copy, io, os, re, string, subprocess, sys
24
25def execute(args, results):
26    if results.verbose or results.dryrun:
27        print("'" + "' '".join(args) + "'")
28    if not results.dryrun:
29        subprocess.check_call(args)
30
31if __name__ == '__main__':
32    parser = argparse.ArgumentParser()
33
34    parser.add_argument('-clean', action='store_true',
35                        help='Clean generated files before building')
36    parser.add_argument('-extension', action='append',
37                        default=[],
38                        help='Specify a required extension or extensions to add to targets')
39    parser.add_argument('-genpath', action='store',
40                        default='gen',
41                        help='Path to directory containing generated files')
42    parser.add_argument('-spec', action='store',
43                        choices=[ 'core', 'khr', 'all' ],
44                        default='core',
45                        help='Type of spec to generate')
46    parser.add_argument('-version', action='store',
47                        choices=[ '1.0', '1.1', '1.2' ],
48                        default='1.2',
49                        help='Type of spec to generate')
50    parser.add_argument('-n', action='store_true', dest='dryrun',
51                        help='Only prints actions, do not execute them')
52    parser.add_argument('-v', action='store_true', dest='verbose',
53                        help='Print actions before executing them')
54
55    (results, options) = parser.parse_known_args()
56
57    # Ensure genpath is an absolute path, not relative
58    if results.genpath[0] != '/':
59        results.genpath = os.getcwd() + '/' + results.genpath
60
61    # Ensure extDependency.py exists and is up to date before importing it
62    try:
63        execute(['make', 'GENERATED=' + results.genpath, 'extDependency'], results)
64
65        # Look for extDependency.py in the specified directory and import it
66        sys.path.insert(0, results.genpath)
67        from extDependency import extensions, allExts, khrExts
68    except:
69        print('Cannot execute "make extDependency" or determine correct extension list', file=sys.stderr)
70
71    # List of versions to build with from the requested -version
72    versionDict = {
73        '1.0' : [ 'VK_VERSION_1_0' ],
74        '1.1' : [ 'VK_VERSION_1_0', 'VK_VERSION_1_1' ],
75        '1.2' : [ 'VK_VERSION_1_0', 'VK_VERSION_1_1', 'VK_VERSION_1_2' ],
76    }
77    versions = 'VERSIONS={}'.format(' '.join(versionDict[results.version]))
78
79    # List of extensions to build with from the requested -spec
80    # Also construct a spec title
81    if results.spec == 'core':
82        title = ''
83        exts = set()
84    if results.spec == 'khr':
85        title = 'with all KHR extensions'
86        exts = set(khrExts)
87    elif results.spec == 'all':
88        title = 'with all registered extensions'
89        exts = set(allExts)
90
91    # List of explicitly requested extension and all its dependencies
92    extraexts = set()
93    for name in results.extension:
94        if name in extensions:
95            extraexts.add(name)
96            extraexts.update(extensions[name])
97        else:
98            print('ERROR: unknown extension', name, file=sys.stderr)
99            sys.exit(1)
100
101    # See if any explicitly requested extensions aren't implicitly requested
102    # Add any such extensions to the spec title
103    extraexts -= exts
104    if len(extraexts) > 0:
105        exts.update(extraexts)
106        if title != '':
107            title += ' and ' + ', '.join(sorted(extraexts))
108        else:
109            title += 'with ' + ', '.join(sorted(extraexts))
110
111    if title != '':
112        title = '(' + title + ')'
113
114    # Finally, actually invoke make as needed for the targets
115    args = [ 'make', 'GENERATED=' + results.genpath ]
116
117    if results.clean:
118        execute(args + ['clean'], results)
119
120    args.append(versions)
121
122    # The actual target
123    if len(exts) > 0:
124        args.append('EXTENSIONS={}'.format(' '.join(sorted(exts))))
125    args.append('APITITLE={}'.format(title))
126    args += options
127
128    try:
129        execute(args, results)
130    except:
131        sys.exit(1)
132