Mike Schuchardt | 6a0ba2c | 2019-07-22 16:57:15 -0700 | [diff] [blame] | 1 | #!/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 | |
| 21 | import argparse |
| 22 | import filecmp |
| 23 | import os |
| 24 | import shutil |
| 25 | import subprocess |
| 26 | import sys |
| 27 | import tempfile |
| 28 | |
| 29 | import common_codegen |
| 30 | |
| 31 | # files to exclude from --verify check |
| 32 | verify_exclude = ['.clang-format'] |
| 33 | |
| 34 | def 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 | |
| 42 | gen_cmds = [[common_codegen.repo_relative('scripts/kvt_genvk.py'), |
| 43 | '-registry', os.path.abspath(os.path.join(args.registry, 'vk.xml')), |
| 44 | '-quiet', |
| 45 | filename] for filename in ['vk_typemap_helper.h', |
| 46 | 'mock_icd.h', |
| 47 | 'mock_icd.cpp']] |
| 48 | |
| 49 | repo_dir = common_codegen.repo_relative('icd/generated') |
| 50 | |
| 51 | # get directory where generators will run |
| 52 | 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 |
| 56 | gen_dir = temp_dir |
| 57 | else: |
| 58 | # generate directly in the repo |
| 59 | gen_dir = repo_dir |
| 60 | |
| 61 | # run each code generator |
| 62 | for cmd in gen_cmds: |
| 63 | print(' '.join(cmd)) |
| 64 | try: |
| 65 | subprocess.check_call([sys.executable] + cmd, cwd=gen_dir) |
| 66 | except Exception as e: |
| 67 | print('ERROR:', str(e)) |
| 68 | return 1 |
| 69 | |
| 70 | # optional post-generation steps |
| 71 | if args.verify: |
| 72 | # compare contents of temp dir and repo |
| 73 | temp_files = set(os.listdir(temp_dir)) |
| 74 | repo_files = set(os.listdir(repo_dir)) |
| 75 | files_match = True |
| 76 | for filename in sorted((temp_files | repo_files) - set(verify_exclude)): |
| 77 | if filename not in repo_files: |
| 78 | print('ERROR: Missing repo file', filename) |
| 79 | files_match = False |
| 80 | elif filename not in temp_files: |
| 81 | print('ERROR: Missing generator for', filename) |
| 82 | files_match = False |
| 83 | elif not filecmp.cmp(os.path.join(temp_dir, filename), |
| 84 | os.path.join(repo_dir, filename), |
| 85 | shallow=False): |
| 86 | print('ERROR: Repo files do not match generator output for', filename) |
| 87 | files_match = False |
| 88 | |
| 89 | # return code for test scripts |
| 90 | if files_match: |
| 91 | print('SUCCESS: Repo files match generator output') |
| 92 | return 0 |
| 93 | return 1 |
| 94 | |
| 95 | elif args.incremental: |
| 96 | # copy missing or differing files from temp directory to repo |
| 97 | for filename in os.listdir(temp_dir): |
| 98 | temp_filename = os.path.join(temp_dir, filename) |
| 99 | repo_filename = os.path.join(repo_dir, filename) |
| 100 | if not os.path.exists(repo_filename) or \ |
| 101 | not filecmp.cmp(temp_filename, repo_filename, shallow=False): |
| 102 | print('update', repo_filename) |
| 103 | shutil.copyfile(temp_filename, repo_filename) |
| 104 | |
| 105 | return 0 |
| 106 | |
| 107 | if __name__ == '__main__': |
| 108 | sys.exit(main(sys.argv[1:])) |
| 109 | |