|
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)
|
@@ -286,6 +290,48 @@ def run_xctests(swift_test_exec, build_dir, release, swiftc_exec, verbose):
|
286 | 290 | return call(swiftpm_call, env=subenv, verbose=verbose) == 0
|
287 | 291 |
|
288 | 292 |
|
| 293 | +def mkdir_p(path): |
| 294 | + """ |
| 295 | + mkdir_p(path) |
| 296 | + Create the given directory, if it does not exist. |
| 297 | + """ |
| 298 | + |
| 299 | + try: |
| 300 | + os.makedirs(path) |
| 301 | + except OSError as e: |
| 302 | + # Ignore EEXIST, which may occur during a race condition. |
| 303 | + if e.errno != errno.EEXIST: |
| 304 | + raise |
| 305 | + |
| 306 | +def change_id_rpath(rpath, binary): |
| 307 | + if platform.system() == 'Darwin': |
| 308 | + cmd = ["install_name_tool", "-id", rpath, binary] |
| 309 | + note("changing id in %s: %s" % (binary, ' '.join(cmd))) |
| 310 | + result = subprocess.call(cmd) |
| 311 | + if result != 0: |
| 312 | + fatal_error("command failed with exit status %d" % (result,)) |
| 313 | + else: |
| 314 | + fatal_error("unable to invoke install_name_tool on this platform") |
| 315 | + |
| 316 | +def check_and_sync(file_path, install_path): |
| 317 | + cmd = ["rsync", "-a", file_path, install_path] |
| 318 | + note("installing %s: %s" % (os.path.basename(file_path), ' '.join(cmd))) |
| 319 | + result = subprocess.check_call(cmd) |
| 320 | + if result != 0: |
| 321 | + fatal_error("install failed with exit status %d" % (result,)) |
| 322 | + |
| 323 | +def install(build_dir, prefix): |
| 324 | + dylibPath = build_dir + '/libSwiftSyntax.dylib' |
| 325 | + modulePath = build_dir + '/SwiftSyntax.swiftmodule' |
| 326 | + docPath = build_dir + '/SwiftSyntax.swiftdoc' |
| 327 | + install_dir = prefix + '/lib/swift/swiftsyntax' |
| 328 | + mkdir_p(install_dir) |
| 329 | + change_id_rpath('@rpath/../swiftsyntax/libSwiftSyntax.dylib', dylibPath) |
| 330 | + check_and_sync(file_path=dylibPath,install_path=install_dir) |
| 331 | + check_and_sync(file_path=modulePath,install_path=install_dir) |
| 332 | + check_and_sync(file_path=docPath,install_path=install_dir) |
| 333 | + return |
| 334 | + |
289 | 335 | ### Main
|
290 | 336 |
|
291 | 337 | def main():
|
@@ -324,7 +370,14 @@ def main():
|
324 | 370 | help='''
|
325 | 371 | Insert ###sourceLocation comments in generated code for line-directive.
|
326 | 372 | ''')
|
327 |
| - |
| 373 | + basic_group.add_argument('--install', action='store_true', |
| 374 | + help=''' |
| 375 | + Install the build artifact to a specified toolchain directory. |
| 376 | + ''') |
| 377 | + basic_group.add_argument('--prefix', |
| 378 | + help=''' |
| 379 | + The directory to where the build artifact should be installed. |
| 380 | + ''') |
328 | 381 | testing_group = parser.add_argument_group('Testing')
|
329 | 382 | testing_group.add_argument('-t', '--test', action='store_true',
|
330 | 383 | help='Run tests')
|
@@ -355,6 +408,13 @@ def main():
|
355 | 408 |
|
356 | 409 | args = parser.parse_args(sys.argv[1:])
|
357 | 410 |
|
| 411 | + if args.install: |
| 412 | + if not args.prefix: |
| 413 | + fatal_error('Must specify directory to install') |
| 414 | + if not args.build_dir: |
| 415 | + fatal_error('Must specify build directory to copy from') |
| 416 | + install(build_dir=args.build_dir, prefix=args.prefix) |
| 417 | + sys.exit(0) |
358 | 418 |
|
359 | 419 | try:
|
360 | 420 | generate_gyb_files(verbose=args.verbose,
|
|
0 commit comments