Skip to content

Commit a788461

Browse files
authored
Merge pull request #38719 from gottesmm/build-script-bootstrap-stage2-init
[build-script] Begin putting in infrastructure for the multi-compiler stage swift build
2 parents 11b3776 + 11ec4df commit a788461

File tree

7 files changed

+176
-60
lines changed

7 files changed

+176
-60
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ option(SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER
250250
"Use the host compiler and not the internal clang to build the swift runtime"
251251
FALSE)
252252

253+
option(SWIFT_RUN_TESTS_WITH_HOST_COMPILER
254+
"Run tests against the host compiler and not the just built swift"
255+
FALSE)
256+
253257
set(SWIFT_SDKS "" CACHE STRING
254258
"If non-empty, limits building target binaries only to specified SDKs (despite other SDKs being available)")
255259

test/CMakeLists.txt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,20 @@ set(SWIFT_LIT_ARGS "" CACHE STRING "Arguments to pass to lit")
134134
set(SWIFT_LIT_ENVIRONMENT "" CACHE STRING "Environment to use for lit invocations")
135135

136136
if(NOT SWIFT_INCLUDE_TOOLS)
137-
list(APPEND SWIFT_LIT_ARGS
138-
"--path=${SWIFT_NATIVE_LLVM_TOOLS_PATH}"
139-
"--path=${SWIFT_NATIVE_CLANG_TOOLS_PATH}"
140-
"--path=${SWIFT_NATIVE_SWIFT_TOOLS_PATH}")
137+
if(SWIFT_RUN_TESTS_WITH_HOST_COMPILER)
138+
precondition(CMAKE_Swift_COMPILER MESSAGE "Can only run tests if a Swift compiler is specified")
139+
get_filename_component(SWIFT_COMPILER_DIR "${CMAKE_Swift_COMPILER}" DIRECTORY)
140+
precondition(SWIFT_COMPILER_DIR)
141+
# We assume that we are building against a toolchain where all tools are
142+
# next to swiftc.
143+
list(APPEND SWIFT_LIT_ARGS
144+
"--path=${SWIFT_COMPILER_DIR}")
145+
else()
146+
list(APPEND SWIFT_LIT_ARGS
147+
"--path=${SWIFT_NATIVE_LLVM_TOOLS_PATH}"
148+
"--path=${SWIFT_NATIVE_CLANG_TOOLS_PATH}"
149+
"--path=${SWIFT_NATIVE_SWIFT_TOOLS_PATH}")
150+
endif()
141151
if(SWIFT_BUILD_STDLIB)
142152
list(APPEND SWIFT_LIT_ARGS
143153
"--param" "test_resource_dir=${SWIFTLIB_DIR}")

utils/swift_build_support/swift_build_support/cmake.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,15 @@ def __iadd__(self, other):
9090

9191
class CMake(object):
9292

93-
def __init__(self, args, toolchain):
93+
def __init__(self, args, toolchain, prefer_just_built_toolchain=False):
94+
"""If prefer_just_built_toolchain is set to True, we set the clang, clang++,
95+
and Swift compilers from the installed toolchain.
96+
"""
9497
self.args = args
9598
self.toolchain = toolchain
99+
self.prefer_just_built_toolchain = prefer_just_built_toolchain
96100

97-
def common_options(self):
101+
def common_options(self, product=None):
98102
"""Return options used for all products, including LLVM/Clang
99103
"""
100104
args = self.args
@@ -135,8 +139,18 @@ def common_options(self):
135139
if args.cmake_cxx_launcher:
136140
define("CMAKE_CXX_COMPILER_LAUNCHER:PATH", args.cmake_cxx_launcher)
137141

138-
define("CMAKE_C_COMPILER:PATH", toolchain.cc)
139-
define("CMAKE_CXX_COMPILER:PATH", toolchain.cxx)
142+
if self.prefer_just_built_toolchain and product:
143+
toolchain_path = product.install_toolchain_path(args.host_target)
144+
define("CMAKE_C_COMPILER:PATH", os.path.join(toolchain_path,
145+
'bin', 'clang'))
146+
define("CMAKE_CXX_COMPILER:PATH", os.path.join(toolchain_path,
147+
'bin', 'clang++'))
148+
define("CMAKE_Swift_COMPILER:PATH", os.path.join(toolchain_path,
149+
'bin', 'swiftc'))
150+
else:
151+
define("CMAKE_C_COMPILER:PATH", toolchain.cc)
152+
define("CMAKE_CXX_COMPILER:PATH", toolchain.cxx)
153+
define("CMAKE_Swift_COMPILER:PATH", toolchain.swiftc)
140154
define("CMAKE_LIBTOOL:PATH", toolchain.libtool)
141155
define("CMAKE_AR:PATH", toolchain.ar)
142156

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# ===--- compiler_stage.py -----------------------------------------------===#
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2021 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+
class StageArgs(object):
14+
def __init__(self, stage, args):
15+
self.stage = stage
16+
self.args = args
17+
18+
def __getattr__(self, key):
19+
real_key = '{}{}'.format(key, self.stage.postfix)
20+
if not hasattr(self.args, real_key):
21+
return None
22+
return getattr(self.args, real_key)
23+
24+
25+
class Stage(object):
26+
def __init__(self, identifier, postfix=""):
27+
self.identifier = identifier
28+
self.postfix = postfix
29+
30+
31+
STAGE_1 = Stage(1, "")
32+
STAGE_2 = Stage(2, "_stage2")

utils/swift_build_support/swift_build_support/host_specific_configuration.py

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,49 @@
1414
import sys
1515
from argparse import ArgumentError
1616

17+
from . import compiler_stage
1718
from .targets import StdlibDeploymentTarget
1819

1920

2021
class HostSpecificConfiguration(object):
21-
2222
"""Configuration information for an individual host."""
2323

24-
def __init__(self, host_target, args):
24+
def __init__(self, host_target, args, stage_dependent_args=None):
2525
"""Initialize for the given `host_target`."""
26+
# If we were not passed a stage_dependent_args object, then we do not need
27+
# to make a distinction in between them and can just use args.
28+
if not isinstance(args, compiler_stage.StageArgs):
29+
args = compiler_stage.StageArgs(compiler_stage.STAGE_1, args)
30+
if stage_dependent_args is None:
31+
stage_dependent_args = args
2632

2733
# Compute the set of deployment targets to configure/build.
28-
if host_target == args.host_target:
34+
if host_target == stage_dependent_args.host_target:
2935
# This host is the user's desired product, so honor the requested
3036
# set of targets to configure/build.
31-
stdlib_targets_to_configure = args.stdlib_deployment_targets
32-
if "all" in args.build_stdlib_deployment_targets:
37+
stdlib_targets_to_configure = stage_dependent_args.stdlib_deployment_targets
38+
if "all" in stage_dependent_args.build_stdlib_deployment_targets:
3339
stdlib_targets_to_build = set(stdlib_targets_to_configure)
3440
else:
3541
stdlib_targets_to_build = set(
36-
args.build_stdlib_deployment_targets).intersection(
37-
set(args.stdlib_deployment_targets))
42+
stage_dependent_args.build_stdlib_deployment_targets).intersection(
43+
set(stage_dependent_args.stdlib_deployment_targets))
3844
else:
3945
# Otherwise, this is a host we are building as part of
4046
# cross-compiling, so we only need the target itself.
4147
stdlib_targets_to_configure = [host_target]
42-
if (hasattr(args, 'stdlib_deployment_targets')):
48+
if stage_dependent_args.stdlib_deployment_targets:
4349
# there are some build configs that expect
4450
# not to be building the stdlib for the target
4551
# since it will be provided by different means
4652
stdlib_targets_to_build = set(
4753
stdlib_targets_to_configure).intersection(
48-
set(args.stdlib_deployment_targets))
54+
set(stage_dependent_args.stdlib_deployment_targets))
4955
else:
5056
stdlib_targets_to_build = set(stdlib_targets_to_configure)
5157

52-
if (hasattr(args, 'stdlib_deployment_targets') and
53-
args.stdlib_deployment_targets == []):
58+
if stage_dependent_args.stdlib_deployment_targets and \
59+
stage_dependent_args.stdlib_deployment_targets == []:
5460
stdlib_targets_to_configure = []
5561
stdlib_targets_to_build = []
5662

@@ -59,11 +65,15 @@ def __init__(self, host_target, args):
5965
# FIXME: We should move the platform-derived arguments to be entirely
6066
# data driven, so that we can eliminate this code duplication and just
6167
# iterate over all supported platforms.
62-
platforms_to_skip_build = self.__platforms_to_skip_build(args)
63-
platforms_to_skip_test = self.__platforms_to_skip_test(args)
68+
platforms_to_skip_build = \
69+
self.__platforms_to_skip_build(args, stage_dependent_args)
70+
platforms_to_skip_test = \
71+
self.__platforms_to_skip_test(args, stage_dependent_args)
6472
platforms_archs_to_skip_test = \
65-
self.__platforms_archs_to_skip_test(args, host_target)
66-
platforms_to_skip_test_host = self.__platforms_to_skip_test_host(args)
73+
self.__platforms_archs_to_skip_test(args, stage_dependent_args,
74+
host_target)
75+
platforms_to_skip_test_host = \
76+
self.__platforms_to_skip_test_host(args, stage_dependent_args)
6777

6878
# Compute the lists of **CMake** targets for each use case (configure
6979
# vs. build vs. run) and the SDKs to configure with.
@@ -125,7 +135,10 @@ def __init__(self, host_target, args):
125135
# Validation, long, and stress tests require building the full
126136
# standard library, whereas the other targets can build a
127137
# slightly smaller subset which is faster to build.
128-
if args.build_swift_stdlib_unittest_extra or \
138+
#
139+
# NOTE: We currently do not seperate testing options for
140+
# stage1/stage2 compiler. This can change with time.
141+
if stage_dependent_args.build_swift_stdlib_unittest_extra or \
129142
args.validation_test or args.long_test or \
130143
args.stress_test:
131144
self.swift_stdlib_build_targets.append(
@@ -172,7 +185,7 @@ def __init__(self, host_target, args):
172185
# If the compiler is being tested after being built to use the
173186
# standalone swift-driver, we build a test-target to
174187
# run a reduced set of lit-tests that verify the early swift-driver.
175-
if getattr(args, 'test_early_swift_driver', False) and\
188+
if args.test_early_swift_driver and\
176189
not test_host_only:
177190
self.swift_test_run_targets.append(
178191
"check-swift-only_early_swiftdriver-{}".format(name))
@@ -215,80 +228,82 @@ def add_flags_for_cross_compilation(self, args, deployment_target):
215228
self.swift_flags = deployment_target.platform.swift_flags(args)
216229
self.cmake_options = deployment_target.platform.cmake_options(args)
217230

218-
def __platforms_to_skip_build(self, args):
231+
def __platforms_to_skip_build(self, args, stage_dependent_args):
219232
platforms_to_skip_build = set()
220-
if not args.build_linux:
233+
if not stage_dependent_args.build_linux:
221234
platforms_to_skip_build.add(StdlibDeploymentTarget.Linux)
222-
if not args.build_freebsd:
235+
if not stage_dependent_args.build_freebsd:
223236
platforms_to_skip_build.add(StdlibDeploymentTarget.FreeBSD)
224-
if not args.build_cygwin:
237+
if not stage_dependent_args.build_cygwin:
225238
platforms_to_skip_build.add(StdlibDeploymentTarget.Cygwin)
226-
if not args.build_osx:
239+
if not stage_dependent_args.build_osx:
227240
platforms_to_skip_build.add(StdlibDeploymentTarget.OSX)
228-
if not args.build_ios_device:
241+
if not stage_dependent_args.build_ios_device:
229242
platforms_to_skip_build.add(StdlibDeploymentTarget.iOS)
230-
if not args.build_ios_simulator:
243+
if not stage_dependent_args.build_ios_simulator:
231244
platforms_to_skip_build.add(StdlibDeploymentTarget.iOSSimulator)
232-
if not args.build_tvos_device:
245+
if not stage_dependent_args.build_tvos_device:
233246
platforms_to_skip_build.add(StdlibDeploymentTarget.AppleTV)
234-
if not args.build_tvos_simulator:
247+
if not stage_dependent_args.build_tvos_simulator:
235248
platforms_to_skip_build.add(
236249
StdlibDeploymentTarget.AppleTVSimulator)
237-
if not args.build_watchos_device:
250+
if not stage_dependent_args.build_watchos_device:
238251
platforms_to_skip_build.add(StdlibDeploymentTarget.AppleWatch)
239-
if not args.build_watchos_simulator:
252+
if not stage_dependent_args.build_watchos_simulator:
240253
platforms_to_skip_build.add(
241254
StdlibDeploymentTarget.AppleWatchSimulator)
242-
if not args.build_android:
255+
if not stage_dependent_args.build_android:
243256
platforms_to_skip_build.add(StdlibDeploymentTarget.Android)
244257
return platforms_to_skip_build
245258

246-
def __platforms_to_skip_test(self, args):
259+
def __platforms_to_skip_test(self, args, stage_dependent_args):
247260
platforms_to_skip_test = set()
248-
if not args.test_linux:
261+
if not stage_dependent_args.test_linux:
249262
platforms_to_skip_test.add(StdlibDeploymentTarget.Linux)
250-
if not args.test_freebsd:
263+
if not stage_dependent_args.test_freebsd:
251264
platforms_to_skip_test.add(StdlibDeploymentTarget.FreeBSD)
252-
if not args.test_cygwin:
265+
if not stage_dependent_args.test_cygwin:
253266
platforms_to_skip_test.add(StdlibDeploymentTarget.Cygwin)
254-
if not args.test_osx:
267+
if not stage_dependent_args.test_osx:
255268
platforms_to_skip_test.add(StdlibDeploymentTarget.OSX)
256-
if not args.test_ios_host and not args.only_non_executable_test:
269+
if not stage_dependent_args.test_ios_host and not args.only_non_executable_test:
257270
platforms_to_skip_test.add(StdlibDeploymentTarget.iOS)
258271
elif not args.only_non_executable_test:
259272
raise ArgumentError(None,
260273
"error: iOS device tests are not " +
261274
"supported in open-source Swift.")
262-
if not args.test_ios_simulator:
275+
if not stage_dependent_args.test_ios_simulator:
263276
platforms_to_skip_test.add(StdlibDeploymentTarget.iOSSimulator)
264-
if not args.test_tvos_host and not args.only_non_executable_test:
277+
if not stage_dependent_args.test_tvos_host and \
278+
not args.only_non_executable_test:
265279
platforms_to_skip_test.add(StdlibDeploymentTarget.AppleTV)
266280
elif not args.only_non_executable_test:
267281
raise ArgumentError(None,
268282
"error: tvOS device tests are not " +
269283
"supported in open-source Swift.")
270-
if not args.test_tvos_simulator:
284+
if not stage_dependent_args.test_tvos_simulator:
271285
platforms_to_skip_test.add(StdlibDeploymentTarget.AppleTVSimulator)
272-
if not args.test_watchos_host and not args.only_non_executable_test:
286+
if not stage_dependent_args.test_watchos_host and \
287+
not args.only_non_executable_test:
273288
platforms_to_skip_test.add(StdlibDeploymentTarget.AppleWatch)
274289
elif not args.only_non_executable_test:
275290
raise ArgumentError(None,
276291
"error: watchOS device tests are not " +
277292
"supported in open-source Swift.")
278-
if not args.test_watchos_simulator:
293+
if not stage_dependent_args.test_watchos_simulator:
279294
platforms_to_skip_test.add(
280295
StdlibDeploymentTarget.AppleWatchSimulator)
281-
if not args.test_android:
296+
if not stage_dependent_args.test_android:
282297
platforms_to_skip_test.add(StdlibDeploymentTarget.Android)
283298

284299
return platforms_to_skip_test
285300

286-
def __platforms_archs_to_skip_test(self, args, host_target):
301+
def __platforms_archs_to_skip_test(self, args, stage_dependent_args, host_target):
287302
platforms_archs_to_skip_test = set()
288-
if not args.test_ios_32bit_simulator:
303+
if not stage_dependent_args.test_ios_32bit_simulator:
289304
platforms_archs_to_skip_test.add(
290305
StdlibDeploymentTarget.iOSSimulator.i386)
291-
if not args.test_watchos_32bit_simulator:
306+
if not stage_dependent_args.test_watchos_32bit_simulator:
292307
platforms_archs_to_skip_test.add(
293308
StdlibDeploymentTarget.AppleWatchSimulator.i386)
294309
if host_target == StdlibDeploymentTarget.OSX.x86_64.name:
@@ -312,14 +327,17 @@ def __platforms_archs_to_skip_test(self, args, host_target):
312327

313328
return platforms_archs_to_skip_test
314329

315-
def __platforms_to_skip_test_host(self, args):
330+
def __platforms_to_skip_test_host(self, args, stage_dependent_args):
316331
platforms_to_skip_test_host = set()
317-
if not args.test_android_host:
332+
if not stage_dependent_args.test_android_host:
318333
platforms_to_skip_test_host.add(StdlibDeploymentTarget.Android)
319-
if not args.test_ios_host and not args.only_non_executable_test:
334+
if not stage_dependent_args.test_ios_host and \
335+
not args.only_non_executable_test:
320336
platforms_to_skip_test_host.add(StdlibDeploymentTarget.iOS)
321-
if not args.test_tvos_host and not args.only_non_executable_test:
337+
if not stage_dependent_args.test_tvos_host and \
338+
not args.only_non_executable_test:
322339
platforms_to_skip_test_host.add(StdlibDeploymentTarget.AppleTV)
323-
if not args.test_watchos_host and not args.only_non_executable_test:
340+
if not stage_dependent_args.test_watchos_host and \
341+
not args.only_non_executable_test:
324342
platforms_to_skip_test_host.add(StdlibDeploymentTarget.AppleWatch)
325343
return platforms_to_skip_test_host

utils/swift_build_support/swift_build_support/products/cmake_product.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,26 @@
1818

1919

2020
class CMakeProduct(product.Product):
21-
def build_with_cmake(self, build_targets, build_type, build_args):
21+
def is_verbose(self):
22+
return self.args.verbose_build
23+
24+
def build_with_cmake(self, build_targets, build_type, build_args,
25+
prefer_just_built_toolchain=False):
2226
assert self.toolchain.cmake is not None
2327
cmake_build = []
24-
_cmake = cmake.CMake(self.args, self.toolchain)
28+
_cmake = cmake.CMake(self.args, self.toolchain,
29+
prefer_just_built_toolchain)
2530

2631
if self.toolchain.distcc_pump:
2732
cmake_build.append(self.toolchain.distcc_pump)
2833
cmake_build.extend([self.toolchain.cmake, "--build"])
2934

35+
# If we are verbose...
36+
if self.is_verbose():
37+
# And ninja, add a -v.
38+
if self.args.cmake_generator == "Ninja":
39+
build_args.append('-v')
40+
3041
generator_output_path = ""
3142
if self.args.cmake_generator == "Ninja":
3243
generator_output_path = os.path.join(self.build_dir, "build.ninja")
@@ -52,7 +63,7 @@ def build_with_cmake(self, build_targets, build_type, build_args):
5263

5364
with shell.pushd(self.build_dir):
5465
shell.call([self.toolchain.cmake] + list(self.cmake_options) +
55-
list(_cmake.common_options()) +
66+
list(_cmake.common_options(self)) +
5667
self.args.extra_cmake_options + [self.source_dir],
5768
env=env)
5869

@@ -80,6 +91,13 @@ def test_with_cmake(self, executable_target, results_targets,
8091

8192
if self.toolchain.distcc_pump:
8293
cmake_build.append(self.toolchain.distcc_pump)
94+
95+
# If we are verbose...
96+
if self.is_verbose():
97+
# And ninja, add a -v.
98+
if self.args.cmake_generator == "Ninja":
99+
build_args.append('-v')
100+
83101
cmake_args = [self.toolchain.cmake, "--build", self.build_dir,
84102
"--config", build_type, "--"]
85103
cmake_build.extend(cmake_args + build_args)

0 commit comments

Comments
 (0)