Skip to content

Commit 90bf96c

Browse files
committed
[build-script] Don't rebuild CMake
This patch updates the CMake-building mechanism to avoid re-bootstrapping CMake if we already bootstrapped one that is new enough. I've made it so that all paths through the function return the path to a CMake so we can use the result of the function as the cmake path without having to check. The function will choose one of the following ways of getting CMake in order of preference: - One we already built - The system CMake - Bootstrapping one from scratch It prefers one we built over checking the system CMake because, if we have already built a CMake previously, it's a good indication that there either was no system CMake installed, or it wasn't new enough. We shouldn't waste time checking it again if a previous run detected that it wasn't good enough. The system CMake is preferable to building one from scratch if we don't need to though, so we determine if the system CMake is sufficient. Finally, if one that we built either doesn't exist, or isn't new enough, and the system either doesn't have a CMake, or a new enough CMake, build one. It is built into the location that we are checking for caching, so the next time we run build-script, it should hit the first case and choose the already-built CMake instead of building it again.
1 parent 71b7725 commit 90bf96c

File tree

2 files changed

+35
-28
lines changed

2 files changed

+35
-28
lines changed

utils/build-script

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -702,12 +702,9 @@ def main_normal():
702702
invocation = build_script_invocation.BuildScriptInvocation(toolchain, args)
703703

704704
cmake = CMake(args=args, toolchain=toolchain)
705-
# Check the CMake version is sufficient on Linux and build from source
706-
# if not.
707-
cmake_path = cmake.check_cmake_version(SWIFT_SOURCE_ROOT, SWIFT_BUILD_ROOT)
708-
if cmake_path is not None:
709-
toolchain.cmake = cmake_path
710-
args.cmake = cmake_path
705+
toolchain.cmake = cmake.get_cmake_path(source_root=SWIFT_SOURCE_ROOT,
706+
build_root=SWIFT_BUILD_ROOT)
707+
args.cmake = toolchain.cmake
711708

712709
# Validate the arguments.
713710
validate_arguments(toolchain, args)

utils/swift_build_support/swift_build_support/cmake.py

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -282,28 +282,38 @@ def build_cmake(self, source_root, build_root):
282282
os.chdir(cwd)
283283
return os.path.join(cmake_build_dir, 'bin', 'cmake')
284284

285-
# For Linux and FreeBSD only, determine the version of the installed
286-
# CMake compared to the source and build the source if necessary.
287-
# Returns the path to the cmake binary.
288-
def check_cmake_version(self, source_root, build_root):
289-
if not platform.system() in ["Linux", "FreeBSD"]:
290-
return
285+
# Get the path to CMake to use for the build
286+
# This function will not build CMake for Apple platforms.
287+
# For other platforms, this builds CMake if a new enough version is not
288+
# available.
289+
def get_cmake_path(self, source_root, build_root):
290+
if platform.system() == 'Darwin':
291+
return self.toolchain.cmake
291292

292293
cmake_source_dir = os.path.join(source_root, 'cmake')
293-
# If the source is not checked out then don't attempt to build cmake.
294294
if not os.path.isdir(cmake_source_dir):
295-
return
296-
297-
cmake_binary = 'cmake'
298-
try:
299-
if self.args.cmake is not None:
300-
cmake_binary = self.args.cmake
301-
except AttributeError:
302-
cmake_binary = 'cmake'
303-
304-
installed_ver = self.installed_cmake_version(cmake_binary)
305-
if installed_ver >= self.cmake_source_version(cmake_source_dir):
306-
return
307-
else:
308-
# Build CMake from source and return the path to the executable.
309-
return self.build_cmake(source_root, build_root)
295+
return self.toolchain.cmake
296+
297+
cmake_required_version = self.cmake_source_version(cmake_source_dir)
298+
299+
# If we have already built a CMake, see if that is new enough. If it is,
300+
# we don't need to build it again. This is a good indication that the
301+
# system either doesn't have a CMake installed or it wasn't new enough
302+
# so prefer our built CMake first.
303+
cmake_built_path = os.path.join(build_root,
304+
f'cmake-{self.args.host_target}',
305+
'bin', 'cmake')
306+
if os.path.isfile(cmake_built_path):
307+
cmake_built_version = self.installed_cmake_version(cmake_built_path)
308+
if cmake_built_version >= cmake_required_version:
309+
return cmake_built_path
310+
311+
# If we already have a new enough CMake installed on the system, use it
312+
if self.toolchain.cmake is not None:
313+
cmake_installed_version = self.installed_cmake_version(self.toolchain.cmake)
314+
if cmake_installed_version >= cmake_required_version:
315+
return self.toolchain.cmake
316+
317+
# The pre-installed CMake isn't new enough. Build one from our sources
318+
# and return the path to that.
319+
return self.build_cmake(source_root, build_root)

0 commit comments

Comments
 (0)