Skip to content

Commit 354f6ea

Browse files
committed
Merge pull request #2352 from rintaro/build-script-refactor-toolchain
2 parents 16ec49d + bcbdc56 commit 354f6ea

File tree

13 files changed

+506
-288
lines changed

13 files changed

+506
-288
lines changed

utils/build-script

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@ from SwiftBuildSupport import (
4242
sys.path.append(os.path.join(os.path.dirname(__file__), 'swift_build_support'))
4343

4444
# E402 means module level import not at top of file
45-
import swift_build_support.toolchain # noqa (E402)
46-
import swift_build_support.cmake # noqa (E402)
45+
from swift_build_support.toolchain import host_toolchain # noqa (E402)
4746
import swift_build_support.debug # noqa (E402)
4847
from swift_build_support import migration # noqa (E402)
49-
import swift_build_support.ninja # noqa (E402)
5048
import swift_build_support.tar # noqa (E402)
5149
import swift_build_support.targets # noqa (E402)
5250
from swift_build_support.cmake import CMake # noqa (E402)
@@ -87,6 +85,15 @@ def argparse_clang_compiler_version(string):
8785
"%r is invalid version value. must be 'MAJOR.MINOR.PATCH'" % string)
8886

8987

88+
# Check the string is executable path string.
89+
# Convert it to absolute path.
90+
def argparse_executable(string):
91+
if os.access(string, os.X_OK):
92+
return os.path.abspath(string)
93+
raise argparse.ArgumentTypeError(
94+
"%r is not execuable" % string)
95+
96+
9097
# Main entry point for the preset mode.
9198
def main_preset():
9299
parser = argparse.ArgumentParser(
@@ -773,7 +780,9 @@ details of the setups of other systems or automated environments.""")
773780
parser.add_argument(
774781
"--cmake",
775782
help="the path to a CMake executable that will be used to build "
776-
"Swift")
783+
"Swift",
784+
type=argparse_executable,
785+
metavar="PATH")
777786
parser.add_argument(
778787
"--show-sdks",
779788
help="print installed Xcode and SDK versions",
@@ -828,11 +837,13 @@ details of the setups of other systems or automated environments.""")
828837
"--host-cc",
829838
help="the absolute path to CC, the 'clang' compiler for the host "
830839
"platform. Default is auto detected.",
840+
type=argparse_executable,
831841
metavar="PATH")
832842
parser.add_argument(
833843
"--host-cxx",
834844
help="the absolute path to CXX, the 'clang++' compiler for the host "
835845
"platform. Default is auto detected.",
846+
type=argparse_executable,
836847
metavar="PATH")
837848
parser.add_argument(
838849
"--distcc",
@@ -897,6 +908,35 @@ details of the setups of other systems or automated environments.""")
897908
if '--check-args-only' in args.build_script_impl_args:
898909
return 0
899910

911+
# Prepare and validate toolchain
912+
toolchain = host_toolchain(xcrun_toolchain=args.darwin_xcrun_toolchain)
913+
914+
if args.host_cc is not None:
915+
toolchain.cc = args.host_cc
916+
if args.host_cxx is not None:
917+
toolchain.cxx = args.host_cxx
918+
if args.cmake is not None:
919+
toolchain.cmake = args.cmake
920+
921+
if toolchain.cc is None or toolchain.cxx is None:
922+
print_with_argv0(
923+
"Can't find clang. Please install clang-3.5 or a later version.")
924+
return 1
925+
926+
if toolchain.cmake is None:
927+
print_with_argv0("Can't find CMake. Please install CMake.")
928+
return 1
929+
930+
if args.distcc:
931+
if toolchain.distcc is None:
932+
print_with_argv0(
933+
"Can't find distcc. Please install distcc")
934+
return 1
935+
if toolchain.distcc_pump is None:
936+
print_with_argv0(
937+
"Can't find distcc-pump. Please install distcc-pump")
938+
return 1
939+
900940
if args.host_target is None or args.stdlib_deployment_targets is None:
901941
print_with_argv0("Unknown operating system.")
902942
return 1
@@ -1221,61 +1261,19 @@ details of the setups of other systems or automated environments.""")
12211261
if args.clean and os.path.isdir(build_dir):
12221262
shutil.rmtree(build_dir)
12231263

1224-
host_clang = swift_build_support.toolchain.host_clang(
1225-
xcrun_toolchain=args.darwin_xcrun_toolchain)
1226-
if args.host_cc is None and host_clang is not None:
1227-
args.host_cc = str(host_clang.cc)
1228-
if args.host_cxx is None and host_clang is not None:
1229-
args.host_cxx = str(host_clang.cxx)
1230-
is_host_clang_ok = (
1231-
args.host_cc is not None and os.access(args.host_cc, os.X_OK) and
1232-
args.host_cxx is not None and os.access(args.host_cxx, os.X_OK))
1233-
if not is_host_clang_ok:
1234-
print_with_argv0(
1235-
"Can't find clang. Please install clang-3.5 or a later version.")
1236-
return 1
1237-
1238-
host_cmake = args.cmake
1239-
if not host_cmake:
1240-
host_cmake = swift_build_support.cmake.host_cmake(
1241-
args.darwin_xcrun_toolchain)
1242-
if not host_cmake:
1243-
print_with_argv0("Can't find CMake. Please install CMake.")
1244-
return 1
1245-
1246-
# distcc usage.
1247-
host_distcc = None
1248-
host_distcc_pump = None
1249-
if args.distcc:
1250-
host_distcc = swift_build_support.which('distcc')
1251-
# On some platforms, 'pump' may be unrelated to distcc, in which case
1252-
# it's called 'distcc-pump'.
1253-
host_distcc_pump = swift_build_support.which('distcc-pump')
1254-
if host_distcc_pump is None:
1255-
host_distcc_pump = swift_build_support.which('pump')
1256-
1257-
if host_distcc is None or host_distcc_pump is None:
1258-
print_with_argv0(
1259-
"Can't find distcc. Please install distcc")
1260-
1261-
host_distcc = str(host_distcc)
1262-
host_distcc_pump = str(host_distcc_pump)
1263-
12641264
cmake = CMake(args=args,
1265-
host_cc=args.host_cc,
1266-
host_cxx=args.host_cxx,
1267-
host_distcc=host_distcc)
1265+
toolchain=toolchain)
12681266

12691267
build_script_impl_args = [
12701268
"--build-dir", build_dir,
12711269
"--install-prefix", os.path.abspath(args.install_prefix),
12721270
"--host-target", args.host_target,
12731271
"--stdlib-deployment-targets",
12741272
" ".join(args.stdlib_deployment_targets),
1275-
"--host-cc", args.host_cc,
1276-
"--host-cxx", args.host_cxx,
1273+
"--host-cc", toolchain.cc,
1274+
"--host-cxx", toolchain.cxx,
12771275
"--darwin-xcrun-toolchain", args.darwin_xcrun_toolchain,
1278-
"--cmake", host_cmake,
1276+
"--cmake", toolchain.cmake,
12791277
"--cmark-build-type", args.cmark_build_variant,
12801278
"--llvm-build-type", args.llvm_build_variant,
12811279
"--swift-build-type", args.swift_build_variant,
@@ -1299,7 +1297,7 @@ details of the setups of other systems or automated environments.""")
12991297
if args.distcc:
13001298
build_script_impl_args += [
13011299
"--distcc",
1302-
"--distcc-pump=%s" % host_distcc_pump
1300+
"--distcc-pump=%s" % toolchain.distcc_pump
13031301
]
13041302
if args.enable_asan:
13051303
build_script_impl_args += ["--enable-asan"]
@@ -1319,8 +1317,7 @@ details of the setups of other systems or automated environments.""")
13191317
build_script_impl_args += [
13201318
"--foundation-build-type", args.foundation_build_variant
13211319
]
1322-
if args.cmake_generator == 'Ninja' and \
1323-
not swift_build_support.ninja.is_ninja_installed():
1320+
if args.cmake_generator == 'Ninja' and toolchain.ninja is None:
13241321
build_script_impl_args += ["--build-ninja"]
13251322

13261323
if args.skip_build_linux:

utils/profdata_merge/process.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
sys.path.append(parent_dir)
2525
support_dir = os.path.join(parent_dir, 'swift_build_support')
2626
sys.path.append(support_dir)
27-
from swift_build_support import xcrun # noqa (E402)
27+
from swift_build_support.toolchain import host_toolchain # noqa (E402)
2828
from SwiftBuildSupport import check_output, check_call # noqa (E402)
2929

30-
# FIXME: This doesn't work on non-Darwin platforms.
31-
LLVM_PROFDATA_PATH = xcrun.find('default', 'llvm-profdata')
30+
toolchain = host_toolchain()
31+
LLVM_PROFDATA_PATH = toolchain.llvm_profdata
3232
_profdata_help = check_output([LLVM_PROFDATA_PATH, 'merge', '-help'])
3333
LLVM_PROFDATA_SUPPORTS_SPARSE = 'sparse' in _profdata_help
3434

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# swift_build_support/cache_util.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+
Cache related utilities
14+
"""
15+
# ----------------------------------------------------------------------------
16+
17+
from functools import update_wrapper
18+
19+
__all__ = [
20+
'cached',
21+
'reify'
22+
]
23+
24+
25+
def cached(func):
26+
"""Decorator that caches result of method or function.
27+
28+
Note: Support method or function.
29+
"""
30+
cache = {}
31+
32+
def wrapper(*args, **kwargs):
33+
key = tuple(args) + tuple(kwargs.items())
34+
if key not in cache:
35+
result = func(*args, **kwargs)
36+
cache[key] = result
37+
return result
38+
else:
39+
return cache[key]
40+
41+
return update_wrapper(wrapper, func)
42+
43+
44+
def reify(func):
45+
"""Decorator that replaces the wrapped method with the result after the
46+
first call.
47+
48+
Note: Support method that takes no arguments.
49+
"""
50+
class wrapper(object):
51+
def __get__(self, obj, objtype=None):
52+
if obj is None:
53+
return self
54+
result = func(obj)
55+
setattr(obj, func.__name__, result)
56+
return result
57+
58+
return update_wrapper(wrapper(), func)

utils/swift_build_support/swift_build_support/cmake.py

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,10 @@
1414
#
1515
# ----------------------------------------------------------------------------
1616

17-
import platform
1817
import subprocess
1918

2019
from numbers import Number
2120

22-
from . import xcrun
23-
from .which import which
24-
25-
26-
def host_cmake(xcrun_toolchain):
27-
"""
28-
Return the path to `cmake`, using tools provided by the host platform.
29-
If `cmake` cannot be found on OS X, return None.
30-
If `cmake` cannot be found on Linux, return a probable path.
31-
"""
32-
if platform.system() == 'Darwin':
33-
return xcrun.find(xcrun_toolchain, 'cmake')
34-
else:
35-
cmake = which('cmake')
36-
if cmake:
37-
return cmake
38-
else:
39-
return '/usr/local/bin/cmake'
40-
4121

4222
class CMakeOptions(object):
4323
"""List like object used to define cmake options
@@ -89,16 +69,15 @@ def __iadd__(self, other):
8969

9070
class CMake(object):
9171

92-
def __init__(self, args, host_cc, host_cxx, host_distcc):
72+
def __init__(self, args, toolchain):
9373
self.args = args
94-
self.host_cc = host_cc
95-
self.host_cxx = host_cxx
96-
self.host_distcc = host_distcc
74+
self.toolchain = toolchain
9775

9876
def common_options(self):
9977
"""Return options used for all products, including LLVM/Clang
10078
"""
10179
args = self.args
80+
toolchain = self.toolchain
10281
options = CMakeOptions()
10382
define = options.define
10483

@@ -116,13 +95,13 @@ def common_options(self):
11695
define("CMAKE_EXPORT_COMPILE_COMMANDS", "ON")
11796

11897
if args.distcc:
119-
define("CMAKE_C_COMPILER:PATH", self.host_distcc)
120-
define("CMAKE_C_COMPILER_ARG1", self.host_cc)
121-
define("CMAKE_CXX_COMPILER:PATH", self.host_distcc)
122-
define("CMAKE_CXX_COMPILER_ARG1", self.host_cxx)
98+
define("CMAKE_C_COMPILER:PATH", toolchain.distcc)
99+
define("CMAKE_C_COMPILER_ARG1", toolchain.cc)
100+
define("CMAKE_CXX_COMPILER:PATH", toolchain.distcc)
101+
define("CMAKE_CXX_COMPILER_ARG1", toolchain.cxx)
123102
else:
124-
define("CMAKE_C_COMPILER:PATH", self.host_cc)
125-
define("CMAKE_CXX_COMPILER:PATH", self.host_cxx)
103+
define("CMAKE_C_COMPILER:PATH", toolchain.cc)
104+
define("CMAKE_CXX_COMPILER:PATH", toolchain.cxx)
126105

127106
if args.cmake_generator == 'Xcode':
128107
define("CMAKE_CONFIGURATION_TYPES",
@@ -140,10 +119,11 @@ def build_args(self):
140119
"""Return arguments to the build tool used for all products
141120
"""
142121
args = self.args
122+
toolchain = self.toolchain
143123
jobs = args.build_jobs
144124
if args.distcc:
145-
jobs = str(
146-
subprocess.check_output([self.host_distcc, '-j'])).rstrip()
125+
jobs = str(subprocess.check_output(
126+
[toolchain.distcc, '-j']).decode()).rstrip()
147127

148128
build_args = list(args.build_args)
149129

utils/swift_build_support/swift_build_support/ninja.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)