Skip to content

Commit da31c21

Browse files
authored
Merge pull request #438 from ahoppen/ahoppen/install
Add support in build-script-helper.py to install swift-format into an open source toolchain
2 parents bd31ba9 + fb434b8 commit da31c21

File tree

1 file changed

+63
-18
lines changed

1 file changed

+63
-18
lines changed

build-script-helper.py

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22

33
"""
44
This source file is part of the Swift.org open source project
@@ -31,14 +31,14 @@ def parse_args(args):
3131

3232
parser.add_argument('--package-path', default='')
3333
parser.add_argument('-v', '--verbose', action='store_true', help='log executed commands')
34-
parser.add_argument('--prefix', help='install path')
34+
parser.add_argument('--prefix', dest='install_prefixes', nargs='*', metavar='PATHS', help='install path')
3535
parser.add_argument('--configuration', default='debug')
3636
parser.add_argument('--build-path', default=None)
3737
parser.add_argument('--multiroot-data-file', help='Path to an Xcode workspace to create a unified build of SwiftSyntax with other projects.')
3838
parser.add_argument('--toolchain', required=True, help='the toolchain to use when building this package')
3939
parser.add_argument('--update', action='store_true', help='update all SwiftPM dependencies')
4040
parser.add_argument('--no-local-deps', action='store_true', help='use normal remote dependencies when building')
41-
parser.add_argument('build_actions', help="Extra actions to perform. Can be any number of the following", choices=['all', 'build', 'test', 'generate-xcodeproj'], nargs="*", default=['build'])
41+
parser.add_argument('build_actions', help="Extra actions to perform. Can be any number of the following", choices=['all', 'build', 'test', 'generate-xcodeproj', 'install'], nargs="*", default=['build'])
4242

4343
parsed = parser.parse_args(args)
4444

@@ -57,11 +57,9 @@ def parse_args(args):
5757
def run(args):
5858
package_name = os.path.basename(args.package_path)
5959

60-
env = dict(os.environ)
60+
env = get_swiftpm_environment_variables(no_local_deps=args.no_local_deps)
6161
# Use local dependencies (i.e. checked out next swift-format).
62-
if not args.no_local_deps:
63-
env['SWIFTCI_USE_LOCAL_DEPS'] = "1"
64-
62+
6563
if args.update:
6664
print("** Updating dependencies of %s **" % package_name)
6765
try:
@@ -76,7 +74,7 @@ def run(args):
7674
sys.exit(1)
7775

7876
# The test action creates its own build. No need to build if we are just testing.
79-
if should_run_action('build', args.build_actions):
77+
if should_run_action('build', args.build_actions) or should_run_action('install', args.build_actions):
8078
print("** Building %s **" % package_name)
8179
try:
8280
invoke_swift(package_path=args.package_path,
@@ -124,6 +122,23 @@ def run(args):
124122
printerr('Executing: %s' % ' '.join(e.cmd))
125123
sys.exit(1)
126124

125+
if should_run_action("install", args.build_actions):
126+
print("** Installing %s **" % package_name)
127+
128+
swiftpm_args = get_swiftpm_options(
129+
package_path=args.package_path,
130+
build_path=args.build_path,
131+
multiroot_data_file=args.multiroot_data_file,
132+
configuration=args.configuration,
133+
verbose=args.verbose
134+
)
135+
cmd = [args.swift_exec, 'build', '--show-bin-path'] + swiftpm_args
136+
bin_path = check_output(cmd, env=env, caputre_stderr=False, verbose=args.verbose).strip()
137+
138+
for prefix in args.install_prefixes:
139+
cmd = ['rsync', '-a', os.path.join(bin_path, 'swift-format'), os.path.join(prefix, 'bin')]
140+
check_call(cmd, verbose=args.verbose)
141+
127142
def should_run_action(action_name, selected_actions):
128143
if action_name in selected_actions:
129144
return True
@@ -142,20 +157,41 @@ def invoke_swift(package_path, swift_exec, action, products, build_path, multiro
142157
for product in products:
143158
invoke_swift_single_product(package_path, swift_exec, action, product, build_path, multiroot_data_file, configuration, env, verbose)
144159

145-
def invoke_swift_single_product(package_path, swift_exec, action, product, build_path, multiroot_data_file, configuration, env, verbose):
146-
args = [swift_exec, action, '--package-path', package_path, '-c', configuration, '--build-path', build_path]
147-
if platform.system() != "Darwin":
148-
args.extend(["--enable-test-discovery"])
160+
def get_swiftpm_options(package_path, build_path, multiroot_data_file, configuration, verbose):
161+
args = [
162+
'--package-path', package_path,
163+
'--configuration', configuration,
164+
'--scratch-path', build_path
165+
]
149166
if multiroot_data_file:
150-
args.extend(['--multiroot-data-file', multiroot_data_file])
151-
if action == 'test':
152-
args.extend(['--test-product', product])
153-
else:
154-
args.extend(['--product', product])
155-
167+
args += ['--multiroot-data-file', multiroot_data_file]
168+
if verbose:
169+
args += ['--verbose']
170+
if platform.system() == 'Darwin':
171+
args += [
172+
'-Xlinker', '-rpath', '-Xlinker', '/usr/lib/swift',
173+
'-Xlinker', '-rpath', '-Xlinker', '@executable_path/../lib/swift/macosx',
174+
'-Xlinker', '-rpath', '-Xlinker', '@executable_path/../lib/swift-5.5/macosx',
175+
]
176+
return args
177+
178+
def get_swiftpm_environment_variables(no_local_deps):
156179
# Tell SwiftSyntax that we are building in a build-script environment so that
157180
# it does not need to be rebuilt if it has already been built before.
181+
env = dict(os.environ)
158182
env['SWIFT_BUILD_SCRIPT_ENVIRONMENT'] = '1'
183+
if not no_local_deps:
184+
env['SWIFTCI_USE_LOCAL_DEPS'] = "1"
185+
return env
186+
187+
188+
def invoke_swift_single_product(package_path, swift_exec, action, product, build_path, multiroot_data_file, configuration, env, verbose):
189+
args = [swift_exec, action]
190+
args += get_swiftpm_options(package_path, build_path, multiroot_data_file, configuration, verbose)
191+
if action == 'test':
192+
args += ['--test-product', product]
193+
else:
194+
args += ['--product', product]
159195

160196
check_call(args, env=env, verbose=verbose)
161197

@@ -170,6 +206,15 @@ def check_call(cmd, verbose, env=os.environ, **kwargs):
170206
print(' '.join([escape_cmd_arg(arg) for arg in cmd]))
171207
return subprocess.check_call(cmd, env=env, stderr=subprocess.STDOUT, **kwargs)
172208

209+
def check_output(cmd, verbose, env=os.environ, caputre_stderr=True, **kwargs):
210+
if verbose:
211+
print(' '.join([escape_cmd_arg(arg) for arg in cmd]))
212+
if caputre_stderr:
213+
stderr = subprocess.STDOUT
214+
else:
215+
stderr = subprocess.DEVNULL
216+
return subprocess.check_output(cmd, env=env, stderr=stderr, encoding='utf-8', **kwargs)
217+
173218
def escape_cmd_arg(arg):
174219
if '"' in arg or ' ' in arg:
175220
return '"%s"' % arg.replace('"', '\\"')

0 commit comments

Comments
 (0)