|
16 | 16 |
|
17 | 17 | from __future__ import absolute_import
|
18 | 18 |
|
| 19 | +import os |
| 20 | +import platform |
| 21 | +import re |
19 | 22 | from numbers import Number
|
20 | 23 |
|
21 | 24 | from . import shell
|
@@ -177,3 +180,96 @@ def build_args(self):
|
177 | 180 | '-jobs', str(jobs)]
|
178 | 181 |
|
179 | 182 | return build_args
|
| 183 | + |
| 184 | + # Determine the version of the installed CMake binary. |
| 185 | + def installed_cmake_version(self, cmake_binary): |
| 186 | + version = shell.capture([cmake_binary, '--version'], dry_run=False, |
| 187 | + echo=True, optional=True) |
| 188 | + (c_major, c_minor, c_patch) = (0, 0, 0) |
| 189 | + if version is not None: |
| 190 | + x = re.findall(r'cmake version (\d+)\.(\d+)\.(\d+)', |
| 191 | + 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' % |
| 239 | + self.args.host_target) |
| 240 | + if not os.path.isdir(cmake_build_dir): |
| 241 | + os.makedirs(cmake_build_dir) |
| 242 | + |
| 243 | + cwd = os.getcwd() |
| 244 | + os.chdir(cmake_build_dir) |
| 245 | + shell.call_without_sleeping([cmake_bootstrap], echo=True) |
| 246 | + shell.call_without_sleeping(['make', '-j%s' % self.args.build_jobs], |
| 247 | + echo=True) |
| 248 | + os.chdir(cwd) |
| 249 | + return os.path.join(cmake_build_dir, 'bin', 'cmake') |
| 250 | + |
| 251 | + # For Linux only, determine the version of the installed CMake compared to |
| 252 | + # the source and build the source if necessary. Returns the path to the |
| 253 | + # cmake binary. |
| 254 | + def check_cmake_version(self, source_root, build_root): |
| 255 | + if platform.system() != 'Linux': |
| 256 | + return |
| 257 | + |
| 258 | + cmake_source_dir = os.path.join(source_root, 'cmake') |
| 259 | + # If the source is not checked out then don't attempt to build cmake. |
| 260 | + if not os.path.isdir(cmake_source_dir): |
| 261 | + return |
| 262 | + |
| 263 | + cmake_binary = 'cmake' |
| 264 | + try: |
| 265 | + if self.args.cmake is not None: |
| 266 | + cmake_binary = self.args.cmake |
| 267 | + except AttributeError: |
| 268 | + cmake_binary = 'cmake' |
| 269 | + |
| 270 | + installed_ver = self.installed_cmake_version(cmake_binary) |
| 271 | + if installed_ver > self.cmake_source_version(cmake_source_dir): |
| 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