@@ -54,6 +54,17 @@ def error(message):
54
54
sys .stdout .flush ()
55
55
raise SystemExit (1 )
56
56
57
+ def symlink_force (target , link_name ):
58
+ if os .path .isdir (link_name ):
59
+ link_name = os .path .join (link_name , os .path .basename (target ))
60
+ try :
61
+ os .symlink (target , link_name )
62
+ except OSError , e :
63
+ if e .errno == errno .EEXIST :
64
+ os .remove (link_name )
65
+ os .symlink (target , link_name )
66
+ else :
67
+ raise e
57
68
58
69
def mkdir_p (path ):
59
70
"""
@@ -449,15 +460,11 @@ def get_swift_build_tool_path():
449
460
if os .path .exists (sbt_path ):
450
461
return sbt_path
451
462
452
- if os .environ .get ("SWIFT_BUILD_TOOL" ):
453
- return os .environ .get ("SWIFT_BUILD_TOOL" )
454
-
455
- # Next, search for it in PATH.
456
- try :
457
- return subprocess .check_output (["which" , "swift-build-tool" ],
458
- universal_newlines = True ).strip ()
459
- except :
460
- pass
463
+ SWIFT_EXEC = os .getenv ("SWIFT_EXEC" )
464
+ if SWIFT_EXEC :
465
+ maybe_path = os .path .join (SWIFT_EXEC , "../swift-build-tool" )
466
+ if exists (maybe_path ):
467
+ return maybe_path
461
468
462
469
# If that failed, on Darwin use xcrun to search for the tool.
463
470
if platform .system () == 'Darwin' :
@@ -469,11 +476,28 @@ def get_swift_build_tool_path():
469
476
return sbt_path
470
477
except subprocess .CalledProcessError :
471
478
pass
479
+ else :
480
+ # Otherwise, search for it in PATH.
481
+ try :
482
+ return subprocess .check_output (["which" , "swift-build-tool" ],
483
+ universal_newlines = True ).strip ()
484
+ except :
485
+ pass
472
486
473
487
# If all else failed, report an error.
474
488
error ("unable to find 'swift-build-tool' tool for bootstrap build" )
475
489
476
490
491
+ def get_swiftc_path ():
492
+ path = os .getenv ("SWIFT_EXEC" )
493
+ if path :
494
+ return os .realpath (path )
495
+ else :
496
+ if platform .system () == 'Darwin' :
497
+ return subprocess .check_output (["xcrun" , "--find" , "swiftc" ], stderr = subprocess .PIPE , universal_newlines = True ).strip ()
498
+ else :
499
+ return subprocess .check_output (["which" , args .swiftc_path ], universal_newlines = True ).strip ()
500
+
477
501
def main ():
478
502
parser = argparse .ArgumentParser (
479
503
usage = "%(prog)s [options] [clean|all|test|install]" ,
@@ -487,7 +511,7 @@ def main():
487
511
nargs = "*" , default = ["all" ])
488
512
parser .add_argument ("--swiftc" , dest = "swiftc_path" ,
489
513
help = "path to the swift compiler [%(default)s]" ,
490
- default = os . getenv ( "SWIFT_EXEC" ) or "swiftc" ,
514
+ default = get_swiftc_path () ,
491
515
metavar = "PATH" )
492
516
parser .add_argument ("--sbt" , dest = "sbt_path" ,
493
517
help = "path to the 'swift-build-tool' tool "
@@ -511,7 +535,7 @@ def main():
511
535
help = "Path to XCTest build directory" )
512
536
args = parser .parse_args ()
513
537
build_actions = set (args .build_actions )
514
-
538
+
515
539
# Validate the build actions.
516
540
for action in build_actions :
517
541
if action not in ("clean" , "all" , "test" , "install" ):
@@ -545,12 +569,6 @@ def main():
545
569
args .sbt_path = os .path .abspath (
546
570
args .sbt_path or get_swift_build_tool_path ())
547
571
548
- # Due to bug in Xcode where SWIFT_EXEC is not set correctly by downloadable
549
- # toolchain
550
- if os .getenv ("XCODE_DEFAULT_TOOLCHAIN_OVERRIDE" ):
551
- args .swiftc = os .path .join (
552
- os .getenv ("XCODE_DEFAULT_TOOLCHAIN_OVERRIDE" ), "usr/bin/swiftc" )
553
-
554
572
# Create or update the bootstrap files.
555
573
create_bootstrap_files (sandbox_path , args )
556
574
@@ -569,25 +587,19 @@ def main():
569
587
runtime_module_path , runtime_lib_path = process_runtime_libraries (
570
588
sandbox_path , args , bootstrap = True )
571
589
572
- # Symlink the expected lib location so that we don't yet
573
- # have to support installation logic in SwiftPM proper
574
- symlink_path = os .path .join (build_path , "lib" , "swift" , "pm" )
575
- if not os .path .islink (symlink_path ):
576
- path = os .path .join (build_path , "lib" , "swift" )
577
- shutil .rmtree (path , True )
578
- mkdir_p (path )
579
- os .symlink (os .path .join (build_path , "debug" ), symlink_path )
580
- symlink_path = os .path .join (build_path , "bin" )
581
- if not os .path .islink (symlink_path ):
582
- path = os .path .join (build_path , "debug" )
583
- shutil .rmtree (path , True )
584
- os .symlink (path , symlink_path )
590
+ # Construct a fake toolchain so swift-build can build itself
591
+ # without requiring it to have hacky-edge-case logic
592
+ def make_fake_toolchain ():
593
+ bindir = os .path .join (sandbox_path , "bin" )
594
+ symlink_force (args .swiftc_path , bindir )
595
+ symlink_force (args .sbt_path , bindir )
596
+
597
+ make_fake_toolchain ()
585
598
586
599
# Build the package manager with itself.
587
- env_cmd = ["env" ,
588
- "SWIFT_EXEC=" + args .swiftc_path ,
589
- "SWIFT_BUILD_TOOL=" + args .sbt_path ,
590
- "SWIFT_BUILD_PATH=" + build_path ]
600
+
601
+ env_cmd = ["env" , "SWIFT_EXEC=" + os .path .join (sandbox_path , "bin" , "swiftc" ),
602
+ "SWIFT_BUILD_PATH=" + build_path ]
591
603
if args .sysroot :
592
604
env_cmd .append ("SYSROOT=" + args .sysroot )
593
605
@@ -628,12 +640,8 @@ def main():
628
640
# If testing, run each of the test bundles.
629
641
if "test" in build_actions :
630
642
# Construct the test environment.
631
- env_cmd = ["env" ,
632
- "SWIFT_EXEC=" + args .swiftc_path ,
633
- "SWIFT_BUILD_TOOL=" + args .sbt_path ,
634
- "SWIFT_BUILD_PATH=" + build_path ,
635
- "SPM_INSTALL_PATH=" + build_path ]
636
-
643
+ env_cmd = ["env" , "SWIFT_EXEC=" + args .swiftc_path ,
644
+ "SWIFT_BUILD_PATH=" + build_path ]
637
645
cmd = env_cmd + [os .path .join (build_path , "debug" , "swift-test" )]
638
646
result = subprocess .call (cmd , cwd = g_project_root )
639
647
if result != 0 :
0 commit comments