Skip to content

Commit 6d0c1e7

Browse files
committed
[build-script] Transform IndexStoreDB and SorcekitLSP to use ProductBuilder.
Create a new helper builder for IndexStoreDB and SourceKitLSP called BuildScriptHelperBuilder (because the invoked script is called build-script-helper.py). Move most of the code that existed in a function in indexstore.db into that helper class. Create small subtypes of the helper paramtrized for IndexStoreDB and SourceKitLSP. Modify the main build-script to invoke the new build instead of the Product class directly. This way, when all the products use builders to be build, all of them will use the same Python invocations, but some of them will use build-script-impl, and others will use build-script-helper.py.
1 parent a96890c commit 6d0c1e7

File tree

13 files changed

+804
-112
lines changed

13 files changed

+804
-112
lines changed

utils/build-script

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -964,20 +964,16 @@ class BuildScriptInvocation(object):
964964

965965
# Non-build-script-impl products...
966966
# Note: currently only supports building for the host.
967-
for host_target in [self.args.host_target]:
967+
for host_target in [
968+
StdlibDeploymentTarget.get_target_for_name(
969+
self.args.host_target)]:
968970
for product_class in product_classes:
969971
if product_class.is_build_script_impl_product():
970972
continue
971-
product_source = product_class.product_source_name()
972-
product_name = product_class.product_name()
973-
product = product_class(
974-
args=self.args,
975-
toolchain=self.toolchain,
976-
source_dir=self.workspace.source_dir(product_source),
977-
build_dir=self.workspace.build_dir(
978-
host_target, product_name))
979-
product.build(host_target)
980-
product.test(host_target)
973+
builder = product_class.new_builder(
974+
self.args, self.toolchain, self.workspace, host_target)
975+
builder.build()
976+
builder.test()
981977

982978
# Extract symbols...
983979
for host_target in all_hosts:

utils/swift_build_support/swift_build_support/products/benchmarks.py

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,48 +28,53 @@ def product_source_name(cls):
2828
def is_build_script_impl_product(cls):
2929
return False
3030

31-
def build(self, host_target):
32-
run_build_script_helper(host_target, self, self.args)
31+
@classmethod
32+
def new_builder(cls, args, toolchain, workspace, host):
33+
return BenchmarksBuilder(cls, args, toolchain, workspace, host)
34+
35+
36+
# NOTE: this is very similar to BuildScriptHelperBuilder, but also
37+
# different enough to justify a different builder altogether.
38+
class BenchmarksBuilder(product.ProductBuilder):
39+
def __init__(self, product_class, args, toolchain, workspace, host):
40+
# Our source directory is a subdirectory inside the swift source
41+
# directory
42+
self.__source_dir = os.path.join(workspace.source_dir('swift'),
43+
'benchmark')
44+
self.__build_dir = workspace.build_dir(host.name,
45+
product_class.product_name())
46+
self.__args = args
3347

34-
def test(self, host_target):
48+
def build(self):
49+
# We use a separate python helper to enable quicker iteration when
50+
# working on this by avoiding going through build-script to test small
51+
# changes.
52+
script_path = os.path.join(
53+
self.__source_dir, 'scripts', 'build_script_helper.py')
54+
toolchain_path = self.__args.install_destdir
55+
if platform.system() == 'Darwin':
56+
# The prefix is an absolute path, so concatenate without os.path.
57+
toolchain_path += \
58+
targets.darwin_toolchain_prefix(self.__args.install_prefix)
59+
helper_cmd = [
60+
script_path,
61+
'--verbose',
62+
'--package-path', self.__source_dir,
63+
'--build-path', self.__build_dir,
64+
'--toolchain', toolchain_path,
65+
]
66+
shell.call(helper_cmd)
67+
68+
def test(self):
3569
"""Just run a single instance of the command for both .debug and
3670
.release.
3771
"""
3872
cmdline = ['--num-iters=1', 'XorLoop']
39-
bench_Onone = os.path.join(self.build_dir, 'bin', 'Benchmark_Onone')
73+
bench_Onone = os.path.join(self.__build_dir, 'bin', 'Benchmark_Onone')
4074
shell.call([bench_Onone] + cmdline)
4175

42-
bench_O = os.path.join(self.build_dir, 'bin', 'Benchmark_O')
76+
bench_O = os.path.join(self.__build_dir, 'bin', 'Benchmark_O')
4377
shell.call([bench_O] + cmdline)
4478

45-
bench_Osize = os.path.join(self.build_dir, 'bin', 'Benchmark_Osize')
79+
bench_Osize = os.path.join(self.__build_dir, 'bin', 'Benchmark_Osize')
4680
shell.call([bench_Osize] + cmdline)
47-
48-
49-
def run_build_script_helper(host_target, product, args):
50-
toolchain_path = args.install_destdir
51-
if platform.system() == 'Darwin':
52-
# The prefix is an absolute path, so concatenate without os.path.
53-
toolchain_path += \
54-
targets.darwin_toolchain_prefix(args.install_prefix)
55-
56-
# Our source_dir is expected to be './$SOURCE_ROOT/benchmarks'. That is due
57-
# the assumption that each product is in its own build directory. This
58-
# product is not like that and has its package/tools instead in
59-
# ./$SOURCE_ROOT/swift/benchmark.
60-
package_path = os.path.join(product.source_dir, '..', 'swift', 'benchmark')
61-
package_path = os.path.abspath(package_path)
62-
63-
# We use a separate python helper to enable quicker iteration when working
64-
# on this by avoiding going through build-script to test small changes.
65-
helper_path = os.path.join(package_path, 'scripts',
66-
'build_script_helper.py')
67-
68-
build_cmd = [
69-
helper_path,
70-
'--verbose',
71-
'--package-path', package_path,
72-
'--build-path', product.build_dir,
73-
'--toolchain', toolchain_path,
74-
]
75-
shell.call(build_cmd)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# swift_build_support/product_builders/build_script_helper_b... -*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See https://swift.org/LICENSE.txt for license information
9+
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ----------------------------------------------------------------------------
12+
13+
import abc
14+
import os
15+
import platform
16+
17+
from . import product
18+
from .. import shell, targets
19+
20+
21+
class BuildScriptHelperBuilder(product.ProductBuilder):
22+
def __init__(self, product_class, args, toolchain, workspace, host):
23+
self.__source_dir = workspace.source_dir(
24+
product_class.product_source_name())
25+
self.__build_dir = workspace.build_dir(host.name,
26+
product_class.product_name())
27+
self.__args = args
28+
29+
def build(self):
30+
self.__run_build_script_helper('build')
31+
32+
def test(self):
33+
if self._should_test():
34+
self.__run_build_script_helper('test')
35+
36+
@abc.abstractmethod
37+
def _should_test(self):
38+
pass
39+
40+
def __run_build_script_helper(self, action):
41+
script_path = os.path.join(
42+
self.__source_dir, 'Utilities', 'build-script-helper.py')
43+
toolchain_path = self.__args.install_destdir
44+
if platform.system() == 'Darwin':
45+
# The prefix is an absolute path, so concatenate without os.path.
46+
toolchain_path += \
47+
targets.darwin_toolchain_prefix(self.__args.install_prefix)
48+
if self.__args.build_variant == 'Debug':
49+
configuration = 'debug'
50+
else:
51+
configuration = 'release'
52+
helper_cmd = [
53+
script_path,
54+
action,
55+
'--verbose',
56+
'--package-path', self.__source_dir,
57+
'--build-path', self.__build_dir,
58+
'--configuration', configuration,
59+
'--toolchain', toolchain_path,
60+
]
61+
shell.call(helper_cmd)

utils/swift_build_support/swift_build_support/products/indexstoredb.py

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,8 @@
1010
#
1111
# ----------------------------------------------------------------------------
1212

13-
import os
14-
import platform
15-
1613
from . import product
17-
from .. import shell
18-
from .. import targets
14+
from .build_script_helper_builder import BuildScriptHelperBuilder
1915

2016

2117
class IndexStoreDB(product.Product):
@@ -27,30 +23,16 @@ def product_source_name(cls):
2723
def is_build_script_impl_product(cls):
2824
return False
2925

30-
def build(self, host_target):
31-
run_build_script_helper('build', host_target, self, self.args)
32-
33-
def test(self, host_target):
34-
if self.args.test and self.args.test_indexstoredb:
35-
run_build_script_helper('test', host_target, self, self.args)
36-
37-
38-
def run_build_script_helper(action, host_target, product, args):
39-
script_path = os.path.join(
40-
product.source_dir, 'Utilities', 'build-script-helper.py')
41-
toolchain_path = args.install_destdir
42-
if platform.system() == 'Darwin':
43-
# The prefix is an absolute path, so concatenate without os.path.
44-
toolchain_path += \
45-
targets.darwin_toolchain_prefix(args.install_prefix)
46-
configuration = 'debug' if args.build_variant == 'Debug' else 'release'
47-
helper_cmd = [
48-
script_path,
49-
action,
50-
'--verbose',
51-
'--package-path', product.source_dir,
52-
'--build-path', product.build_dir,
53-
'--configuration', configuration,
54-
'--toolchain', toolchain_path,
55-
]
56-
shell.call(helper_cmd)
26+
@classmethod
27+
def new_builder(cls, args, toolchain, workspace, host):
28+
return IndexStoreDBBuilder(cls, args, toolchain, workspace, host)
29+
30+
31+
class IndexStoreDBBuilder(BuildScriptHelperBuilder):
32+
def __init__(self, product_class, args, toolchain, workspace, host):
33+
BuildScriptHelperBuilder.__init__(self, product_class, args, toolchain,
34+
workspace, host)
35+
self.__args = args
36+
37+
def _should_test(self):
38+
return self.__args.test and self.__args.test_indexstoredb

utils/swift_build_support/swift_build_support/products/ninja.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ def is_build_script_impl_product(cls):
3030

3131
@classmethod
3232
def new_builder(cls, args, toolchain, workspace, host):
33-
return NinjaBuilder(cls, args, toolchain, workspace)
33+
return NinjaBuilder(cls, args, toolchain, workspace, host)
3434

3535

3636
class NinjaBuilder(product.ProductBuilder):
37-
def __init__(self, product_class, args, toolchain, workspace):
37+
def __init__(self, product_class, args, toolchain, workspace, host):
3838
self.source_dir = workspace.source_dir(
3939
product_class.product_source_name())
40+
# host is ignored. Ninja only builds for the build host.
4041
self.build_dir = workspace.build_dir('build',
4142
product_class.product_name())
4243
self.args = args

utils/swift_build_support/swift_build_support/products/product.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,6 @@ def is_build_script_impl_product(cls):
4040
"""
4141
return True
4242

43-
def build(self, host_target):
44-
"""build() -> void
45-
46-
Perform the build, for a non-build-script-impl product.
47-
"""
48-
raise NotImplementedError
49-
50-
def test(self, host_target):
51-
"""test() -> void
52-
53-
Run the tests, for a non-build-script-impl product.
54-
"""
55-
raise NotImplementedError
56-
5743
def __init__(self, args, toolchain, source_dir, build_dir):
5844
self.args = args
5945
self.toolchain = toolchain
@@ -81,7 +67,7 @@ class ProductBuilder(object):
8167
"""
8268

8369
@abc.abstractmethod
84-
def __init__(self, product_class, args, toolchain, workspace):
70+
def __init__(self, product_class, args, toolchain, workspace, host):
8571
"""
8672
Create a product builder for the given product class.
8773
@@ -102,6 +88,10 @@ def __init__(self, product_class, args, toolchain, workspace):
10288
to be located. A builder should use the workspace to access its own
10389
source/build directory, as well as other products source/build
10490
directories.
91+
host : `swift_build_support.targets.Target`
92+
The target host for the product. The product is intended to be used
93+
in the given target, even if the build machine is of a different OS
94+
and/or architecture.
10595
"""
10696
pass
10797

utils/swift_build_support/swift_build_support/products/sourcekitlsp.py

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

13-
from . import indexstoredb
1413
from . import product
14+
from .build_script_helper_builder import BuildScriptHelperBuilder
1515

1616

1717
class SourceKitLSP(product.Product):
@@ -23,11 +23,16 @@ def product_source_name(cls):
2323
def is_build_script_impl_product(cls):
2424
return False
2525

26-
def build(self, host_target):
27-
indexstoredb.run_build_script_helper(
28-
'build', host_target, self, self.args)
26+
@classmethod
27+
def new_builder(cls, args, toolchain, workspace, host):
28+
return SourceKitLSPBuilder(cls, args, toolchain, workspace, host)
29+
30+
31+
class SourceKitLSPBuilder(BuildScriptHelperBuilder):
32+
def __init__(self, product_class, args, toolchain, workspace, host):
33+
BuildScriptHelperBuilder.__init__(self, product_class, args, toolchain,
34+
workspace, host)
35+
self.__args = args
2936

30-
def test(self, host_target):
31-
if self.args.test and self.args.test_sourcekitlsp:
32-
indexstoredb.run_build_script_helper(
33-
'test', host_target, self, self.args)
37+
def _should_test(self):
38+
return self.__args.test and self.__args.test_sourcekitlsp

utils/swift_build_support/swift_build_support/products/tsan_libdispatch.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,24 @@ def product_source_name(cls):
2929
def is_build_script_impl_product(cls):
3030
return False
3131

32-
def build(self, host_target):
32+
@classmethod
33+
def new_builder(cls, args, toolchain, workspace, host):
34+
return TSanLibDispatchBuilder(cls, args, toolchain, workspace, host)
35+
36+
37+
class TSanLibDispatchBuilder(product.ProductBuilder):
38+
def __init__(self, product_class, args, toolchain, workspace, host):
39+
self.__args = args
40+
self.__workspace = workspace
41+
42+
self.__source_dir = workspace.source_dir('compiler-rt')
43+
self.__build_dir = workspace.build_dir(host.name,
44+
product_class.product_name())
45+
46+
def build(self):
3347
"""Build TSan runtime (compiler-rt)."""
34-
rt_source_dir = join_path(self.source_dir, os.pardir, 'compiler-rt')
35-
toolchain_path = join_path(self.args.install_destdir, 'usr')
48+
49+
toolchain_path = join_path(self.__args.install_destdir, 'usr')
3650
clang = join_path(toolchain_path, 'bin', 'clang')
3751
clangxx = join_path(toolchain_path, 'bin', 'clang++')
3852

@@ -48,21 +62,21 @@ def build(self, host_target):
4862
'-DCOMPILER_RT_BUILD_XRAY=OFF',
4963
'-DCOMPILER_RT_INTERCEPT_LIBDISPATCH=ON',
5064
'-DCOMPILER_RT_LIBDISPATCH_INSTALL_PATH=%s' % toolchain_path,
51-
rt_source_dir]
65+
self.__source_dir]
5266
build_cmd = ['ninja', 'tsan']
5367

5468
# Always rebuild TSan runtime
55-
shell.rmtree(self.build_dir)
56-
shell.makedirs(self.build_dir)
69+
shell.rmtree(self.__build_dir)
70+
shell.makedirs(self.__build_dir)
5771

58-
with shell.pushd(self.build_dir):
72+
with shell.pushd(self.__build_dir):
5973
shell.call(config_cmd)
6074
shell.call(build_cmd)
6175

62-
def test(self, host_target):
76+
def test(self):
6377
"""Run check-tsan target with a LIT filter for libdispatch."""
6478
cmd = ['ninja', 'check-tsan']
6579
env = {'LIT_FILTER': 'libdispatch'}
6680

67-
with shell.pushd(self.build_dir):
81+
with shell.pushd(self.__build_dir):
6882
shell.call(cmd, env=env)

0 commit comments

Comments
 (0)