blob: a2002aae146ea7ebe72aca65aafc08e0ce56c8f6 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (c) 2019 The Khronos Group Inc.
# Copyright (c) 2019 Valve Corporation
# Copyright (c) 2019 LunarG, Inc.
# Copyright (c) 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Mike Schuchardt <mikes@lunarg.com>
import argparse
import filecmp
import os
import shutil
import subprocess
import sys
import tempfile
import common_codegen
# files to exclude from --verify check
verify_exclude = ['.clang-format']
def main(argv):
parser = argparse.ArgumentParser(description='Generate source code for this repository')
parser.add_argument('registry', metavar='REGISTRY_PATH', help='path to the Vulkan-Headers registry directory')
group = parser.add_mutually_exclusive_group()
group.add_argument('-i', '--incremental', action='store_true', help='only update repo files that change')
group.add_argument('-v', '--verify', action='store_true', help='verify repo files match generator output')
args = parser.parse_args(argv)
# output paths and the list of files in the path
files_to_gen = {str(os.path.join('icd','generated')) : ['vk_typemap_helper.h',
'mock_icd.h',
'mock_icd.cpp'],
str(os.path.join('vulkaninfo','generated')): ['vulkaninfo.hpp']}
#base directory for the source repository
repo_dir = common_codegen.repo_relative('')
# get directory where generators will run if needed
if args.verify or args.incremental:
# generate in temp directory so we can compare or copy later
temp_obj = tempfile.TemporaryDirectory(prefix='VulkanLoader_generated_source_')
temp_dir = temp_obj.name
for path in files_to_gen.keys():
os.makedirs(os.path.join(temp_dir, path))
# run each code generator
for path, filenames in files_to_gen.items():
for filename in filenames:
if args.verify or args.incremental:
output_path = os.path.join(temp_dir, path)
else:
output_path = common_codegen.repo_relative(path)
cmd = [common_codegen.repo_relative(os.path.join('scripts','kvt_genvk.py')),
'-registry', os.path.abspath(os.path.join(args.registry, 'vk.xml')),
'-quiet', '-directory', output_path, filename]
print(' '.join(cmd))
try:
if args.verify or args.incremental:
subprocess.check_call([sys.executable] + cmd, cwd=temp_dir)
else:
subprocess.check_call([sys.executable] + cmd, cwd=repo_dir)
except Exception as e:
print('ERROR:', str(e))
return 1
# optional post-generation steps
if args.verify:
# compare contents of temp dir and repo
temp_files = {}
for path in files_to_gen.keys():
temp_files[path] = set()
temp_files[path].update(set(os.listdir(os.path.join(temp_dir, path))))
repo_files = {}
for path in files_to_gen.keys():
repo_files[path] = set()
repo_files[path].update(set(os.listdir(os.path.join(repo_dir, path))) - set(verify_exclude))
files_match = True
for path in files_to_gen.keys():
for filename in sorted((temp_files[path] | repo_files[path])):
if filename not in repo_files[path]:
print('ERROR: Missing repo file', filename)
files_match = False
elif filename not in temp_files[path]:
print('ERROR: Missing generator for', filename)
files_match = False
elif not filecmp.cmp(os.path.join(temp_dir, path, filename),
os.path.join(repo_dir, path, filename),
shallow=False):
print('ERROR: Repo files do not match generator output for', filename)
files_match = False
# return code for test scripts
if files_match:
print('SUCCESS: Repo files match generator output')
return 0
return 1
elif args.incremental:
# copy missing or differing files from temp directory to repo
for path in files_to_gen.keys():
for filename in os.listdir(os.path.join(temp_dir,path)):
temp_filename = os.path.join(temp_dir, path, filename)
repo_filename = os.path.join(repo_dir, path, filename)
if not os.path.exists(repo_filename) or \
not filecmp.cmp(temp_filename, repo_filename, shallow=False):
print('update', repo_filename)
shutil.copyfile(temp_filename, repo_filename)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))