|
7 | 7 | import subprocess
|
8 | 8 | import sys
|
9 | 9 | import tempfile
|
10 |
| - |
| 10 | +import errno |
| 11 | +import platform |
11 | 12 |
|
12 | 13 | PACKAGE_DIR = os.path.dirname(os.path.realpath(__file__))
|
13 | 14 | WORKSPACE_DIR = os.path.realpath(PACKAGE_DIR + '/..')
|
|
22 | 23 | def printerr(message):
|
23 | 24 | print(message, file=sys.stderr)
|
24 | 25 |
|
| 26 | +def note(message): |
| 27 | + print("--- %s: note: %s" % (os.path.basename(sys.argv[0]), message)) |
| 28 | + sys.stdout.flush() |
25 | 29 |
|
26 | 30 | def fatal_error(message):
|
27 | 31 | printerr(message)
|
@@ -143,6 +147,8 @@ def get_swiftpm_invocation(spm_exec, build_dir, release):
|
143 | 147 | if build_dir:
|
144 | 148 | swiftpm_call.extend(['--build-path', build_dir])
|
145 | 149 |
|
| 150 | + # Swift compiler needs to know the module link name. |
| 151 | + swiftpm_call.extend(['-Xswiftc', '-module-link-name', '-Xswiftc', 'SwiftSyntax']) |
146 | 152 | return swiftpm_call
|
147 | 153 |
|
148 | 154 |
|
@@ -285,6 +291,47 @@ def run_xctests(swift_test_exec, build_dir, release, swiftc_exec, verbose):
|
285 | 291 |
|
286 | 292 | return call(swiftpm_call, env=subenv, verbose=verbose) == 0
|
287 | 293 |
|
| 294 | +def delete_rpath(rpath, binary): |
| 295 | + if platform.system() == 'Darwin': |
| 296 | + cmd = ["install_name_tool", "-delete_rpath", rpath, binary] |
| 297 | + note("removing RPATH from %s: %s" % (binary, ' '.join(cmd))) |
| 298 | + result = subprocess.call(cmd) |
| 299 | + if result != 0: |
| 300 | + fatal_error("command failed with exit status %d" % (result,)) |
| 301 | + else: |
| 302 | + fatal_error("unable to remove RPATHs on this platform") |
| 303 | + |
| 304 | +def change_id_rpath(rpath, binary): |
| 305 | + if platform.system() == 'Darwin': |
| 306 | + cmd = ["install_name_tool", "-id", rpath, binary] |
| 307 | + note("changing id in %s: %s" % (binary, ' '.join(cmd))) |
| 308 | + result = subprocess.call(cmd) |
| 309 | + if result != 0: |
| 310 | + fatal_error("command failed with exit status %d" % (result,)) |
| 311 | + else: |
| 312 | + fatal_error("unable to invoke install_name_tool on this platform") |
| 313 | + |
| 314 | +def check_and_sync(file_path, install_path): |
| 315 | + cmd = ["rsync", "-a", file_path, install_path] |
| 316 | + note("installing %s: %s" % (os.path.basename(file_path), ' '.join(cmd))) |
| 317 | + result = subprocess.check_call(cmd) |
| 318 | + if result != 0: |
| 319 | + fatal_error("install failed with exit status %d" % (result,)) |
| 320 | + |
| 321 | +def install(build_dir, dylib_dir, swiftmodule_dir, stdlib_rpath): |
| 322 | + dylibPath = build_dir + '/libSwiftSyntax.dylib' |
| 323 | + modulePath = build_dir + '/SwiftSyntax.swiftmodule' |
| 324 | + docPath = build_dir + '/SwiftSyntax.swiftdoc' |
| 325 | + # users should find the dylib as if it's a part of stdlib. |
| 326 | + change_id_rpath('@rpath/libSwiftSyntax.dylib', dylibPath) |
| 327 | + # we don't wanna hard-code the stdlib dylibs into rpath. |
| 328 | + delete_rpath(stdlib_rpath, dylibPath) |
| 329 | + check_and_sync(file_path=dylibPath,install_path=dylib_dir) |
| 330 | + # Optionally install .swiftmodule |
| 331 | + if swiftmodule_dir: |
| 332 | + check_and_sync(file_path=modulePath,install_path=swiftmodule_dir) |
| 333 | + check_and_sync(file_path=docPath,install_path=swiftmodule_dir) |
| 334 | + return |
288 | 335 |
|
289 | 336 | ### Main
|
290 | 337 |
|
@@ -324,7 +371,18 @@ def main():
|
324 | 371 | help='''
|
325 | 372 | Insert ###sourceLocation comments in generated code for line-directive.
|
326 | 373 | ''')
|
327 |
| - |
| 374 | + basic_group.add_argument('--install', action='store_true', |
| 375 | + help=''' |
| 376 | + Install the build artifact to a specified toolchain directory. |
| 377 | + ''') |
| 378 | + basic_group.add_argument('--dylib-dir', |
| 379 | + help=''' |
| 380 | + The directory to where the .dylib should be installed. |
| 381 | + ''') |
| 382 | + basic_group.add_argument('--swiftmodule-dir', |
| 383 | + help=''' |
| 384 | + The directory to where the .swiftmodule should be installed. |
| 385 | + ''') |
328 | 386 | testing_group = parser.add_argument_group('Testing')
|
329 | 387 | testing_group.add_argument('-t', '--test', action='store_true',
|
330 | 388 | help='Run tests')
|
@@ -355,6 +413,21 @@ def main():
|
355 | 413 |
|
356 | 414 | args = parser.parse_args(sys.argv[1:])
|
357 | 415 |
|
| 416 | + if args.install: |
| 417 | + if not args.dylib_dir: |
| 418 | + fatal_error('Must specify directory to install') |
| 419 | + if not args.build_dir: |
| 420 | + fatal_error('Must specify build directory to copy from') |
| 421 | + if args.release: |
| 422 | + build_dir=args.build_dir + '/release' |
| 423 | + else: |
| 424 | + # will this ever happen? |
| 425 | + build_dir=args.build_dir + '/debug' |
| 426 | + stdlib_rpath = realpath(os.path.dirname(args.swiftc_exec) + '/../lib/swift/macosx/') |
| 427 | + install(build_dir=build_dir, dylib_dir=args.dylib_dir, |
| 428 | + swiftmodule_dir=args.swiftmodule_dir, |
| 429 | + stdlib_rpath=stdlib_rpath) |
| 430 | + sys.exit(0) |
358 | 431 |
|
359 | 432 | try:
|
360 | 433 | generate_gyb_files(verbose=args.verbose,
|
|
0 commit comments