@@ -848,14 +848,24 @@ class BuildScriptInvocation(object):
848848 return options
849849
850850 def compute_product_classes (self ):
851- """compute_product_classes() -> (list, list)
852-
853- Compute the list first of all build-script-impl products and then all
854- non-build-script-impl products. It is assumed that concatenating the two
855- lists together will result in a valid dependency graph for the
856- compilation.
851+ """compute_product_classes() -> (list, list, list)
857852
853+ Compute the list first of all pre-build-script-impl products, then all
854+ build-script-impl products and then all non-build-script-impl products.
855+ It is assumed that concatenating the three lists together will result in a
856+ valid dependency graph for the compilation.
858857 """
858+ before_impl_product_classes = []
859+ # If --skip-early-swift-driver is passed in, swift will be built
860+ # as usual, but relying on its own C++-based (Legacy) driver.
861+ # Otherwise, we build an "early" swift-driver using the host
862+ # toolchain, which the later-built compiler will forward
863+ # `swiftc` invocations to. That is, if we find a Swift compiler
864+ # in the host toolchain. If the host toolchain is not equpipped with
865+ # a Swift compiler, a warning is emitted. In the future, it may become
866+ # mandatory that the host toolchain come with its own `swiftc`.
867+ if self .args .build_early_swift_driver :
868+ before_impl_product_classes .append (products .EarlySwiftDriver )
859869
860870 # FIXME: This is a weird division (returning a list of class objects),
861871 # but it matches the existing structure of the `build-script-impl`.
@@ -940,6 +950,7 @@ class BuildScriptInvocation(object):
940950 # non-build-script-impl products. Otherwise, it would be unsafe to
941951 # re-order build-script-impl products in front of non
942952 # build-script-impl products.
953+ before_impl_product_classes = []
943954 impl_product_classes = []
944955 product_classes = []
945956 is_darwin = platform .system () == 'Darwin'
@@ -950,15 +961,19 @@ class BuildScriptInvocation(object):
950961
951962 if p .is_build_script_impl_product ():
952963 impl_product_classes .append (p )
964+ elif p .is_before_build_script_impl_product ():
965+ before_impl_product_classes .append (p )
953966 else :
954967 product_classes .append (p )
955968 if self .args .verbose_build :
956969 print ("Final Build Order:" )
970+ for p in before_impl_product_classes :
971+ print (" {}" .format (p .product_name ()))
957972 for p in impl_product_classes :
958973 print (" {}" .format (p .product_name ()))
959974 for p in product_classes :
960975 print (" {}" .format (p .product_name ()))
961- return (impl_product_classes , product_classes )
976+ return (before_impl_product_classes , impl_product_classes , product_classes )
962977
963978 def execute (self ):
964979 """Execute the invocation with the configured arguments."""
@@ -975,7 +990,6 @@ class BuildScriptInvocation(object):
975990 return
976991
977992 # Otherwise, we compute and execute the individual actions ourselves.
978-
979993 # Compute the list of hosts to operate on.
980994 all_host_names = [
981995 self .args .host_target ] + self .args .cross_compile_hosts
@@ -986,10 +1000,22 @@ class BuildScriptInvocation(object):
9861000 #
9871001 # FIXME: This should really be per-host, but the current structure
9881002 # matches that of `build-script-impl`.
989- (impl_product_classes , product_classes ) = self .compute_product_classes ()
1003+ (before_impl_product_classes , impl_product_classes , product_classes ) = \
1004+ self .compute_product_classes ()
9901005
9911006 # Execute each "pass".
9921007
1008+ # Pre-build-script-impl products...
1009+ # Note: currently only supports building for the host.
1010+ for host_target in [self .args .host_target ]:
1011+ for product_class in before_impl_product_classes :
1012+ if product_class .is_build_script_impl_product ():
1013+ continue
1014+ if not product_class .is_before_build_script_impl_product ():
1015+ continue
1016+ # Execute clean, build, test, install
1017+ self .execute_product_build_steps (product_class , host_target )
1018+
9931019 # Build...
9941020 for host_target in all_hosts :
9951021 # FIXME: We should only compute these once.
@@ -1029,33 +1055,8 @@ class BuildScriptInvocation(object):
10291055 for product_class in product_classes :
10301056 if product_class .is_build_script_impl_product ():
10311057 continue
1032- product_source = product_class .product_source_name ()
1033- product_name = product_class .product_name ()
1034- if product_class .is_swiftpm_unified_build_product ():
1035- build_dir = self .workspace .swiftpm_unified_build_dir (
1036- host_target )
1037- else :
1038- build_dir = self .workspace .build_dir (
1039- host_target , product_name )
1040- product = product_class (
1041- args = self .args ,
1042- toolchain = self .toolchain ,
1043- source_dir = self .workspace .source_dir (product_source ),
1044- build_dir = build_dir )
1045- if product .should_clean (host_target ):
1046- print ("--- Cleaning %s ---" % product_name )
1047- product .clean (host_target )
1048- if product .should_build (host_target ):
1049- print ("--- Building %s ---" % product_name )
1050- product .build (host_target )
1051- if product .should_test (host_target ):
1052- print ("--- Running tests for %s ---" % product_name )
1053- product .test (host_target )
1054- print ("--- Finished tests for %s ---" % product_name )
1055- if product .should_install (host_target ) or \
1056- (self .install_all and product .should_build (host_target )):
1057- print ("--- Installing %s ---" % product_name )
1058- product .install (host_target )
1058+ # Execute clean, build, test, install
1059+ self .execute_product_build_steps (product_class , host_target )
10591060
10601061 # Extract symbols...
10611062 for host_target in all_hosts :
@@ -1103,6 +1104,35 @@ class BuildScriptInvocation(object):
11031104 ["--only-execute" , action_name ],
11041105 env = self .impl_env , echo = self .args .verbose_build )
11051106
1107+ def execute_product_build_steps (self , product_class , host_target ):
1108+ product_source = product_class .product_source_name ()
1109+ product_name = product_class .product_name ()
1110+ if product_class .is_swiftpm_unified_build_product ():
1111+ build_dir = self .workspace .swiftpm_unified_build_dir (
1112+ host_target )
1113+ else :
1114+ build_dir = self .workspace .build_dir (
1115+ host_target , product_name )
1116+ product = product_class (
1117+ args = self .args ,
1118+ toolchain = self .toolchain ,
1119+ source_dir = self .workspace .source_dir (product_source ),
1120+ build_dir = build_dir )
1121+ if product .should_clean (host_target ):
1122+ print ("--- Cleaning %s ---" % product_name )
1123+ product .clean (host_target )
1124+ if product .should_build (host_target ):
1125+ print ("--- Building %s ---" % product_name )
1126+ product .build (host_target )
1127+ if product .should_test (host_target ):
1128+ print ("--- Running tests for %s ---" % product_name )
1129+ product .test (host_target )
1130+ print ("--- Finished tests for %s ---" % product_name )
1131+ if product .should_install (host_target ) or \
1132+ (self .install_all and product .should_build (host_target )):
1133+ print ("--- Installing %s ---" % product_name )
1134+ product .install (host_target )
1135+
11061136
11071137# -----------------------------------------------------------------------------
11081138# Main (preset)
0 commit comments