Skip to content

Commit 9402a16

Browse files
committed
Automatically choose a built ninja
Instead of using `--build-ninja` to decide to build ninja, build it automatically if a sufficiently new enough version is not available. Also record the build time taken to build the local Ninja so that we can see how much time we would save by stashing a pre-built Ninja in CI.
1 parent d2d5925 commit 9402a16

File tree

5 files changed

+55
-30
lines changed

5 files changed

+55
-30
lines changed

utils/build-script

-4
Original file line numberDiff line numberDiff line change
@@ -745,10 +745,6 @@ def main_normal():
745745
sys.stdout.write("Cleaning install destdir!\n")
746746
shell.rmtree(args.install_destdir)
747747

748-
# Build ninja if required, which will update the toolchain.
749-
if args.build_ninja:
750-
invocation.build_ninja()
751-
752748
# Execute the underlying build script implementation.
753749
invocation.execute()
754750

utils/build_swift/build_swift/driver_arguments.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ def create_argument_parser():
852852
help='install playground support')
853853

854854
option('--build-ninja', toggle_true,
855-
help='build the Ninja tool')
855+
help='build the Ninja tool [deprecated: Ninja is built when necessary]')
856856

857857
option(['--build-lld'], toggle_true('build_lld'), default=True,
858858
help='build lld as part of llvm')

utils/swift_build_support/swift_build_support/build_script_invocation.py

+6-15
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import HostSpecificConfiguration
3030
from swift_build_support.swift_build_support.productpipeline_list_builder \
3131
import ProductPipelineListBuilder
32+
from swift_build_support.swift_build_support.products.ninja \
33+
import get_ninja_path
3234
from swift_build_support.swift_build_support.targets \
3335
import StdlibDeploymentTarget
3436
from swift_build_support.swift_build_support.utils import clear_log_time
@@ -52,25 +54,14 @@ def __init__(self, toolchain, args):
5254

5355
clear_log_time()
5456

57+
self.toolchain.ninja = get_ninja_path(self.toolchain,
58+
self.args,
59+
self.workspace)
60+
5561
@property
5662
def install_all(self):
5763
return self.args.install_all or self.args.infer_dependencies
5864

59-
def build_ninja(self):
60-
if not os.path.exists(self.workspace.source_dir("ninja")):
61-
fatal_error(
62-
"can't find source directory for ninja "
63-
"(tried %s)" % (self.workspace.source_dir("ninja")))
64-
65-
ninja_build = products.Ninja.new_builder(
66-
args=self.args,
67-
toolchain=self.toolchain,
68-
workspace=self.workspace,
69-
host=StdlibDeploymentTarget.get_target_for_name(
70-
self.args.host_target))
71-
ninja_build.build()
72-
self.toolchain.ninja = ninja_build.ninja_bin_path
73-
7465
def convert_to_impl_arguments(self):
7566
"""convert_to_impl_arguments() -> (env, args)
7667

utils/swift_build_support/swift_build_support/products/ninja.py

+47-9
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
# ----------------------------------------------------------------------------
1616

1717
import os.path
18+
import re
1819

1920
from build_swift.build_swift import cache_utils
2021

2122
from . import product
2223
from .. import shell
24+
from ..utils import log_time_in_scope
2325

2426

2527
class Ninja(product.Product):
@@ -52,12 +54,48 @@ def ninja_bin_path(self):
5254
def build(self):
5355
if os.path.exists(self.ninja_bin_path):
5456
return
55-
shell.call([
56-
self.toolchain.cmake,
57-
"-S", self.source_dir,
58-
"-B", self.build_dir,
59-
"-DCMAKE_BUILD_TYPE=Release",
60-
"-DBUILD_TESTING=OFF",
61-
f"-DCMAKE_C_COMPILER={self.toolchain.cc}",
62-
f"-DCMAKE_CXX_COMPILER={self.toolchain.cxx}"])
63-
shell.call([self.toolchain.cmake, "--build", self.build_dir])
57+
58+
print("--- Local Ninja Build ---")
59+
with log_time_in_scope('local ninja'):
60+
shell.call([
61+
self.toolchain.cmake,
62+
"-S", self.source_dir,
63+
"-B", self.build_dir,
64+
"-DCMAKE_BUILD_TYPE=Release",
65+
"-DBUILD_TESTING=OFF",
66+
f"-DCMAKE_C_COMPILER={self.toolchain.cc}",
67+
f"-DCMAKE_CXX_COMPILER={self.toolchain.cxx}"])
68+
shell.call([self.toolchain.cmake, "--build", self.build_dir])
69+
70+
71+
def get_ninja_version(ninja_bin_path):
72+
if not ninja_bin_path or not os.path.isfile(ninja_bin_path):
73+
return
74+
ninja_version_pattern = re.compile(r'^(\d+)\.(\d+)\.(\d+).*')
75+
version = shell.capture([ninja_bin_path, "--version"], dry_run=False,
76+
echo=True, optional=True)
77+
m = ninja_version_pattern.match(version)
78+
if m is None:
79+
return
80+
(major, minor, patch) = map(int, m.groups())
81+
return (major, minor, patch)
82+
83+
84+
def get_ninja_path(toolchain, args, workspace):
85+
min_ninja_version = (1, 8, 2)
86+
87+
built_ninja_path = os.path.join(workspace.build_dir('build', 'ninja'), 'ninja')
88+
built_ninja_version = get_ninja_version(built_ninja_path)
89+
if built_ninja_version and min_ninja_version <= built_ninja_version:
90+
return built_ninja_path
91+
92+
toolchain_ninja_version = get_ninja_version(toolchain.ninja)
93+
if toolchain_ninja_version and min_ninja_version <= toolchain_ninja_version:
94+
return toolchain.ninja
95+
96+
# Build ninja from source
97+
ninja_build = Ninja.new_builder(args=args,
98+
toolchain=toolchain,
99+
workspace=workspace)
100+
ninja_build.build()
101+
return ninja_build.ninja_bin_path

utils/swift_build_support/tests/products/test_ninja.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def setUp(self):
4545

4646
# Setup args
4747
self.args = argparse.Namespace(
48-
build_ninja=True,
4948
darwin_deployment_version_osx="10.9")
5049

5150
# Setup shell
@@ -89,6 +88,7 @@ def test_build(self):
8988
ninja_build.build()
9089

9190
self.assertEqual(self.stdout.getvalue(), f"""\
91+
--- Local Ninja Build ---
9292
+ {self.toolchain.cmake} \
9393
-S {self.workspace.source_dir('ninja')} \
9494
-B {self.workspace.build_dir('build', 'ninja')} \

0 commit comments

Comments
 (0)