blob: 3c448adf33983425ed5398ca6d2654c9e8cc5058 [file] [log] [blame]
Mike Schuchardtc64a5412019-07-02 00:27:05 -07001#!/usr/bin/env python3
2# Copyright (c) 2019 The Khronos Group Inc.
3# Copyright (c) 2019 Valve Corporation
4# Copyright (c) 2019 LunarG, Inc.
5# Copyright (c) 2019 Google Inc.
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19# Author: Mike Schuchardt <mikes@lunarg.com>
20
21import argparse
Mike Schuchardte51c74b2019-07-10 17:01:21 -070022import common_codegen
Mike Schuchardtc64a5412019-07-02 00:27:05 -070023import filecmp
24import os
25import shutil
26import subprocess
27import sys
28import tempfile
29
30# files to exclude from --verify check
31verify_exclude = ['.clang-format']
32
Mike Schuchardtc64a5412019-07-02 00:27:05 -070033def main(argv):
34 parser = argparse.ArgumentParser(description='Generate source code for this repository')
35 parser.add_argument('registry', metavar='REGISTRY_PATH', help='path to the Vulkan-Headers registry directory')
36 group = parser.add_mutually_exclusive_group()
37 group.add_argument('-i', '--incremental', action='store_true', help='only update repo files that change')
38 group.add_argument('-v', '--verify', action='store_true', help='verify repo files match generator output')
39 args = parser.parse_args(argv)
40
Mike Schuchardte51c74b2019-07-10 17:01:21 -070041 gen_cmds = [*[[common_codegen.repo_relative('scripts/lvl_genvk.py'),
Mike Schuchardtc64a5412019-07-02 00:27:05 -070042 '-registry', os.path.abspath(os.path.join(args.registry, 'vk.xml')),
43 '-quiet',
44 filename] for filename in ["chassis.cpp",
45 "chassis.h",
46 "layer_chassis_dispatch.cpp",
47 "layer_chassis_dispatch.h",
48 "object_tracker.cpp",
49 "object_tracker.h",
50 "parameter_validation.cpp",
51 "parameter_validation.h",
52 "thread_safety.cpp",
53 "thread_safety.h",
54 "vk_dispatch_table_helper.h",
55 "vk_enum_string_helper.h",
56 "vk_extension_helper.h",
57 "vk_layer_dispatch_table.h",
58 "vk_object_types.h",
59 "vk_safe_struct.cpp",
60 "vk_safe_struct.h",
61 "vk_typemap_helper.h"]],
Mike Schuchardte51c74b2019-07-10 17:01:21 -070062 [common_codegen.repo_relative('scripts/vk_validation_stats.py'),
Mike Schuchardtc64a5412019-07-02 00:27:05 -070063 os.path.abspath(os.path.join(args.registry, 'validusage.json')),
64 '-export_header'],
Mike Schuchardte51c74b2019-07-10 17:01:21 -070065 [common_codegen.repo_relative('scripts/external_revision_generator.py'),
66 '--rev_file', common_codegen.repo_relative('scripts/known_good.json'),
Mike Schuchardtc64a5412019-07-02 00:27:05 -070067 '-s', 'SPIRV_TOOLS_COMMIT_ID',
68 '-o', 'spirv_tools_commit_id.h']]
69
Mike Schuchardte51c74b2019-07-10 17:01:21 -070070 repo_dir = common_codegen.repo_relative('layers/generated')
Mike Schuchardtc64a5412019-07-02 00:27:05 -070071
72 # get directory where generators will run
73 if args.verify or args.incremental:
74 # generate in temp directory so we can compare or copy later
75 temp_obj = tempfile.TemporaryDirectory(prefix='VulkanVL_generated_source_')
76 temp_dir = temp_obj.name
77 gen_dir = temp_dir
78 else:
79 # generate directly in the repo
80 gen_dir = repo_dir
81
82 # run each code generator
83 for cmd in gen_cmds:
84 print(' '.join(cmd))
85 try:
86 subprocess.check_call([sys.executable] + cmd,
87 # ignore generator output, vk_validation_stats.py is especially noisy
88 stdout=subprocess.DEVNULL,
89 cwd=gen_dir)
90 except Exception as e:
91 print('ERROR:', str(e))
92 return 1
93
94 # optional post-generation steps
95 if args.verify:
96 # compare contents of temp dir and repo
97 temp_files = set(os.listdir(temp_dir))
98 repo_files = set(os.listdir(repo_dir))
99 files_match = True
100 for filename in sorted((temp_files | repo_files) - set(verify_exclude)):
101 if filename not in repo_files:
102 print('ERROR: Missing repo file', filename)
103 files_match = False
104 elif filename not in temp_files:
105 print('ERROR: Missing generator for', filename)
106 files_match = False
107 elif not filecmp.cmp(os.path.join(temp_dir, filename),
108 os.path.join(repo_dir, filename),
109 shallow=False):
110 print('ERROR: Repo files do not match generator output for', filename)
111 files_match = False
112
113 # return code for test scripts
114 if files_match:
115 print('SUCCESS: Repo files match generator output')
116 return 0
117 return 1
118
119 elif args.incremental:
120 # copy missing or differing files from temp directory to repo
121 for filename in os.listdir(temp_dir):
122 temp_filename = os.path.join(temp_dir, filename)
123 repo_filename = os.path.join(repo_dir, filename)
124 if not os.path.exists(repo_filename) or \
125 not filecmp.cmp(temp_filename, repo_filename, shallow=False):
126 print('update', repo_filename)
127 shutil.copyfile(temp_filename, repo_filename)
128
129 return 0
130
131if __name__ == '__main__':
132 sys.exit(main(sys.argv[1:]))
133