Skip to content

Commit 5d015dc

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-rebranch
2 parents 93b7608 + bebbcf4 commit 5d015dc

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

utils/build-script

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,13 @@ def main_normal():
10421042
if args.cmake is not None:
10431043
toolchain.cmake = args.cmake
10441044

1045+
cmake = CMake(args=args, toolchain=toolchain)
1046+
# Check the CMake version is sufficient on Linux and build from source if not.
1047+
cmake_path = cmake.check_cmake_version(SWIFT_SOURCE_ROOT, SWIFT_BUILD_ROOT)
1048+
if cmake_path is not None:
1049+
toolchain.cmake = cmake_path
1050+
args.cmake = cmake_path
1051+
10451052
# Preprocess the arguments to apply defaults.
10461053
BuildScriptInvocation.apply_default_arguments(toolchain, args)
10471054

utils/swift_build_support/swift_build_support/cmake.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
from . import shell
2222

23+
import re
24+
import os
25+
import platform
26+
2327

2428
class CMakeOptions(object):
2529
"""List like object used to define cmake options
@@ -177,3 +181,95 @@ def build_args(self):
177181
'-jobs', str(jobs)]
178182

179183
return build_args
184+
185+
# Determine the version of the installed CMake binary.
186+
def installed_cmake_version(self, cmake_binary):
187+
version = shell.capture([cmake_binary, '--version'], dry_run=False,
188+
echo=True, optional=True)
189+
(c_major, c_minor, c_patch) = (0, 0, 0)
190+
if version is not None:
191+
x = re.findall(r'cmake version (\d+)\.(\d+)\.(\d+)', version.rstrip())
192+
if len(x) == 1:
193+
(c_major, c_minor, c_patch) = map(int, x[0])
194+
195+
return (c_major, c_minor, c_patch)
196+
197+
# Determine the version of the checked out CMake source.
198+
def cmake_source_version(self, cmake_source_dir):
199+
cmake_version_file = os.path.join(cmake_source_dir, 'Source',
200+
'CMakeVersion.cmake')
201+
major = -1
202+
minor = -1
203+
patch = -1
204+
205+
file = open(cmake_version_file, "r")
206+
for line in file.readlines():
207+
m = re.findall(r'set\(CMake_VERSION_MAJOR (\d+)\)', line)
208+
if len(m) == 1:
209+
major = int(m[0])
210+
continue
211+
212+
m = re.findall(r'set\(CMake_VERSION_MINOR (\d+)\)', line)
213+
if len(m) == 1:
214+
minor = int(m[0])
215+
continue
216+
217+
m = re.findall(r'set\(CMake_VERSION_PATCH (\d+)\)', line)
218+
if len(m) == 1:
219+
patch = int(m[0])
220+
continue
221+
222+
if major == -1 or minor == -1 or patch == -1:
223+
raise RuntimeError("Cant determine CMake version from %s"
224+
% cmake_version_file)
225+
226+
return (major, minor, patch)
227+
228+
# Build CMake from source.
229+
def build_cmake(self, source_root, build_root):
230+
cmake_bootstrap = os.path.join(source_root, 'cmake', 'bootstrap')
231+
232+
if hasattr(self.args, 'build_script_impl_args'):
233+
for opt in self.args.build_script_impl_args:
234+
m = re.findall('--build-dir=(.*)', opt)
235+
if len(m) == 1:
236+
build_root = m[0]
237+
238+
cmake_build_dir = os.path.join(build_root, 'cmake-%s' % self.args.host_target)
239+
if not os.path.isdir(cmake_build_dir):
240+
os.makedirs(cmake_build_dir)
241+
242+
cwd = os.getcwd()
243+
os.chdir(cmake_build_dir)
244+
shell.call_without_sleeping([cmake_bootstrap], echo=True)
245+
shell.call_without_sleeping(['make', '-j%s' % self.args.build_jobs],
246+
echo=True)
247+
os.chdir(cwd)
248+
return os.path.join(cmake_build_dir, 'bin', 'cmake')
249+
250+
# For Linux only, determine the version of the installed CMake compared to the
251+
# source and build the source if necessary. Returns the path to the cmake binary.
252+
def check_cmake_version(self, source_root, build_root):
253+
if platform.system() != 'Linux':
254+
return
255+
256+
cmake_source_dir = os.path.join(source_root, 'cmake')
257+
# If the source is not checked out then don't attempt to build anything.
258+
if not os.path.isdir(cmake_source_dir):
259+
return
260+
261+
cmake_binary = 'cmake'
262+
try:
263+
if self.args.cmake is not None:
264+
cmake_binary = self.args.cmake
265+
except AttributeError:
266+
cmake_binary = 'cmake'
267+
268+
(i_major, i_minor, i_patch) = self.installed_cmake_version(cmake_binary)
269+
(s_major, s_minor, s_patch) = self.cmake_source_version(cmake_source_dir)
270+
if (i_major > s_major or (i_major == s_major and i_minor >= s_minor) or
271+
(i_major == s_major and i_minor == s_minor and i_patch >= s_patch)):
272+
return
273+
else:
274+
# Build CMake from source and return the path to the executable.
275+
return self.build_cmake(source_root, build_root)

0 commit comments

Comments
 (0)