176 строки
5.8 KiB
Python
Executable File
176 строки
5.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# utils/sil-opt-verify-all-modules.py - Verifies Swift modules -*- python -*-
|
|
#
|
|
# This source file is part of the Swift.org open source project
|
|
#
|
|
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
# Licensed under Apache License v2.0 with Runtime Library Exception
|
|
#
|
|
# See https://swift.org/LICENSE.txt for license information
|
|
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
|
|
from __future__ import print_function
|
|
|
|
import argparse
|
|
import glob
|
|
import multiprocessing
|
|
import os
|
|
import pipes
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
|
|
def get_verify_toolchain_modules_commands(toolchain_dir, sil_opt):
|
|
if sil_opt is None:
|
|
sil_opt = os.path.join(toolchain_dir, 'usr', 'bin', 'sil-opt')
|
|
|
|
toolchain_basename = os.path.basename(toolchain_dir)
|
|
if toolchain_basename.startswith('Legacy'):
|
|
return []
|
|
if toolchain_basename.startswith('XcodeDefault'):
|
|
toolchain_name = 'XcodeDefault'
|
|
if toolchain_basename.startswith('tvOS'):
|
|
toolchain_name = 'tvOS'
|
|
if toolchain_basename.startswith('OSX'):
|
|
toolchain_name = 'OSX'
|
|
if toolchain_basename.startswith('watchOS'):
|
|
toolchain_name = 'watchOS'
|
|
if toolchain_basename.startswith('iOS'):
|
|
toolchain_name = 'iOS'
|
|
|
|
return get_verify_resource_dir_modules_commands(
|
|
os.path.join(toolchain_dir, 'usr', 'lib', 'swift'),
|
|
os.path.join(toolchain_dir, 'usr', 'bin', 'sil-opt'),
|
|
toolchain_name)
|
|
|
|
|
|
def get_verify_build_dir_commands(build_dir, toolchain_name='XcodeDefault'):
|
|
return get_verify_resource_dir_modules_commands(
|
|
os.path.join(build_dir, 'lib', 'swift'),
|
|
os.path.join(build_dir, 'bin', 'sil-opt'),
|
|
toolchain_name)
|
|
|
|
|
|
def get_verify_resource_dir_modules_commands(
|
|
resource_dir, sil_opt, toolchain_name):
|
|
print("================================================================")
|
|
print("Resource dir: " + resource_dir)
|
|
print("sil-opt path: " + sil_opt)
|
|
|
|
known_platforms = [
|
|
('appletvos', 'arm64', 'arm64-apple-tvos9.0'),
|
|
('appletvsimulator', 'x86_64', 'x86_64-apple-tvos9.0'),
|
|
('iphoneos', 'armv7', 'armv7-apple-ios7.0'),
|
|
('iphoneos', 'armv7s', 'armv7s-apple-ios7.0'),
|
|
('iphoneos', 'arm64', 'arm64-apple-ios7.0'),
|
|
('iphonesimulator', 'i386', 'i386-apple-ios7.0'),
|
|
('iphonesimulator', 'x86_64', 'x86_64-apple-ios7.0'),
|
|
('macosx', 'x86_64', 'x86_64-apple-macosx10.9'),
|
|
('watchos', 'armv7k', 'armv7k-apple-watchos2.0'),
|
|
('watchsimulator', 'i386', 'i386-apple-watchos2.0'),
|
|
]
|
|
|
|
commands = []
|
|
module_cache_dir = tempfile.mkdtemp(
|
|
prefix="swift-testsuite-clang-module-cache")
|
|
for (subdir, arch, triple) in known_platforms:
|
|
modules_dir = os.path.join(resource_dir, subdir, arch)
|
|
print(modules_dir)
|
|
modules = glob.glob(os.path.join(modules_dir, '*.swiftmodule'))
|
|
for module_file_name in modules:
|
|
if module_file_name.endswith('XCTest.swiftmodule'):
|
|
# FIXME: sil-opt does not have the '-F' option.
|
|
continue
|
|
commands.append([
|
|
'xcrun', '--toolchain', toolchain_name, '--sdk', subdir,
|
|
sil_opt,
|
|
'-target', triple,
|
|
'-resource-dir', resource_dir,
|
|
'-module-cache-path', module_cache_dir,
|
|
'-verify',
|
|
module_file_name,
|
|
])
|
|
|
|
return commands
|
|
|
|
|
|
def quote_shell_command(args):
|
|
return " ".join([pipes.quote(a) for a in args])
|
|
|
|
|
|
def run_commands_in_parallel(commands):
|
|
makefile = ".DEFAULT_GOAL := all\n"
|
|
targets = []
|
|
for c in commands:
|
|
target_name = "target" + str(len(targets))
|
|
targets.append(target_name)
|
|
makefile += target_name + ":\n"
|
|
makefile += \
|
|
"\t" + quote_shell_command(c) + \
|
|
" > {target}.stdout\n".format(target=target_name)
|
|
|
|
makefile += "all: " + " ".join(targets) + "\n"
|
|
|
|
temp_dir = tempfile.mkdtemp(prefix="swift-testsuite-main")
|
|
with open(os.path.join(temp_dir, 'Makefile'), 'w') as makefile_file:
|
|
makefile_file.write(makefile)
|
|
|
|
max_processes = multiprocessing.cpu_count()
|
|
subprocess.check_call([
|
|
'make',
|
|
'-C', temp_dir,
|
|
'-j', str(max_processes),
|
|
'--keep-going'
|
|
])
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
description="""Verifies Swift modules.""")
|
|
parser.add_argument(
|
|
"--sil-opt",
|
|
help="use the specified 'sil-opt' binary",
|
|
metavar="PATH")
|
|
parser.add_argument(
|
|
"--verify-build-dir",
|
|
help="verify the Swift resource directory under the given build dir.",
|
|
metavar="PATH")
|
|
parser.add_argument(
|
|
"--verify-xcode",
|
|
help="verify the Xcode.app that is currently xcode-select'ed",
|
|
action="store_true")
|
|
args = parser.parse_args()
|
|
|
|
if args.verify_build_dir is not None and args.verify_xcode:
|
|
print("--verify-build-dir and --verify-xcode can't be used together")
|
|
return 1
|
|
|
|
if args.verify_build_dir is not None:
|
|
commands = get_verify_build_dir_commands(args.verify_build_dir)
|
|
|
|
if args.verify_xcode:
|
|
# Find Xcode.
|
|
swift_path = subprocess.check_output(['xcrun', '--find', 'swift'])
|
|
xcode_path = swift_path
|
|
for _ in range(0, 7):
|
|
xcode_path = os.path.dirname(xcode_path)
|
|
|
|
toolchains_dir = os.path.join(
|
|
xcode_path, 'Contents', 'Developer', 'Toolchains')
|
|
toolchains = glob.glob(os.path.join(toolchains_dir, '*.xctoolchain'))
|
|
|
|
commands = []
|
|
for toolchain_dir in toolchains:
|
|
commands += get_verify_toolchain_modules_commands(
|
|
toolchain_dir, args.sil_opt)
|
|
|
|
run_commands_in_parallel(commands)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|