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