blob: 61a0feb90930bc949a964eb7c5bb63840d1f0013 [file] [log] [blame]
Ahmad Sharif4467f002012-12-20 12:09:49 -08001#!/usr/bin/python
Yunlian Jiangb0a02f42013-08-22 09:55:54 -07002
3# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
Ahmad Shariffd356fb2012-05-07 12:02:16 -07006
7"""Utilities for toolchain build."""
8
9__author__ = "asharif@google.com (Ahmad Sharif)"
10
Ahmad Shariff395c262012-10-09 17:48:09 -070011from contextlib import contextmanager
Ahmad Shariffd356fb2012-05-07 12:02:16 -070012import os
13import re
Ahmad Sharif4467f002012-12-20 12:09:49 -080014import shutil
15import sys
16import time
17
18import lock_machine
Ahmad Shariff395c262012-10-09 17:48:09 -070019
Ahmad Shariffd356fb2012-05-07 12:02:16 -070020import command_executer
21import logger
Ahmad Shariff395c262012-10-09 17:48:09 -070022
23
24def GetChromeOSVersionFromLSBVersion(lsb_version):
Ahmad Sharif4467f002012-12-20 12:09:49 -080025 """Get Chromeos version from Lsb version."""
Ahmad Shariff395c262012-10-09 17:48:09 -070026 ce = command_executer.GetCommandExecuter()
Luis Lozano6aebeb12013-09-03 01:55:02 -070027 command = ("git ls-remote "
Luis Lozano6aae4c92013-09-10 00:00:27 -070028 "https://chromium.googlesource.com/chromiumos/manifest.git")
Ahmad Shariff395c262012-10-09 17:48:09 -070029 ret, out, _ = ce.RunCommand(command, return_output=True,
30 print_to_console=False)
31 assert ret == 0, "Command %s failed" % command
32 lower = []
33 for line in out.splitlines():
Ahmad Sharif4467f002012-12-20 12:09:49 -080034 mo = re.search(r"refs/heads/release-R(\d+)-(\d+)\.B", line)
Ahmad Shariff395c262012-10-09 17:48:09 -070035 if mo:
36 revision = int(mo.group(1))
37 build = int(mo.group(2))
38 lsb_build = int(lsb_version.split(".")[0])
39 if lsb_build > build:
40 lower.append(revision)
41 lower = sorted(lower)
42 if lower:
43 return "R%d-%s" % (lower[-1] + 1, lsb_version)
44 else:
45 return "Unknown"
Ahmad Shariffd356fb2012-05-07 12:02:16 -070046
47
48def ApplySubs(string, *substitutions):
49 for pattern, replacement in substitutions:
50 string = re.sub(pattern, replacement, string)
51 return string
52
53
Ahmad Sharif4467f002012-12-20 12:09:49 -080054def UnitToNumber(unit_num, base=1000):
55 """Convert a number with unit to float."""
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070056 unit_dict = {"kilo": base,
57 "mega": base**2,
58 "giga": base**3}
Ahmad Sharif4467f002012-12-20 12:09:49 -080059 unit_num = unit_num.lower()
60 mo = re.search(r"(\d*)(.+)?", unit_num)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070061 number = mo.group(1)
62 unit = mo.group(2)
Ahmad Shariff395c262012-10-09 17:48:09 -070063 if not unit:
64 return float(number)
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070065 for k, v in unit_dict.items():
66 if k.startswith(unit):
67 return float(number) * v
68 raise Exception("Unit: %s not found in byte: %s!" %
69 (unit,
Ahmad Sharif4467f002012-12-20 12:09:49 -080070 unit_num))
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070071
72
Ahmad Shariffd356fb2012-05-07 12:02:16 -070073def GetFilenameFromString(string):
74 return ApplySubs(string,
Ahmad Sharif4467f002012-12-20 12:09:49 -080075 (r"/", "__"),
76 (r"\s", "_"),
77 (r"[\^\$=\"\\\?]", ""),
78 )
Ahmad Shariffd356fb2012-05-07 12:02:16 -070079
80
81def GetRoot(scr_name):
82 """Break up pathname into (dir+name)."""
83 abs_path = os.path.abspath(scr_name)
84 return (os.path.dirname(abs_path), os.path.basename(abs_path))
85
86
Ahmad Sharif4467f002012-12-20 12:09:49 -080087def GetChromeOSKeyFile(chromeos_root):
88 return os.path.join(chromeos_root,
89 "src",
90 "scripts",
91 "mod_for_test_scripts",
92 "ssh_keys",
93 "testing_rsa")
94
95
Ahmad Sharif5ae8a5c2012-05-18 10:59:51 -070096def GetChrootPath(chromeos_root):
97 return os.path.join(chromeos_root,
98 "chroot")
99
100
101def GetInsideChrootPath(chromeos_root, file_path):
102 if not file_path.startswith(GetChrootPath(chromeos_root)):
103 raise Exception("File: %s doesn't seem to be in the chroot: %s" %
104 (file_path,
105 chromeos_root))
106 return file_path[len(GetChrootPath(chromeos_root)):]
107
108
109def GetOutsideChrootPath(chromeos_root, file_path):
110 return os.path.join(GetChrootPath(chromeos_root),
111 file_path.lstrip("/"))
112
113
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700114def FormatQuotedCommand(command):
115 return ApplySubs(command,
116 ("\"", "\\\""))
117
118
119def FormatCommands(commands):
120 return ApplySubs(str(commands),
121 ("&&", "&&\n"),
122 (";", ";\n"),
Ahmad Sharif4467f002012-12-20 12:09:49 -0800123 (r"\n+\s*", "\n"))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700124
125
126def GetImageDir(chromeos_root, board):
127 return os.path.join(chromeos_root,
128 "src",
129 "build",
130 "images",
131 board)
132
133
134def LabelLatestImage(chromeos_root, board, label):
135 image_dir = GetImageDir(chromeos_root, board)
136 latest_image_dir = os.path.join(image_dir, "latest")
137 latest_image_dir = os.path.realpath(latest_image_dir)
138 latest_image_dir = os.path.basename(latest_image_dir)
139 with WorkingDirectory(image_dir):
140 command = "ln -sf -T %s %s" % (latest_image_dir, label)
141 ce = command_executer.GetCommandExecuter()
142 return ce.RunCommand(command)
143
144
145def DoesLabelExist(chromeos_root, board, label):
146 image_label = os.path.join(GetImageDir(chromeos_root, board),
147 label)
148 return os.path.exists(image_label)
149
150
Luis Lozanof81680c2013-03-15 14:44:13 -0700151def GetBuildPackagesCommand(board, usepkg=False, debug=False):
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700152 if usepkg:
153 usepkg_flag = "--usepkg"
154 else:
155 usepkg_flag = "--nousepkg"
Luis Lozanof81680c2013-03-15 14:44:13 -0700156 if debug:
157 withdebug_flag = '--withdebug'
158 else:
159 withdebug_flag = '--nowithdebug'
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700160 return ("./build_packages %s --withdev --withtest --withautotest "
Yunlian Jiangb0a02f42013-08-22 09:55:54 -0700161 "--skip_toolchain_update %s --board=%s "
162 "--accept_licenses=@CHROMEOS" %
Luis Lozanof81680c2013-03-15 14:44:13 -0700163 (usepkg_flag, withdebug_flag, board))
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700164
165
Luis Lozanof81680c2013-03-15 14:44:13 -0700166def GetBuildImageCommand(board, dev=False):
167 dev_args = ""
168 if dev:
169 dev_args = "--noenable_rootfs_verification --disk_layout=2gb-rootfs"
170 return "./build_image --board=%s %s test" % (board, dev_args)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700171
172def GetSetupBoardCommand(board, gcc_version=None, binutils_version=None,
173 usepkg=None, force=None):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800174 """Get setup_board command."""
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700175 options = []
176
177 if gcc_version:
178 options.append("--gcc_version=%s" % gcc_version)
179
180 if binutils_version:
181 options.append("--binutils_version=%s" % binutils_version)
182
183 if usepkg:
184 options.append("--usepkg")
185 else:
186 options.append("--nousepkg")
187
188 if force:
189 options.append("--force")
190
Yunlian Jiangb0a02f42013-08-22 09:55:54 -0700191 options.append("--accept_licenses=@CHROMEOS")
192
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700193 return "./setup_board --board=%s %s" % (board, " ".join(options))
194
195
196def CanonicalizePath(path):
197 path = os.path.expanduser(path)
198 path = os.path.realpath(path)
199 return path
200
201
202def GetCtargetFromBoard(board, chromeos_root):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800203 """Get Ctarget from board."""
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700204 base_board = board.split("_")[0]
205 command = ("source "
206 "../platform/dev/toolchain_utils.sh; get_ctarget_from_board %s" %
207 base_board)
208 ce = command_executer.GetCommandExecuter()
Ahmad Shariff395c262012-10-09 17:48:09 -0700209 ret, out, _ = ce.ChrootRunCommand(chromeos_root,
210 command,
211 return_output=True)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700212 if ret != 0:
213 raise ValueError("Board %s is invalid!" % board)
Ahmad Shariff395c262012-10-09 17:48:09 -0700214 # Remove ANSI escape sequences.
215 out = StripANSIEscapeSequences(out)
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700216 return out.strip()
217
218
Ahmad Shariff395c262012-10-09 17:48:09 -0700219def StripANSIEscapeSequences(string):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800220 string = re.sub(r"\x1b\[[0-9]*[a-zA-Z]", "", string)
Ahmad Shariff395c262012-10-09 17:48:09 -0700221 return string
222
223
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700224def GetChromeSrcDir():
225 return "var/cache/distfiles/target/chrome-src/src"
226
227
228def GetEnvStringFromDict(env_dict):
229 return " ".join(["%s=\"%s\"" % var for var in env_dict.items()])
230
231
Ahmad Shariff395c262012-10-09 17:48:09 -0700232def MergeEnvStringWithDict(env_string, env_dict, prepend=True):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800233 """Merge env string with dict."""
Ahmad Shariff395c262012-10-09 17:48:09 -0700234 if not env_string.strip():
235 return GetEnvStringFromDict(env_dict)
236 override_env_list = []
237 ce = command_executer.GetCommandExecuter()
238 for k, v in env_dict.items():
239 v = v.strip("\"'")
240 if prepend:
241 new_env = "%s=\"%s $%s\"" % (k, v, k)
242 else:
243 new_env = "%s=\"$%s %s\"" % (k, k, v)
244 command = "; ".join([env_string, new_env, "echo $%s" % k])
245 ret, out, _ = ce.RunCommand(command, return_output=True)
246 override_env_list.append("%s=%r" % (k, out.strip()))
247 ret = env_string + " " + " ".join(override_env_list)
248 return ret.strip()
249
250
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700251def GetAllImages(chromeos_root, board):
252 ce = command_executer.GetCommandExecuter()
253 command = ("find %s/src/build/images/%s -name chromiumos_test_image.bin" %
254 (chromeos_root, board))
Ahmad Shariff395c262012-10-09 17:48:09 -0700255 ret, out, _ = ce.RunCommand(command, return_output=True)
256 assert ret == 0, "Could not run command: %s" % command
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700257 return out.splitlines()
258
259
Ahmad Sharif4467f002012-12-20 12:09:49 -0800260def AcquireLock(lock_file, timeout=1200):
261 """Acquire a lock with timeout."""
262 start_time = time.time()
263 locked = False
264 abs_path = os.path.abspath(lock_file)
265 dir_path = os.path.dirname(abs_path)
266 sleep_time = min(10, timeout/10.0)
Luis Lozanof81680c2013-03-15 14:44:13 -0700267 reason = "pid: {0}, commad: {1}".format(os.getpid(),
268 sys.argv[0])
Ahmad Sharif4467f002012-12-20 12:09:49 -0800269 if not os.path.exists(dir_path):
270 try:
Luis Lozanof81680c2013-03-15 14:44:13 -0700271 with lock_machine.FileCreationMask(0002):
272 os.makedirs(dir_path)
Ahmad Sharif4467f002012-12-20 12:09:49 -0800273 except OSError:
274 print "Cannot create dir {0}, exiting...".format(dir_path)
275 exit(0)
276 while True:
Luis Lozanof81680c2013-03-15 14:44:13 -0700277 locked = (lock_machine.Lock(lock_file).NonBlockingLock(True, reason))
Ahmad Sharif4467f002012-12-20 12:09:49 -0800278 if locked:
279 break
280 time.sleep(sleep_time)
281 if time.time() - start_time > timeout:
282 logger.GetLogger().LogWarning(
283 "Could not acquire lock on this file: {0} within {1} seconds."
284 "Manually remove the file if you think the lock is stale"
285 .format(abs_path, timeout))
286 break
287 return locked
288
289
290def ReleaseLock(lock_file):
291 lock_file = os.path.abspath(lock_file)
292 ret = lock_machine.Lock(lock_file).Unlock(True)
293 assert ret, ("Could not unlock {0},"
294 "Please remove it manually".format(lock_file))
295
296
297def IsFloat(text):
298 if text is None:
299 return False
300 try:
301 float(text)
302 return True
303 except ValueError:
304 return False
305
306def RemoveChromeBrowserObjectFiles(chromeos_root, board):
307 """ Remove any object files from all the posible locations """
308 out_dir = os.path.join(
309 GetChrootPath(chromeos_root),
310 "var/cache/chromeos-chrome/chrome-src/src/out_%s" % board)
311 if os.path.exists(out_dir):
312 shutil.rmtree(out_dir)
313 logger.GetLogger().LogCmd("rm -rf %s" % out_dir)
314 out_dir = os.path.join(
315 GetChrootPath(chromeos_root),
316 "var/cache/chromeos-chrome/chrome-src-internal/src/out_%s" % board)
317 if os.path.exists(out_dir):
318 shutil.rmtree(out_dir)
319 logger.GetLogger().LogCmd("rm -rf %s" % out_dir)
320
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700321@contextmanager
322def WorkingDirectory(new_dir):
Ahmad Sharif4467f002012-12-20 12:09:49 -0800323 """Get the working directory."""
Ahmad Shariffd356fb2012-05-07 12:02:16 -0700324 old_dir = os.getcwd()
325 if old_dir != new_dir:
326 msg = "cd %s" % new_dir
327 logger.GetLogger().LogCmd(msg)
328 os.chdir(new_dir)
329 yield new_dir
330 if old_dir != new_dir:
331 msg = "cd %s" % old_dir
332 logger.GetLogger().LogCmd(msg)
333 os.chdir(old_dir)
Han Shen91445322013-03-20 13:43:31 -0700334
335def HasGitStagedChanges(git_dir):
336 """Return True if git repository has staged changes."""
337 command = 'cd {0} && git diff --quiet --cached --exit-code HEAD'.format(
338 git_dir)
339 return command_executer.GetCommandExecuter().RunCommand(
340 command, print_to_console=False)
341
342def HasGitUnstagedChanges(git_dir):
343 """Return True if git repository has un-staged changes."""
344 command = 'cd {0} && git diff --quiet --exit-code HEAD'.format(git_dir)
345 return command_executer.GetCommandExecuter().RunCommand(
346 command, print_to_console=False)
347
348def HasGitUntrackedChanges(git_dir):
349 """Return True if git repository has un-tracked changes."""
350 command = 'cd {0} && test -z $(git ls-files --exclude-standard --others)' \
351 .format(git_dir)
352 return command_executer.GetCommandExecuter().RunCommand(
353 command,print_to_console=False)
354
355def IsGitTreeClean(git_dir):
356 if HasGitStagedChanges(git_dir):
357 logger.GetLogger().LogWarning("Git tree has staged changes.")
358 return False
359 if HasGitUnstagedChanges(git_dir):
360 logger.GetLogger().LogWarning("Git tree has unstaged changes.")
361 return False
362 if HasGitUntrackedChanges(git_dir):
363 logger.GetLogger().LogWarning("Git tree has un-tracked changes.")
364 return False
365 return True
366
367def GetGitChangesAsList(git_dir, path=None, staged=False):
368 command = 'cd {0} && git diff --name-only'.format(git_dir)
369 if staged:
370 command = command + ' --cached'
371 if path:
372 command = command + ' -- ' + path
Luis Lozano6aebeb12013-09-03 01:55:02 -0700373 _, out, _ = command_executer.GetCommandExecuter().RunCommand(
Han Shen91445322013-03-20 13:43:31 -0700374 command, return_output=True, print_to_console=False)
375 rv = []
376 for line in out.splitlines():
377 rv.append(line)
378 return rv