|
20 | 20 |
|
21 | 21 | from . import shell
|
22 | 22 |
|
| 23 | +import re |
| 24 | +import os |
| 25 | +import platform |
| 26 | + |
23 | 27 |
|
24 | 28 | class CMakeOptions(object):
|
25 | 29 | """List like object used to define cmake options
|
@@ -177,3 +181,95 @@ def build_args(self):
|
177 | 181 | '-jobs', str(jobs)]
|
178 | 182 |
|
179 | 183 | 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