diff --git a/SwiftEvolve/.gitignore b/SwiftEvolve/.gitignore index 58de200..5f63f29 100644 --- a/SwiftEvolve/.gitignore +++ b/SwiftEvolve/.gitignore @@ -2,5 +2,7 @@ /.build /Packages /*.xcodeproj +/*.xcconfig +/DerivedData /Package.resolved /.swiftpm diff --git a/build-script-helper.py b/build-script-helper.py index 2894360..bdfb45e 100755 --- a/build-script-helper.py +++ b/build-script-helper.py @@ -2,7 +2,7 @@ """ This source file is part of the Swift.org open source project - + Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception @@ -23,6 +23,9 @@ import os, platform import subprocess +def printerr(message): + print(message, file=sys.stderr) + def main(argv_prefix = []): args = parse_args(argv_prefix + sys.argv[1:]) run(args) @@ -36,7 +39,8 @@ def parse_args(args): parser.add_argument('--config', default='release') parser.add_argument('--build-dir', default='.build') parser.add_argument('--toolchain', required=True, help='the toolchain to use when building this package') - parser.add_argument('build_actions', help="Extra actions to perform. Can be any number of the following: [all, test, install, generate-xcodeproj]", nargs="*", default=[]) + parser.add_argument('--update', action='store_true', help='update all SwiftPM dependencies') + parser.add_argument('build_actions', help="Extra actions to perform. Can be any number of the following", choices=['all', 'build', 'test', 'install', 'generate-xcodeproj'], nargs="*", default=['build']) parsed = parser.parse_args(args) @@ -60,44 +64,100 @@ def run(args): sourcekit_searchpath=args.sourcekitd_dir package_name = os.path.basename(args.package_dir) - print("** Building %s **" % package_name) - invoke_swift(package_dir=args.package_dir, - swift_exec=args.swift_exec, - action='build', - sourcekit_searchpath=sourcekit_searchpath, - build_dir=args.build_dir, - config=args.config, - verbose=args.verbose) + if args.update: + print("** Updating dependencies of %s **" % package_name) + try: + update_swiftpm_dependencies(package_dir=args.package_dir, + swift_exec=args.swift_exec, + build_dir=args.build_dir, + verbose=args.verbose) + except subprocess.CalledProcessError as e: + printerr('FAIL: Updating dependencies of %s failed' % package_name) + printerr('Executing: %s' % ' '.join(e.cmd)) + sys.exit(1) + + # The test action creates its own build. No need to build if we are just testing + if should_run_any_action(['build', 'install'], args.build_actions): + print("** Building %s **" % package_name) + try: + invoke_swift(package_dir=args.package_dir, + swift_exec=args.swift_exec, + action='build', + sourcekit_searchpath=sourcekit_searchpath, + build_dir=args.build_dir, + config=args.config, + verbose=args.verbose) + except subprocess.CalledProcessError as e: + printerr('FAIL: Building %s failed' % package_name) + printerr('Executing: %s' % ' '.join(e.cmd)) + sys.exit(1) output_dir = os.path.realpath(os.path.join(args.build_dir, args.config)) - if "generate-xcodeproj" in args.build_actions or "all" in args.build_actions: + if should_run_action("generate-xcodeproj", args.build_actions): print("** Generating Xcode project for %s **" % package_name) - generate_xcodeproj(args.package_dir, - swift_exec=args.swift_exec, - sourcekit_searchpath=sourcekit_searchpath, - verbose=args.verbose) - - if "test" in args.build_actions or "all" in args.build_actions: + try: + generate_xcodeproj(args.package_dir, + swift_exec=args.swift_exec, + sourcekit_searchpath=sourcekit_searchpath, + verbose=args.verbose) + except subprocess.CalledProcessError as e: + printerr('FAIL: Generating the Xcode project failed') + printerr('Executing: %s' % ' '.join(e.cmd)) + sys.exit(1) + + if should_run_action("test", args.build_actions): print("** Testing %s **" % package_name) - invoke_swift(package_dir=args.package_dir, - swift_exec=args.swift_exec, - action='test', - sourcekit_searchpath=sourcekit_searchpath, - # note: test uses a different build_dir so it doesn't interfere with the 'build' step's products before install - build_dir=os.path.join(args.build_dir, 'test-build'), - config='debug', - verbose=args.verbose) - - if "install" in args.build_actions or "all" in args.build_actions: + try: + invoke_swift(package_dir=args.package_dir, + swift_exec=args.swift_exec, + action='test', + sourcekit_searchpath=sourcekit_searchpath, + # note: test uses a different build_dir so it doesn't interfere with the 'build' step's products before install + build_dir=os.path.join(args.build_dir, 'test-build'), + config='debug', + verbose=args.verbose) + except subprocess.CalledProcessError as e: + printerr('FAIL: Testing %s failed' % package_name) + printerr('Executing: %s' % ' '.join(e.cmd)) + sys.exit(1) + + if should_run_action("install", args.build_actions): print("** Installing %s **" % package_name) stdlib_dir = os.path.join(args.toolchain, 'usr', 'lib', 'swift', 'macosx') - install_package(args.package_dir, - install_dir=args.prefix, - sourcekit_searchpath=sourcekit_searchpath, - build_dir=output_dir, - rpaths_to_delete=[stdlib_dir], - verbose=args.verbose) + try: + install_package(args.package_dir, + install_dir=args.prefix, + sourcekit_searchpath=sourcekit_searchpath, + build_dir=output_dir, + rpaths_to_delete=[stdlib_dir], + verbose=args.verbose) + except subprocess.CalledProcessError as e: + printerr('FAIL: Installing %s failed' % package_name) + printerr('Executing: %s' % ' '.join(e.cmd)) + sys.exit(1) + + +# Returns true if any of the actions in `action_names` should be run. +def should_run_any_action(action_names, selected_actions): + for action_name in action_names: + if should_run_action(action_name, selected_actions): + return True + return False + + +def should_run_action(action_name, selected_actions): + if action_name in selected_actions: + return True + elif "all" in selected_actions: + return True + else: + return False + + +def update_swiftpm_dependencies(package_dir, swift_exec, build_dir, verbose): + args = [swift_exec, 'package', '--package-path', package_dir, '--build-path', build_dir, 'update'] + check_call(args, verbose=verbose) def invoke_swift(package_dir, action, swift_exec, sourcekit_searchpath, build_dir, config, verbose): @@ -119,7 +179,7 @@ def install_package(package_dir, install_dir, sourcekit_searchpath, build_dir, r rpaths_to_delete += [sourcekit_searchpath] rpaths_to_add = ['@executable_path/../lib/swift/macosx', '@executable_path/../lib'] - + # Install sk-stress-test and sk-swiftc-wrapper for product in get_products(package_dir): src = os.path.join(build_dir, product) @@ -141,6 +201,7 @@ def install(src, dest, rpaths_to_delete, rpaths_to_add, verbose): add_rpath(dest, rpath, verbose=verbose) def generate_xcodeproj(package_dir, swift_exec, sourcekit_searchpath, verbose): + package_name = os.path.basename(package_dir) config_path = os.path.join(package_dir, 'Config.xcconfig') with open(config_path, 'w') as config_file: config_file.write(''' @@ -148,7 +209,9 @@ def generate_xcodeproj(package_dir, swift_exec, sourcekit_searchpath, verbose): LD_RUNPATH_SEARCH_PATHS = {sourcekit_searchpath} $(inherited) '''.format(sourcekit_searchpath=sourcekit_searchpath)) - args = [swift_exec, 'package', '--package-path', package_dir, 'generate-xcodeproj', '--xcconfig-overrides', config_path, '--output', os.path.join(package_dir, 'SourceKitStressTester.xcodeproj')] + xcodeproj_path = os.path.join(package_dir, '%s.xcodeproj' % package_name) + + args = [swift_exec, 'package', '--package-path', package_dir, 'generate-xcodeproj', '--xcconfig-overrides', config_path, '--output', xcodeproj_path] check_call(args, verbose=verbose) def add_rpath(binary, rpath, verbose):