Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SwiftEvolve/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
/.build
/Packages
/*.xcodeproj
/*.xcconfig
/DerivedData
/Package.resolved
/.swiftpm
133 changes: 98 additions & 35 deletions build-script-helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand All @@ -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)

Expand All @@ -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:
Copy link

@nathawes nathawes Oct 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not important, but you could return "all" in selected_actions at this point, or replace the whole body with something like return any(item in (action_name, "all") for item in selected_actions).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually find it clearer this way. The second suggestion means, I actually need to think about what’s going on and I like repeating the same pattern that I used for action_name already for "all". It’s a bit more verbose but I find it reads clearer.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries!

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):
Expand All @@ -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)
Expand All @@ -141,14 +201,17 @@ 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('''
SYSTEM_FRAMEWORK_SEARCH_PATHS = {sourcekit_searchpath} $(inherited)
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):
Expand Down