Skip to content

Commit 54e98e4

Browse files
committed
[build-script] Unify configuration params into one toolchain param
This shifts the paradigm of the build script from specifying every executable manually to building SwiftSyntax using an existing toolchain. This goes in sync with building SwiftSyntax using swift_build_support in the main Swift repository.
1 parent 903ac50 commit 54e98e4

File tree

1 file changed

+42
-116
lines changed

1 file changed

+42
-116
lines changed

build-script.py

Lines changed: 42 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def escapeCmdArg(arg):
4949
return arg
5050

5151

52-
def call(cmd, env=os.environ, stdout=None, stderr=subprocess.STDOUT,
52+
def call(cmd, env=os.environ, stdout=None, stderr=subprocess.STDOUT,
5353
verbose=False):
5454
if verbose:
5555
print(' '.join([escapeCmdArg(arg) for arg in cmd]))
@@ -78,9 +78,9 @@ def realpath(path):
7878
def check_gyb_exec():
7979
if not os.path.exists(GYB_EXEC):
8080
fatal_error('''
81-
Error: Could not find gyb.
81+
Error: Could not find gyb.
8282
83-
Make sure you have the main swift repo checked out next to the swift-syntax
83+
Make sure you have the main swift repo checked out next to the swift-syntax
8484
repository.
8585
Refer to README.md for more information.
8686
''')
@@ -110,10 +110,10 @@ def generate_gyb_files(verbose, add_source_locations, tar_path):
110110
# Clear any *.swift files that are relics from the previous run.
111111
for previous_gyb_gen_file in os.listdir(generated_files_dir):
112112
if previous_gyb_gen_file.endswith('.swift'):
113-
gyb_file = os.path.join(swiftsyntax_sources_dir,
113+
gyb_file = os.path.join(swiftsyntax_sources_dir,
114114
previous_gyb_gen_file + '.gyb')
115115
if not os.path.exists(gyb_file):
116-
check_call(['rm', previous_gyb_gen_file], cwd=generated_files_dir,
116+
check_call(['rm', previous_gyb_gen_file], cwd=generated_files_dir,
117117
verbose=verbose)
118118

119119
# Generate the new .swift files in a temporary directory and only copy them
@@ -140,7 +140,7 @@ def generate_gyb_files(verbose, add_source_locations, tar_path):
140140
line_directive_flags,
141141
verbose=verbose)
142142

143-
# Copy the file if different from the file already present in
143+
# Copy the file if different from the file already present in
144144
# gyb_generated
145145
check_call(['rsync'] +
146146
['--checksum'] +
@@ -166,15 +166,10 @@ def get_installed_name():
166166
def get_installed_dylib_name():
167167
return 'lib' + get_installed_name() + '.dylib'
168168

169-
def get_swiftpm_invocation(spm_exec, build_dir, parser_header_dir,
170-
parser_lib_dir, release):
171-
if spm_exec == 'swift build':
172-
swiftpm_call = ['swift', 'build']
173-
elif spm_exec == 'swift test':
174-
swiftpm_call = ['swift', 'test']
175-
else:
176-
swiftpm_call = [spm_exec]
169+
def get_swiftpm_invocation(toolchain, action, build_dir, release):
170+
swift_exec = os.path.join(toolchain, 'usr', 'bin', 'swift')
177171

172+
swiftpm_call = [swift_exec, action]
178173
swiftpm_call.extend(['--package-path', PACKAGE_DIR])
179174
if release:
180175
swiftpm_call.extend(['--configuration', 'release'])
@@ -184,34 +179,23 @@ def get_swiftpm_invocation(spm_exec, build_dir, parser_header_dir,
184179
# Swift compiler needs to know the module link name.
185180
swiftpm_call.extend(['-Xswiftc', '-module-link-name', '-Xswiftc', get_installed_name()])
186181

187-
# To find the syntax parser library.
188-
if parser_header_dir:
189-
swiftpm_call.extend(['-Xswiftc', '-I', '-Xswiftc', parser_header_dir])
190-
if parser_lib_dir:
191-
swiftpm_call.extend(['-Xswiftc', '-L', '-Xswiftc', parser_lib_dir])
192-
if platform.system() == 'Darwin':
193-
swiftpm_call.extend(['-Xlinker', '-rpath', '-Xlinker', parser_lib_dir])
194-
195182
# To speed up compilation.
196183
swiftpm_call.extend(['-Xswiftc', '-enforce-exclusivity=unchecked'])
197184
return swiftpm_call
198185

199186
class Builder(object):
200-
def __init__(self, swift_build_exec, swiftc_exec, build_dir,
201-
parser_header_dir, parser_lib_dir,
202-
release, verbose, disable_sandbox=False):
203-
self.swiftpm_call = get_swiftpm_invocation(spm_exec=swift_build_exec,
187+
def __init__(self, toolchain, build_dir, release, verbose,
188+
disable_sandbox=False):
189+
self.swiftpm_call = get_swiftpm_invocation(toolchain=toolchain,
190+
action='build',
204191
build_dir=build_dir,
205-
parser_header_dir=parser_header_dir,
206-
parser_lib_dir=parser_lib_dir,
207192
release=release)
208193
if disable_sandbox:
209194
self.swiftpm_call.append('--disable-sandbox')
210195
if verbose:
211196
self.swiftpm_call.extend(['--verbose'])
212197
self.verbose = verbose
213198
self._environ = dict(os.environ)
214-
self._environ['SWIFT_EXEC'] = swiftc_exec
215199
self._environ['SWIFT_SYNTAX_BUILD_SCRIPT'] = ''
216200

217201
def build(self, product_name, module_group_path=''):
@@ -228,31 +212,20 @@ def build(self, product_name, module_group_path=''):
228212

229213

230214
## Testing
231-
def run_tests(swift_test_exec, build_dir, parser_header_dir, parser_lib_dir,
232-
release, swift_build_exec, filecheck_exec, swiftc_exec, verbose):
215+
def run_tests(toolchain, build_dir, release, filecheck_exec, verbose):
233216
print('** Running SwiftSyntax Tests **')
234217

235-
optional_swiftc_exec = swiftc_exec
236-
if optional_swiftc_exec == 'swift':
237-
optional_swiftc_exec = None
238-
239-
lit_success = run_lit_tests(swift_build_exec=swift_build_exec,
218+
lit_success = run_lit_tests(toolchain=toolchain,
240219
build_dir=build_dir,
241-
parser_header_dir=parser_header_dir,
242-
parser_lib_dir=parser_lib_dir,
243220
release=release,
244-
swiftc_exec=optional_swiftc_exec,
245221
filecheck_exec=filecheck_exec,
246222
verbose=verbose)
247223
if not lit_success:
248224
return False
249225

250-
xctest_success = run_xctests(swift_test_exec=swift_test_exec,
226+
xctest_success = run_xctests(toolchain=toolchain,
251227
build_dir=build_dir,
252-
parser_header_dir=parser_header_dir,
253-
parser_lib_dir=parser_lib_dir,
254228
release=release,
255-
swiftc_exec=swiftc_exec,
256229
verbose=verbose)
257230
if not xctest_success:
258231
return False
@@ -264,30 +237,28 @@ def run_tests(swift_test_exec, build_dir, parser_header_dir, parser_lib_dir,
264237
def check_lit_exec():
265238
if not os.path.exists(LIT_EXEC):
266239
fatal_error('''
267-
Error: Could not find lit.py.
240+
Error: Could not find lit.py.
268241
269-
Make sure you have the llvm repo checked out next to the swift-syntax repo.
242+
Make sure you have the llvm repo checked out next to the swift-syntax repo.
270243
Refer to README.md for more information.
271244
''')
272245

273246

274247
def check_incr_transfer_roundtrip_exec():
275248
if not os.path.exists(INCR_TRANSFER_ROUNDTRIP_EXEC):
276249
fatal_error('''
277-
Error: Could not find incr_transfer_round_trip.py.
250+
Error: Could not find incr_transfer_round_trip.py.
278251
279-
Make sure you have the main swift repo checked out next to the swift-syntax
280-
repo.
252+
Make sure you have the main swift repo checked out next to the swift-syntax
253+
repo.
281254
Refer to README.md for more information.
282255
''')
283256

284257

285-
def find_lit_test_helper_exec(swift_build_exec, parser_header_dir, parser_lib_dir,
286-
build_dir, release):
287-
swiftpm_call = get_swiftpm_invocation(spm_exec=swift_build_exec,
258+
def find_lit_test_helper_exec(toolchain, build_dir, release):
259+
swiftpm_call = get_swiftpm_invocation(toolchain=toolchain,
260+
action='build',
288261
build_dir=build_dir,
289-
parser_header_dir=parser_header_dir,
290-
parser_lib_dir=parser_lib_dir,
291262
release=release)
292263
swiftpm_call.extend(['--product', 'lit-test-helper'])
293264
swiftpm_call.extend(['--show-bin-path'])
@@ -296,25 +267,20 @@ def find_lit_test_helper_exec(swift_build_exec, parser_header_dir, parser_lib_di
296267
return bin_dir.strip() + '/lit-test-helper'
297268

298269

299-
def run_lit_tests(swift_build_exec, build_dir, parser_header_dir, parser_lib_dir,
300-
release, swiftc_exec, filecheck_exec, verbose):
270+
def run_lit_tests(toolchain, build_dir, release, filecheck_exec, verbose):
301271
print('** Running lit-based tests **')
302272

303273
check_lit_exec()
304274
check_incr_transfer_roundtrip_exec()
305275

306276
lit_test_helper_exec = \
307-
find_lit_test_helper_exec(swift_build_exec=swift_build_exec,
277+
find_lit_test_helper_exec(toolchain=toolchain,
308278
build_dir=build_dir,
309-
parser_header_dir=parser_header_dir,
310-
parser_lib_dir=parser_lib_dir,
311279
release=release)
312280

313281
lit_call = [LIT_EXEC]
314282
lit_call.extend([PACKAGE_DIR + '/lit_tests'])
315-
316-
if swiftc_exec:
317-
lit_call.extend(['--param', 'SWIFTC=' + realpath(swiftc_exec)])
283+
318284
if filecheck_exec:
319285
lit_call.extend(['--param', 'FILECHECK=' + filecheck_exec])
320286
if lit_test_helper_exec:
@@ -332,24 +298,17 @@ def run_lit_tests(swift_build_exec, build_dir, parser_header_dir, parser_lib_dir
332298

333299
## XCTest based tests
334300

335-
def run_xctests(swift_test_exec, build_dir, parser_header_dir, parser_lib_dir,
336-
release, swiftc_exec, verbose):
301+
def run_xctests(toolchain, build_dir, release, verbose):
337302
print('** Running XCTests **')
338-
swiftpm_call = get_swiftpm_invocation(spm_exec=swift_test_exec,
303+
swiftpm_call = get_swiftpm_invocation(toolchain=toolchain,
304+
action='test',
339305
build_dir=build_dir,
340-
parser_header_dir=parser_header_dir,
341-
parser_lib_dir=parser_lib_dir,
342306
release=release)
343307

344308
if verbose:
345309
swiftpm_call.extend(['--verbose'])
346310

347-
subenv = dict(os.environ)
348-
if swiftc_exec:
349-
# Add the swiftc exec to PATH so that SwiftSyntax finds it
350-
subenv['PATH'] = realpath(swiftc_exec + '/..') + ':' + subenv['PATH']
351-
subenv['SWIFT_EXEC'] = swiftc_exec
352-
return call(swiftpm_call, env=subenv, verbose=verbose) == 0
311+
return call(swiftpm_call, verbose=verbose) == 0
353312

354313
def delete_rpath(rpath, binary):
355314
if platform.system() == 'Darwin':
@@ -451,12 +410,15 @@ def main():
451410
basic_group.add_argument('--swiftmodule-base-name',
452411
help='''
453412
The name under which the Swift module should be installed. A .swiftdoc and
454-
.swiftmodule file extension will be added to this path and the
455-
corresponding files will be copied there.
413+
.swiftmodule file extension will be added to this path and the
414+
corresponding files will be copied there.
456415
Example /path/to/SwiftSyntax.swiftmodule/x86_64 copies files to
457416
/path/to/SwiftSyntax.swiftmodule/x86_64.swiftmodule and
458417
/path/to/SwiftSyntax.swiftmodule/x86_64.swiftdoc
459418
''')
419+
basic_group.add_argument('--toolchain', help='''
420+
The path to the toolchain that shall be used to build SwiftSyntax.
421+
''')
460422

461423
build_group = parser.add_argument_group('Build')
462424
build_group.add_argument('--disable-sandbox',
@@ -476,38 +438,7 @@ def main():
476438
testing_group = parser.add_argument_group('Testing')
477439
testing_group.add_argument('-t', '--test', action='store_true',
478440
help='Run tests')
479-
480-
testing_group.add_argument('--swift-build-exec', default='swift build',
481-
help='''
482-
Path to the swift-build executable that is used to build SwiftPM projects
483-
If not specified the the 'swift build' command will be used.
484-
''')
485-
testing_group.add_argument('--swift-test-exec', default='swift test',
486-
help='''
487-
Path to the swift-test executable that is used to test SwiftPM projects
488-
If not specified the the 'swift test' command will be used.
489-
''')
490-
testing_group.add_argument('--swiftc-exec', default='swiftc', help='''
491-
Path to the swift executable. If not specified the swiftc exeuctable
492-
will be inferred from PATH.
493-
''')
494-
testing_group.add_argument('--syntax-parser-header-dir', default=None,
495-
help='''
496-
Path to the header and modulemap for the syntax parser library.
497-
If not specified no extra search path will be provided, it will be assumed
498-
that the library is in swift's default search paths.
499-
''')
500-
testing_group.add_argument('--syntax-parser-lib-dir', default=None,
501-
help='''
502-
Path to the syntax parser shared library. If not specified no extra search
503-
path will be provided, it will be assumed that the library is in swift's
504-
default search paths.
505-
''')
506-
testing_group.add_argument('--swift-syntax-test-exec', default=None,
507-
help='''
508-
Path to the swift-syntax-test executable that was built from the main
509-
Swift repo. If not specified, it will be looked up from PATH.
510-
''')
441+
511442
testing_group.add_argument('--filecheck-exec', default=None, help='''
512443
Path to the FileCheck executable that was built as part of the LLVM
513444
repository. If not specified, it will be looked up from PATH.
@@ -525,7 +456,7 @@ def main():
525456
else:
526457
# will this ever happen?
527458
build_dir=args.build_dir + '/debug'
528-
stdlib_rpath = realpath(os.path.dirname(args.swiftc_exec) + '/../lib/swift/macosx/')
459+
stdlib_rpath = os.path.join(args.toolchain, 'usr', 'lib', 'swift', 'macosx')
529460
install(build_dir=build_dir, dylib_dir=args.dylib_dir,
530461
swiftmodule_base_name=args.swiftmodule_base_name,
531462
stdlib_rpath=stdlib_rpath)
@@ -549,14 +480,13 @@ def main():
549480
sys.exit(0)
550481

551482
try:
552-
builder = Builder(swift_build_exec=args.swift_build_exec,
553-
swiftc_exec=args.swiftc_exec,
483+
builder = Builder(toolchain=args.toolchain,
554484
build_dir=args.build_dir,
555-
parser_header_dir=args.syntax_parser_header_dir,
556-
parser_lib_dir=args.syntax_parser_lib_dir,
557485
release=args.release,
558486
verbose=args.verbose,
559487
disable_sandbox=args.disable_sandbox)
488+
# TODO: Building with group info does not allow us to reuse the build
489+
# for running the tests.
560490
builder.build('SwiftSyntax', module_group_path=GROUP_INFO_PATH)
561491

562492
# Only build lit-test-helper if we are planning to run tests
@@ -570,14 +500,10 @@ def main():
570500

571501
if args.test:
572502
try:
573-
success = run_tests(swift_test_exec=args.swift_test_exec,
503+
success = run_tests(toolchain=args.toolchain,
574504
build_dir=realpath(args.build_dir),
575-
parser_header_dir=args.syntax_parser_header_dir,
576-
parser_lib_dir=args.syntax_parser_lib_dir,
577505
release=args.release,
578-
swift_build_exec=args.swift_build_exec,
579506
filecheck_exec=realpath(args.filecheck_exec),
580-
swiftc_exec=args.swiftc_exec,
581507
verbose=args.verbose)
582508
if not success:
583509
# An error message has already been printed by the failing test

0 commit comments

Comments
 (0)