22
22
23
23
import six
24
24
25
+ from swift_build_support .swift_build_support import build_graph
25
26
from swift_build_support .swift_build_support import products
26
27
from swift_build_support .swift_build_support import shell
27
28
from swift_build_support .swift_build_support import targets
28
29
from swift_build_support .swift_build_support import workspace
29
30
from swift_build_support .swift_build_support .cmake import CMake
30
31
from swift_build_support .swift_build_support .host_specific_configuration \
31
32
import HostSpecificConfiguration
32
- from swift_build_support .swift_build_support .productpipeline_list_builder \
33
- import ProductPipelineListBuilder
34
33
from swift_build_support .swift_build_support .targets \
35
34
import StdlibDeploymentTarget
36
35
from swift_build_support .swift_build_support .utils \
@@ -134,12 +133,12 @@ def convert_to_impl_arguments(self):
134
133
135
134
# Compute any product specific cmake arguments.
136
135
#
137
- # NOTE: The sum(list(...)) is b/c compute_product_pipelines returns a
136
+ # NOTE: The sum(list(...)) is b/c compute_product_classes returns a
138
137
# tuple of lists of which the first is the build-script-impl products
139
138
# and the second is the non-build-script-impl-products. It guarantees
140
139
# that when we concatenate these two lists together we get a valid
141
140
# dependency graph.
142
- for product_class in sum (list (self .compute_product_pipelines ()[ 0 ] ), []):
141
+ for product_class in sum (list (self .compute_product_classes () ), []):
143
142
if not product_class .is_build_script_impl_product ():
144
143
continue
145
144
@@ -492,20 +491,15 @@ def compute_host_specific_variables(self):
492
491
493
492
return options
494
493
495
- def compute_product_pipelines (self ):
496
- """compute_product_pipelines () -> [[Product]]
494
+ def compute_product_classes (self ):
495
+ """compute_product_classes () -> (list, list, list)
497
496
498
- A list of lists of products.
499
-
500
- Compute lists of product pipelines that we should run. It is guaranteed
501
- that all product pipeline lists consist of solely build-script-impl
502
- products or build-script products. So one can always check the first
503
- element to know if a pipeline returned from the builder is an impl
504
- product or not.
497
+ Compute the list first of all pre-build-script-impl products, then all
498
+ build-script-impl products and then all non-build-script-impl products.
499
+ It is assumed that concatenating the three lists together will result in a
500
+ valid dependency graph for the compilation.
505
501
"""
506
- builder = ProductPipelineListBuilder (self .args )
507
-
508
- builder .begin_pipeline ()
502
+ before_impl_product_classes = []
509
503
# If --skip-early-swift-driver is passed in, swift will be built
510
504
# as usual, but relying on its own C++-based (Legacy) driver.
511
505
# Otherwise, we build an "early" swift-driver using the host
@@ -514,79 +508,120 @@ def compute_product_pipelines(self):
514
508
# in the host toolchain. If the host toolchain is not equpipped with
515
509
# a Swift compiler, a warning is emitted. In the future, it may become
516
510
# mandatory that the host toolchain come with its own `swiftc`.
517
- builder . add_product ( products . EarlySwiftDriver ,
518
- is_enabled = self . args . build_early_swift_driver )
511
+ if self . args . build_early_swift_driver :
512
+ before_impl_product_classes . append ( products . EarlySwiftDriver )
519
513
520
- builder . add_product ( products . CMark ,
521
- is_enabled = self . args . build_cmark )
514
+ if self . args . build_cmark :
515
+ before_impl_product_classes . append ( products . CMark )
522
516
523
- # Begin a build-script-impl pipeline for handling the compiler toolchain
524
- # and a subset of the tools that we build. We build these in this manner
525
- # to preserve current build-script-impl run behavior as we transition
526
- # the build-script code base. The main difference is that these are all
527
- # build, tested, and installed all at once instead of performing build,
528
- # test, install like a normal build-script product.
529
- builder .begin_impl_pipeline (should_run_epilogue_operations = True )
517
+ # FIXME: This is a weird division (returning a list of class objects),
518
+ # but it matches the existing structure of the `build-script-impl`.
519
+ impl_product_classes = []
530
520
531
521
# If --skip-build-llvm is passed in, LLVM cannot be completely disabled, as
532
522
# Swift still needs a few LLVM targets like tblgen to be built for it to be
533
523
# configured. Instead, handle this in build-script-impl for now.
534
- builder .add_impl_product (products .LLVM ,
535
- is_enabled = True )
536
- builder .add_impl_product (products .LibCXX ,
537
- is_enabled = self .args .build_libcxx )
538
- builder .add_impl_product (products .LibICU ,
539
- is_enabled = self .args .build_libicu )
540
- builder .add_impl_product (products .Swift ,
541
- is_enabled = self .args .build_swift )
542
- builder .add_impl_product (products .LLDB ,
543
- is_enabled = self .args .build_lldb )
544
- builder .add_impl_product (products .LibDispatch ,
545
- is_enabled = self .args .build_libdispatch )
546
- builder .add_impl_product (products .Foundation ,
547
- is_enabled = self .args .build_foundation )
548
- builder .add_impl_product (products .XCTest ,
549
- is_enabled = self .args .build_xctest )
550
- builder .add_impl_product (products .LLBuild ,
551
- is_enabled = self .args .build_llbuild )
552
-
553
- # Begin the post build-script-impl build phase.
554
- builder .begin_pipeline ()
555
-
556
- builder .add_product (products .SwiftPM ,
557
- is_enabled = self .args .build_swiftpm )
558
- builder .add_product (products .SwiftSyntax ,
559
- is_enabled = self .args .build_swiftsyntax )
560
- builder .add_product (products .SKStressTester ,
561
- is_enabled = self .args .build_skstresstester )
562
- builder .add_product (products .SwiftFormat ,
563
- is_enabled = self .args .build_swiftformat )
564
- builder .add_product (products .SwiftEvolve ,
565
- is_enabled = self .args .build_swiftevolve )
566
- builder .add_product (products .IndexStoreDB ,
567
- is_enabled = self .args .build_indexstoredb )
568
- builder .add_product (products .PlaygroundSupport ,
569
- is_enabled = self .args .build_playgroundsupport )
570
- builder .add_product (products .SourceKitLSP ,
571
- is_enabled = self .args .build_sourcekitlsp )
572
- builder .add_product (products .Benchmarks ,
573
- is_enabled = self .args .build_toolchainbenchmarks )
574
- builder .add_product (products .SwiftInspect ,
575
- is_enabled = self .args .build_swift_inspect )
576
- builder .add_product (products .TSanLibDispatch ,
577
- is_enabled = self .args .tsan_libdispatch_test )
524
+ impl_product_classes .append (products .LLVM )
525
+ if self .args .build_libcxx :
526
+ impl_product_classes .append (products .LibCXX )
527
+ if self .args .build_libicu :
528
+ impl_product_classes .append (products .LibICU )
529
+ if self .args .build_swift :
530
+ impl_product_classes .append (products .Swift )
531
+ if self .args .build_lldb :
532
+ impl_product_classes .append (products .LLDB )
533
+ if self .args .build_libdispatch :
534
+ impl_product_classes .append (products .LibDispatch )
535
+ if self .args .build_foundation :
536
+ impl_product_classes .append (products .Foundation )
537
+ if self .args .build_xctest :
538
+ impl_product_classes .append (products .XCTest )
539
+ if self .args .build_llbuild :
540
+ impl_product_classes .append (products .LLBuild )
541
+ # Sanity check that all of our impl classes are actually
542
+ # build_script_impl products.
543
+ for prod in impl_product_classes :
544
+ assert (prod .is_build_script_impl_product ())
545
+
546
+ product_classes = []
547
+ if self .args .build_swiftpm :
548
+ product_classes .append (products .SwiftPM )
549
+ if self .args .build_swiftsyntax :
550
+ product_classes .append (products .SwiftSyntax )
551
+ if self .args .build_skstresstester :
552
+ product_classes .append (products .SKStressTester )
553
+ if self .args .build_swiftformat :
554
+ product_classes .append (products .SwiftFormat )
555
+ if self .args .build_swiftevolve :
556
+ product_classes .append (products .SwiftEvolve )
557
+ if self .args .build_indexstoredb :
558
+ product_classes .append (products .IndexStoreDB )
559
+ if self .args .build_playgroundsupport :
560
+ product_classes .append (products .PlaygroundSupport )
561
+ if self .args .build_sourcekitlsp :
562
+ product_classes .append (products .SourceKitLSP )
563
+ if self .args .build_toolchainbenchmarks :
564
+ product_classes .append (products .Benchmarks )
565
+ if self .args .build_swift_inspect :
566
+ product_classes .append (products .SwiftInspect )
567
+ if self .args .tsan_libdispatch_test :
568
+ product_classes .append (products .TSanLibDispatch )
578
569
579
570
# Keep SwiftDriver at last.
580
571
# swift-driver's integration with the build scripts is not fully
581
572
# supported. Using swift-driver to build these products may hit
582
573
# failures.
583
- builder .add_product (products .SwiftDriver ,
584
- is_enabled = self .args .build_swift_driver
585
- or self .args .install_swift_driver )
586
-
587
- # Now that we have constructed our pass pipelines using our builder, get
588
- # the final schedule and finalize the builder.
589
- return builder .finalize (shouldInfer = self .args .infer_dependencies )
574
+ if self .args .build_swift_driver or self .args .install_swift_driver :
575
+ product_classes .append (products .SwiftDriver )
576
+ # Sanity check that all of our non-impl classes are actually
577
+ # not build_script_impl products.
578
+ for prod in product_classes :
579
+ assert (not prod .is_build_script_impl_product ())
580
+
581
+ # Now that we have our two lists of product_classes, if we are asked to
582
+ # infer dependencies, infer the dependencies now and then re-split the
583
+ # list.
584
+ if self .args .infer_dependencies :
585
+ combined_classes = before_impl_product_classes + \
586
+ impl_product_classes + \
587
+ product_classes
588
+ if self .args .verbose_build :
589
+ print ("-- Build Graph Inference --" )
590
+ print ("Initial Product List:" )
591
+ for p in combined_classes :
592
+ print (" {}" .format (p .product_name ()))
593
+
594
+ # Now that we have produced the schedule, resplit. We require our
595
+ # dependencies to respect our build-script-impl property. This means
596
+ # that no build-script-impl products can have dependencies on
597
+ # non-build-script-impl products. Otherwise, it would be unsafe to
598
+ # re-order build-script-impl products in front of non
599
+ # build-script-impl products.
600
+ before_impl_product_classes = []
601
+ impl_product_classes = []
602
+ product_classes = []
603
+ is_darwin = platform .system () == 'Darwin'
604
+ final_schedule = \
605
+ build_graph .produce_scheduled_build (combined_classes )[0 ]
606
+ for p in final_schedule :
607
+ if is_darwin and p .is_nondarwin_only_build_product ():
608
+ continue
609
+ if p .is_build_script_impl_product ():
610
+ impl_product_classes .append (p )
611
+ elif p .is_before_build_script_impl_product ():
612
+ before_impl_product_classes .append (p )
613
+ else :
614
+ product_classes .append (p )
615
+
616
+ if self .args .verbose_build :
617
+ print ("Final Build Order:" )
618
+ for p in before_impl_product_classes :
619
+ print (" {}" .format (p .product_name ()))
620
+ for p in impl_product_classes :
621
+ print (" {}" .format (p .product_name ()))
622
+ for p in product_classes :
623
+ print (" {}" .format (p .product_name ()))
624
+ return (before_impl_product_classes , impl_product_classes , product_classes )
590
625
591
626
def execute (self ):
592
627
"""Execute the invocation with the configured arguments."""
@@ -609,40 +644,26 @@ def execute(self):
609
644
all_hosts = [StdlibDeploymentTarget .get_target_for_name (name )
610
645
for name in all_host_names ]
611
646
612
- # Compute the list of lists of product classes to operate on.
647
+ # Compute the list of product classes to operate on.
613
648
#
614
649
# FIXME: This should really be per-host, but the current structure
615
650
# matches that of `build-script-impl`.
616
- (product_pipelines , last_impl_index ) = self .compute_product_pipelines ()
617
-
618
- # Execute each "product pipeline".
619
- for index in range (len (product_pipelines )):
620
- pipeline = product_pipelines [index ]
621
- # Skip empty pipelines.
622
- if len (pipeline ) == 0 :
623
- continue
624
- is_impl = pipeline [0 ].is_build_script_impl_product ()
625
- if is_impl :
626
- perform_epilogue_opts = last_impl_index == index
627
- self ._execute_impl (pipeline , all_hosts , perform_epilogue_opts )
628
- else :
629
- assert (index != last_impl_index )
630
- self ._execute (pipeline , all_host_names )
631
-
632
- # And then perform the rest of the non-core epilogue actions.
633
-
634
- # Extract symbols...
635
- for host_target in all_hosts :
636
- self ._execute_extract_symbols_action (host_target )
651
+ (before_impl_product_classes , impl_product_classes , product_classes ) = \
652
+ self .compute_product_classes ()
637
653
638
- # Package...
639
- for host_target in all_hosts :
640
- self ._execute_package_action (host_target )
654
+ # Execute each "pass".
641
655
642
- # Lipo...
643
- self ._execute_merged_host_lipo_action ()
656
+ # Pre-build-script-impl products...
657
+ # Note: currently only supports building for the host.
658
+ for host_target in all_host_names :
659
+ for product_class in before_impl_product_classes :
660
+ if product_class .is_build_script_impl_product ():
661
+ continue
662
+ if not product_class .is_before_build_script_impl_product ():
663
+ continue
664
+ # Execute clean, build, test, install
665
+ self .execute_product_build_steps (product_class , host_target )
644
666
645
- def _execute_impl (self , pipeline , all_hosts , should_run_epilogue_operations ):
646
667
# Build...
647
668
for host_target in all_hosts :
648
669
# FIXME: We should only compute these once.
@@ -660,35 +681,42 @@ def _execute_impl(self, pipeline, all_hosts, should_run_epilogue_operations):
660
681
print ("Running Swift benchmarks for: {}" .format (
661
682
" " .join (config .swift_benchmark_run_targets )))
662
683
663
- for product_class in pipeline :
684
+ for product_class in impl_product_classes :
664
685
self ._execute_build_action (host_target , product_class )
665
686
666
687
# Test...
667
688
for host_target in all_hosts :
668
- for product_class in pipeline :
689
+ for product_class in impl_product_classes :
669
690
self ._execute_test_action (host_target , product_class )
670
691
671
692
# Install...
672
693
for host_target in all_hosts :
673
- for product_class in pipeline :
694
+ for product_class in impl_product_classes :
674
695
self ._execute_install_action (host_target , product_class )
675
696
676
- # And then we may be asked to perform several post-processing operations
677
- # on what we have built. If we are not supposed to do so, bail now.
678
- if not should_run_epilogue_operations :
679
- return
680
-
681
697
# Core Lipo...
682
698
self ._execute_merged_host_lipo_core_action ()
683
699
684
- def _execute (self , pipeline , all_host_names ):
685
- # Pre-build-script-impl products...
700
+ # Non-build-script-impl products...
686
701
# Note: currently only supports building for the host.
687
- for host_target in all_host_names :
688
- for product_class in pipeline :
702
+ for host_target in [self .args .host_target ]:
703
+ for product_class in product_classes :
704
+ if product_class .is_build_script_impl_product ():
705
+ continue
689
706
# Execute clean, build, test, install
690
707
self .execute_product_build_steps (product_class , host_target )
691
708
709
+ # Extract symbols...
710
+ for host_target in all_hosts :
711
+ self ._execute_extract_symbols_action (host_target )
712
+
713
+ # Package...
714
+ for host_target in all_hosts :
715
+ self ._execute_package_action (host_target )
716
+
717
+ # Lipo...
718
+ self ._execute_merged_host_lipo_action ()
719
+
692
720
def _execute_build_action (self , host_target , product_class ):
693
721
action_name = "{}-{}-build" .format (host_target .name ,
694
722
product_class .product_name ())
0 commit comments