blob: b3092ff60a1b9ed7d619b7cb355508375b3f2775 [file] [log] [blame]
#!/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())