Skip to content

Commit b1d56ea

Browse files
committed
[build-script] Add support for using isolated -impl actions.
- This change moves the top-level invocation driver loop into `build-script` and uses the `-impl` script to perform each individual action. Once landed and enabled, this will enable us to migrate the individual pieces of the `-impl` script into Python code in an incremental fashion. - This also introduces stub product definitions for each of the different projects we manage. - This works, but is disabled by default (`--no-legacy-impl`) because it severely impacts the performance of null builds (4x slower, currently) due to the `build-script-impl` parsing overhead. If only we had a JITing bash implementation...
1 parent c8bbd63 commit b1d56ea

File tree

13 files changed

+327
-19
lines changed

13 files changed

+327
-19
lines changed

utils/build-script

Lines changed: 121 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ from swift_build_support.cmake import CMake # noqa (E402)
5050
import swift_build_support.workspace # noqa (E402)
5151

5252

53-
def call_without_sleeping(command, env=None, dry_run=False):
53+
build_script_impl = os.path.join(
54+
SWIFT_SOURCE_ROOT, "swift", "utils", "build-script-impl")
55+
56+
57+
def call_without_sleeping(command, env=None, dry_run=False, echo=False):
5458
"""
5559
Execute a command during which system sleep is disabled.
5660
@@ -62,7 +66,7 @@ def call_without_sleeping(command, env=None, dry_run=False):
6266
# Don't mutate the caller's copy of the arguments.
6367
command = ["caffeinate"] + list(command)
6468

65-
shell.call(command, env=env, dry_run=dry_run)
69+
shell.call(command, env=env, dry_run=dry_run, echo=echo)
6670

6771

6872
class HostSpecificConfiguration(object):
@@ -774,6 +778,115 @@ class BuildScriptInvocation(object):
774778

775779
return options
776780

781+
def compute_product_classes(self):
782+
"""compute_product_classes() -> list
783+
784+
Compute the list of all Product classes used in this build. This list
785+
is constructed in dependency order.
786+
"""
787+
788+
# FIXME: This is a weird division (returning a list of class objects),
789+
# but it matches the existing structure of the `build-script-impl`.
790+
791+
product_classes = []
792+
product_classes.append(products.CMark)
793+
product_classes.append(products.LLVM)
794+
product_classes.append(products.Swift)
795+
if self.args.build_lldb:
796+
product_classes.append(products.LLDB)
797+
if self.args.build_llbuild:
798+
product_classes.append(products.LLBuild)
799+
if self.args.build_libdispatch:
800+
product_classes.append(products.LibDispatch)
801+
if self.args.build_foundation:
802+
product_classes.append(products.Foundation)
803+
if self.args.build_xctest:
804+
product_classes.append(products.XCTest)
805+
if self.args.build_swiftpm:
806+
product_classes.append(products.SwiftPM)
807+
return product_classes
808+
809+
def execute(self):
810+
"""Execute the invocation with the configured arguments."""
811+
812+
# Convert to a build-script-impl invocation.
813+
(impl_env, impl_args) = self.convert_to_impl_arguments()
814+
815+
# If using the legacy implementation, delegate all behavior to
816+
# `build-script-impl`.
817+
if self.args.legacy_impl:
818+
# Execute the underlying build script implementation.
819+
call_without_sleeping([build_script_impl] + impl_args,
820+
env=impl_env, echo=True)
821+
return
822+
823+
# Otherwise, we compute and execute the individual actions ourselves.
824+
825+
def execute_one_impl_action(host=None, product_class=None, name=None):
826+
if host is None:
827+
assert (product_class is None and
828+
name == "merged-hosts-lipo"), "invalid action"
829+
action_name = name
830+
elif product_class is None:
831+
assert name == "package", "invalid action"
832+
action_name = "{}-{}".format(host.name, name)
833+
else:
834+
assert name is not None, "invalid action"
835+
action_name = "{}-{}-{}".format(
836+
host.name, product_class.product_name(), name)
837+
call_without_sleeping(
838+
[build_script_impl] + impl_args + [
839+
"--only-execute", action_name],
840+
env=impl_env, echo=self.args.verbose_build)
841+
842+
# Compute the list of hosts to operate on.
843+
all_host_names = [
844+
self.args.host_target] + self.args.cross_compile_hosts
845+
all_hosts = [StdlibDeploymentTarget.get_target_for_name(name)
846+
for name in all_host_names]
847+
848+
# Compute the list of product classes to operate on.
849+
#
850+
# FIXME: This should really be per-host, but the current structure
851+
# matches that of `build-script-impl`.
852+
product_classes = self.compute_product_classes()
853+
854+
# Execute each "pass".
855+
856+
# Build...
857+
for host_target in all_hosts:
858+
# FIXME: We should only compute these once.
859+
config = HostSpecificConfiguration(host_target.name, self)
860+
print("Building the standard library for: {}".format(
861+
" ".join(config.swift_stdlib_build_targets)))
862+
if config.swift_test_run_targets and (
863+
self.args.test or self.args.long_test):
864+
print("Running Swift tests for: {}".format(
865+
" ".join(config.swift_test_run_targets)))
866+
if config.swift_benchmark_run_targets and self.args.benchmark:
867+
print("Running Swift benchmarks for: {}".format(
868+
" ".join(config.swift_benchmark_run_targets)))
869+
870+
for product_class in product_classes:
871+
execute_one_impl_action(host_target, product_class, "build")
872+
873+
# Test...
874+
for host_target in all_hosts:
875+
for product_class in product_classes:
876+
execute_one_impl_action(host_target, product_class, "test")
877+
878+
# Install...
879+
for host_target in all_hosts:
880+
for product_class in product_classes:
881+
execute_one_impl_action(host_target, product_class, "install")
882+
883+
# Package...
884+
for host_target in all_hosts:
885+
execute_one_impl_action(host_target, name="package")
886+
887+
# Lipo...
888+
execute_one_impl_action(name="merged-hosts-lipo")
889+
777890

778891
# Main entry point for the preset mode.
779892
def main_preset():
@@ -1042,6 +1155,11 @@ details of the setups of other systems or automated environments.""")
10421155
"them",
10431156
action="store_true",
10441157
default=False)
1158+
parser.add_argument(
1159+
"--no-legacy-impl", dest="legacy_impl",
1160+
help="avoid legacy implementation",
1161+
action="store_false",
1162+
default=True)
10451163

10461164
targets_group = parser.add_argument_group(
10471165
title="Host and cross-compilation targets")
@@ -1739,9 +1857,6 @@ details of the setups of other systems or automated environments.""")
17391857

17401858
args = migration.parse_args(parser, sys.argv[1:])
17411859

1742-
build_script_impl = os.path.join(
1743-
SWIFT_SOURCE_ROOT, "swift", "utils", "build-script-impl")
1744-
17451860
if args.build_script_impl_args:
17461861
# If we received any impl args, check if `build-script-impl` would
17471862
# accept them or not before any further processing.
@@ -1795,13 +1910,8 @@ details of the setups of other systems or automated environments.""")
17951910
if args.build_ninja:
17961911
invocation.build_ninja()
17971912

1798-
# Convert to a build-script-impl invocation.
1799-
(build_script_impl_env, build_script_impl_args) = \
1800-
invocation.convert_to_impl_arguments()
1801-
18021913
# Execute the underlying build script implementation.
1803-
call_without_sleeping([build_script_impl] + build_script_impl_args,
1804-
env=build_script_impl_env)
1914+
invocation.execute()
18051915

18061916
if args.symbols_package:
18071917
print('--- Creating symbols package ---')

utils/swift_build_support/swift_build_support/products/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,27 @@
1010
#
1111
# ----------------------------------------------------------------------------
1212

13+
from .cmark import CMark
14+
from .foundation import Foundation
15+
from .libdispatch import LibDispatch
16+
from .llbuild import LLBuild
17+
from .lldb import LLDB
18+
from .llvm import LLVM
1319
from .ninja import Ninja
20+
from .swift import Swift
21+
from .swiftpm import SwiftPM
22+
from .xctest import XCTest
1423

1524
__all__ = [
25+
'CMark',
1626
'Ninja',
27+
'Foundation',
28+
'LibDispatch',
29+
'LLBuild',
30+
'LLDB',
31+
'LLVM',
32+
'Ninja',
33+
'Swift',
34+
'SwiftPM',
35+
'XCTest',
1736
]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# swift_build_support/products/cmark.py -------------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
from . import product
14+
15+
16+
class CMark(product.Product):
17+
pass
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# swift_build_support/products/foundation.py ---------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
from . import product
14+
15+
16+
class Foundation(product.Product):
17+
pass
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# swift_build_support/products/libdispatch.py -------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
from . import product
14+
15+
16+
class LibDispatch(product.Product):
17+
pass
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# swift_build_support/products/clang.py -------------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
from . import product
14+
15+
16+
class LLBuild(product.Product):
17+
pass
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# swift_build_support/products/lldb.py --------------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
from . import product
14+
15+
16+
class LLDB(product.Product):
17+
pass
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# swift_build_support/products/llvm.py --------------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
from . import product
14+
15+
16+
class LLVM(product.Product):
17+
pass

utils/swift_build_support/swift_build_support/products/ninja.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,12 @@
1818
import platform
1919
import sys
2020

21+
from . import product
2122
from .. import cache_util
2223
from .. import shell
2324

2425

25-
class Ninja(object):
26-
27-
def __init__(self, args, toolchain, source_dir, build_dir):
28-
self.args = args
29-
self.toolchain = toolchain
30-
self.source_dir = source_dir
31-
self.build_dir = build_dir
32-
26+
class Ninja(product.Product):
3327
@cache_util.reify
3428
def ninja_bin_path(self):
3529
return os.path.join(self.build_dir, 'ninja')
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# swift_build_support/products/product.py -----------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
14+
class Product(object):
15+
@classmethod
16+
def product_name(cls):
17+
"""product_name() -> str
18+
19+
The identifier-style name to use for this product.
20+
"""
21+
return cls.__name__.lower()
22+
23+
@classmethod
24+
def get_build_directory_name(cls, host_target):
25+
return "{}-{}".format(cls.product_name(),
26+
host_target.name)
27+
28+
def __init__(self, args, toolchain, source_dir, build_dir):
29+
self.args = args
30+
self.toolchain = toolchain
31+
self.source_dir = source_dir
32+
self.build_dir = build_dir
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# swift_build_support/products/swift.py -------------------------*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
from . import product
14+
15+
16+
class Swift(product.Product):
17+
pass

0 commit comments

Comments
 (0)