Skip to content

Commit 89847ac

Browse files
authored
Merge pull request #38928 from apple/revert-38886-pr-88e3658ca820cb93dc6145ed8648f17387c3c87e
Revert "[build-script] Use a builder to setup pass pipelines that are then scheduled when using --infer"
2 parents 0daa9cc + 7348395 commit 89847ac

File tree

3 files changed

+146
-336
lines changed

3 files changed

+146
-336
lines changed

utils/swift_build_support/swift_build_support/build_script_invocation.py

Lines changed: 146 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@
2222

2323
import six
2424

25+
from swift_build_support.swift_build_support import build_graph
2526
from swift_build_support.swift_build_support import products
2627
from swift_build_support.swift_build_support import shell
2728
from swift_build_support.swift_build_support import targets
2829
from swift_build_support.swift_build_support import workspace
2930
from swift_build_support.swift_build_support.cmake import CMake
3031
from swift_build_support.swift_build_support.host_specific_configuration \
3132
import HostSpecificConfiguration
32-
from swift_build_support.swift_build_support.productpipeline_list_builder \
33-
import ProductPipelineListBuilder
3433
from swift_build_support.swift_build_support.targets \
3534
import StdlibDeploymentTarget
3635
from swift_build_support.swift_build_support.utils \
@@ -134,12 +133,12 @@ def convert_to_impl_arguments(self):
134133

135134
# Compute any product specific cmake arguments.
136135
#
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
138137
# tuple of lists of which the first is the build-script-impl products
139138
# and the second is the non-build-script-impl-products. It guarantees
140139
# that when we concatenate these two lists together we get a valid
141140
# 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()), []):
143142
if not product_class.is_build_script_impl_product():
144143
continue
145144

@@ -492,20 +491,15 @@ def compute_host_specific_variables(self):
492491

493492
return options
494493

495-
def compute_product_pipelines(self):
496-
"""compute_product_pipelines() -> [[Product]]
494+
def compute_product_classes(self):
495+
"""compute_product_classes() -> (list, list, list)
497496
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.
505501
"""
506-
builder = ProductPipelineListBuilder(self.args)
507-
508-
builder.begin_pipeline()
502+
before_impl_product_classes = []
509503
# If --skip-early-swift-driver is passed in, swift will be built
510504
# as usual, but relying on its own C++-based (Legacy) driver.
511505
# Otherwise, we build an "early" swift-driver using the host
@@ -514,79 +508,120 @@ def compute_product_pipelines(self):
514508
# in the host toolchain. If the host toolchain is not equpipped with
515509
# a Swift compiler, a warning is emitted. In the future, it may become
516510
# 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)
519513

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)
522516

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 = []
530520

531521
# If --skip-build-llvm is passed in, LLVM cannot be completely disabled, as
532522
# Swift still needs a few LLVM targets like tblgen to be built for it to be
533523
# 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)
578569

579570
# Keep SwiftDriver at last.
580571
# swift-driver's integration with the build scripts is not fully
581572
# supported. Using swift-driver to build these products may hit
582573
# 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)
590625

591626
def execute(self):
592627
"""Execute the invocation with the configured arguments."""
@@ -609,40 +644,26 @@ def execute(self):
609644
all_hosts = [StdlibDeploymentTarget.get_target_for_name(name)
610645
for name in all_host_names]
611646

612-
# Compute the list of lists of product classes to operate on.
647+
# Compute the list of product classes to operate on.
613648
#
614649
# FIXME: This should really be per-host, but the current structure
615650
# 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()
637653

638-
# Package...
639-
for host_target in all_hosts:
640-
self._execute_package_action(host_target)
654+
# Execute each "pass".
641655

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)
644666

645-
def _execute_impl(self, pipeline, all_hosts, should_run_epilogue_operations):
646667
# Build...
647668
for host_target in all_hosts:
648669
# FIXME: We should only compute these once.
@@ -660,35 +681,42 @@ def _execute_impl(self, pipeline, all_hosts, should_run_epilogue_operations):
660681
print("Running Swift benchmarks for: {}".format(
661682
" ".join(config.swift_benchmark_run_targets)))
662683

663-
for product_class in pipeline:
684+
for product_class in impl_product_classes:
664685
self._execute_build_action(host_target, product_class)
665686

666687
# Test...
667688
for host_target in all_hosts:
668-
for product_class in pipeline:
689+
for product_class in impl_product_classes:
669690
self._execute_test_action(host_target, product_class)
670691

671692
# Install...
672693
for host_target in all_hosts:
673-
for product_class in pipeline:
694+
for product_class in impl_product_classes:
674695
self._execute_install_action(host_target, product_class)
675696

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-
681697
# Core Lipo...
682698
self._execute_merged_host_lipo_core_action()
683699

684-
def _execute(self, pipeline, all_host_names):
685-
# Pre-build-script-impl products...
700+
# Non-build-script-impl products...
686701
# 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
689706
# Execute clean, build, test, install
690707
self.execute_product_build_steps(product_class, host_target)
691708

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+
692720
def _execute_build_action(self, host_target, product_class):
693721
action_name = "{}-{}-build".format(host_target.name,
694722
product_class.product_name())

0 commit comments

Comments
 (0)