blob: a2002aae146ea7ebe72aca65aafc08e0ce56c8f6 [file] [log] [blame]
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -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
22import filecmp
23import os
24import shutil
25import subprocess
26import sys
27import tempfile
28
29import common_codegen
30
31# files to exclude from --verify check
32verify_exclude = ['.clang-format']
33
34def main(argv):
35 parser = argparse.ArgumentParser(description='Generate source code for this repository')
36 parser.add_argument('registry', metavar='REGISTRY_PATH', help='path to the Vulkan-Headers registry directory')
37 group = parser.add_mutually_exclusive_group()
38 group.add_argument('-i', '--incremental', action='store_true', help='only update repo files that change')
39 group.add_argument('-v', '--verify', action='store_true', help='verify repo files match generator output')
40 args = parser.parse_args(argv)
41
Charles Giessen5aaa6432020-04-25 18:53:21 -060042 # output paths and the list of files in the path
43 files_to_gen = {str(os.path.join('icd','generated')) : ['vk_typemap_helper.h',
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -070044 'mock_icd.h',
Charles Giessen5aaa6432020-04-25 18:53:21 -060045 'mock_icd.cpp'],
46 str(os.path.join('vulkaninfo','generated')): ['vulkaninfo.hpp']}
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -070047
Charles Giessen5aaa6432020-04-25 18:53:21 -060048 #base directory for the source repository
49 repo_dir = common_codegen.repo_relative('')
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -070050
Charles Giessen5aaa6432020-04-25 18:53:21 -060051 # get directory where generators will run if needed
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -070052 if args.verify or args.incremental:
53 # generate in temp directory so we can compare or copy later
54 temp_obj = tempfile.TemporaryDirectory(prefix='VulkanLoader_generated_source_')
55 temp_dir = temp_obj.name
Charles Giessen5aaa6432020-04-25 18:53:21 -060056 for path in files_to_gen.keys():
57 os.makedirs(os.path.join(temp_dir, path))
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -070058
59 # run each code generator
Charles Giessen5aaa6432020-04-25 18:53:21 -060060 for path, filenames in files_to_gen.items():
61 for filename in filenames:
62 if args.verify or args.incremental:
63 output_path = os.path.join(temp_dir, path)
64 else:
65 output_path = common_codegen.repo_relative(path)
66
67 cmd = [common_codegen.repo_relative(os.path.join('scripts','kvt_genvk.py')),
68 '-registry', os.path.abspath(os.path.join(args.registry, 'vk.xml')),
69 '-quiet', '-directory', output_path, filename]
70 print(' '.join(cmd))
71 try:
72 if args.verify or args.incremental:
73 subprocess.check_call([sys.executable] + cmd, cwd=temp_dir)
74 else:
75 subprocess.check_call([sys.executable] + cmd, cwd=repo_dir)
76
77 except Exception as e:
78 print('ERROR:', str(e))
79 return 1
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -070080
81 # optional post-generation steps
82 if args.verify:
83 # compare contents of temp dir and repo
Charles Giessen5aaa6432020-04-25 18:53:21 -060084 temp_files = {}
85 for path in files_to_gen.keys():
86 temp_files[path] = set()
87 temp_files[path].update(set(os.listdir(os.path.join(temp_dir, path))))
88
89 repo_files = {}
90 for path in files_to_gen.keys():
91 repo_files[path] = set()
92 repo_files[path].update(set(os.listdir(os.path.join(repo_dir, path))) - set(verify_exclude))
93
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -070094 files_match = True
Charles Giessen5aaa6432020-04-25 18:53:21 -060095 for path in files_to_gen.keys():
96 for filename in sorted((temp_files[path] | repo_files[path])):
97 if filename not in repo_files[path]:
98 print('ERROR: Missing repo file', filename)
99 files_match = False
100 elif filename not in temp_files[path]:
101 print('ERROR: Missing generator for', filename)
102 files_match = False
103 elif not filecmp.cmp(os.path.join(temp_dir, path, filename),
104 os.path.join(repo_dir, path, filename),
105 shallow=False):
106 print('ERROR: Repo files do not match generator output for', filename)
107 files_match = False
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -0700108
109 # return code for test scripts
110 if files_match:
111 print('SUCCESS: Repo files match generator output')
112 return 0
113 return 1
114
115 elif args.incremental:
116 # copy missing or differing files from temp directory to repo
Charles Giessen5aaa6432020-04-25 18:53:21 -0600117 for path in files_to_gen.keys():
118 for filename in os.listdir(os.path.join(temp_dir,path)):
119 temp_filename = os.path.join(temp_dir, path, filename)
120 repo_filename = os.path.join(repo_dir, path, filename)
121 if not os.path.exists(repo_filename) or \
122 not filecmp.cmp(temp_filename, repo_filename, shallow=False):
123 print('update', repo_filename)
124 shutil.copyfile(temp_filename, repo_filename)
Mike Schuchardt6a0ba2c2019-07-22 16:57:15 -0700125
126 return 0
127
128if __name__ == '__main__':
129 sys.exit(main(sys.argv[1:]))
130