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