1#!/usr/bin/python2 2# 3# Copyright 2010 Google Inc. All Rights Reserved. 4"""Script to build ChromeOS benchmarks 5 6Inputs: 7 chromeos_root 8 toolchain_root 9 board 10 [chromeos/cpu/<benchname> | 11 chromeos/browser/[pagecycler|sunspider] | 12 chromeos/startup] 13 14 This script assumes toolchain has already been built in toolchain_root. 15 16 chromeos/cpu/<benchname> 17 - Execute bench.py script within chroot to build benchmark 18 - Copy build results to perflab-bin 19 20 chromeos/startup 21 - Call build_chromeos to build image. 22 - Copy image to perflab-bin 23 24 chromeos/browser/* 25 - Call build_chromebrowser to build image with new browser 26 - Copy image to perflab-bin 27 28""" 29 30from __future__ import print_function 31 32__author__ = 'bjanakiraman@google.com (Bhaskar Janakiraman)' 33 34import argparse 35import os 36import sys 37import re 38 39import build_chromeos 40from cros_utils import command_executer 41from cros_utils import logger 42 43KNOWN_BENCHMARKS = [ 44 'chromeos/startup', 'chromeos/browser/pagecycler', 45 'chromeos/browser/sunspider', 'chromeos/browser/v8bench', 46 'chromeos/cpu/bikjmp' 47] 48 49# Commands to build CPU benchmarks. 50 51CPU_BUILDCMD_CLEAN = ('cd /usr/local/toolchain_root/third_party/android_bench/' 52 'v2_0/CLOSED_SOURCE/%s; python ../../scripts/bench.py ' 53 '--toolchain=/usr/bin --action=clean;') 54 55CPU_BUILDCMD_BUILD = ('cd /usr/local/toolchain_root/third_party/android_bench/' 56 'v2_0/CLOSED_SOURCE/%s; python ../../scripts/bench.py ' 57 '--toolchain=/usr/bin --add_cflags=%s --add_ldflags=%s ' 58 '--makeopts=%s --action=build') 59 60# Common initializations 61cmd_executer = command_executer.GetCommandExecuter() 62 63 64def Usage(parser, message): 65 print('ERROR: %s' % message) 66 parser.print_help() 67 sys.exit(0) 68 69 70def CreateRunsh(destdir, benchmark): 71 """Create run.sh script to run benchmark. 72 73 Perflab needs a run.sh that runs the benchmark. 74 """ 75 run_cmd = os.path.dirname(os.path.abspath(__file__)) + '/run_benchmarks.py' 76 contents = '#!/bin/sh\n%s $@ %s\n' % (run_cmd, benchmark) 77 runshfile = destdir + '/run.sh' 78 f = open(runshfile, 'w') 79 f.write(contents) 80 f.close() 81 retval = cmd_executer.RunCommand('chmod +x %s' % runshfile) 82 return retval 83 84 85def CreateBinaryCopy(sourcedir, destdir, copy=None): 86 """Create links in perflab-bin/destdir/* to sourcedir/*, instead of copies 87 88 Args: 89 sourcedir: directory from which to copy. 90 destdir: directory to which to copy. 91 copy: when none, make soft links to everything under sourcedir, otherwise 92 copy all to destdir. 93 TODO: remove this parameter if it's determined that CopyFiles can use 94 rsync -L. 95 """ 96 retval = 0 97 # check if sourcedir exists 98 if not os.path.exists(sourcedir): 99 logger.GetLogger().LogError('benchmark results %s does not exist.' % 100 sourcedir) 101 return 1 102 103 # Deal with old copies - save off old ones for now. 104 # Note - if its a link, it doesn't save anything. 105 if os.path.exists(destdir): 106 command = 'rm -rf %s.old' % destdir 107 retval = cmd_executer.RunCommand(command) 108 if retval != 0: 109 return retval 110 command = 'mv %s %s.old' % (destdir, destdir) 111 retval = cmd_executer.RunCommand(command) 112 if retval != 0: 113 return retval 114 os.makedirs(destdir) 115 sourcedir = os.path.abspath(sourcedir) 116 if copy is None: 117 command = 'ln -s %s/* %s' % (sourcedir, destdir) 118 else: 119 command = 'cp -fr %s/* %s' % (sourcedir, destdir) 120 retval = cmd_executer.RunCommand(command) 121 return retval 122 123 124def Main(argv): 125 """Build ChromeOS.""" 126 # Common initializations 127 128 parser = argparse.ArgumentParser() 129 parser.add_argument('-c', 130 '--chromeos_root', 131 dest='chromeos_root', 132 help='Target directory for ChromeOS installation.') 133 parser.add_argument('-t', 134 '--toolchain_root', 135 dest='toolchain_root', 136 help='This is obsolete. Do not use.') 137 parser.add_argument('-r', 138 '--third_party', 139 dest='third_party', 140 help='The third_party dir containing android ' 141 'benchmarks.') 142 parser.add_argument('-C', 143 '--clean', 144 dest='clean', 145 action='store_true', 146 default=False, 147 help='Clean up build.') 148 parser.add_argument('-B', 149 '--build', 150 dest='build', 151 action='store_true', 152 default=False, 153 help='Build benchmark.') 154 parser.add_argument('-O', 155 '--only_copy', 156 dest='only_copy', 157 action='store_true', 158 default=False, 159 help='Only copy to perflab-bin - no builds.') 160 parser.add_argument('--workdir', 161 dest='workdir', 162 default='.', 163 help='Work directory for perflab outputs.') 164 parser.add_argument('--clobber_chroot', 165 dest='clobber_chroot', 166 action='store_true', 167 help='Delete the chroot and start fresh', 168 default=False) 169 parser.add_argument('--clobber_board', 170 dest='clobber_board', 171 action='store_true', 172 help='Delete the board and start fresh', 173 default=False) 174 parser.add_argument('--cflags', 175 dest='cflags', 176 default='', 177 help='CFLAGS for the ChromeOS packages') 178 parser.add_argument('--cxxflags', 179 dest='cxxflags', 180 default='', 181 help='CXXFLAGS for the ChromeOS packages') 182 parser.add_argument('--ldflags', 183 dest='ldflags', 184 default='', 185 help='LDFLAGS for the ChromeOS packages') 186 parser.add_argument('--makeopts', 187 dest='makeopts', 188 default='', 189 help='Make options for the ChromeOS packages') 190 parser.add_argument('--board', 191 dest='board', 192 help='ChromeOS target board, e.g. x86-generic') 193 # Leftover positional arguments 194 parser.add_argument('args', nargs='+', help='benchmarks') 195 196 options = parser.parse_args(argv[1:]) 197 198 # validate args 199 for arg in options.args: 200 if arg not in KNOWN_BENCHMARKS: 201 logger.GetLogger().LogFatal('Bad benchmark %s specified' % arg) 202 203 if options.chromeos_root is None: 204 Usage(parser, '--chromeos_root must be set') 205 206 if options.board is None: 207 Usage(parser, '--board must be set') 208 209 if options.toolchain_root: 210 logger.GetLogger().LogWarning('--toolchain_root should not be set') 211 212 options.chromeos_root = os.path.expanduser(options.chromeos_root) 213 options.workdir = os.path.expanduser(options.workdir) 214 215 retval = 0 216 if options.third_party: 217 third_party = options.third_party 218 else: 219 third_party = '%s/../../../third_party' % os.path.dirname(__file__) 220 third_party = os.path.realpath(third_party) 221 for arg in options.args: 222 # CPU benchmarks 223 if re.match('chromeos/cpu', arg): 224 comps = re.split('/', arg) 225 benchname = comps[2] 226 227 tec_options = [] 228 if third_party: 229 tec_options.append('--third_party=%s' % third_party) 230 if options.clean: 231 retval = cmd_executer.ChrootRunCommand(options.chromeos_root, 232 CPU_BUILDCMD_CLEAN % benchname, 233 tec_options=tec_options) 234 logger.GetLogger().LogErrorIf(retval, 235 'clean of benchmark %s failed.' % arg) 236 if options.build: 237 retval = cmd_executer.ChrootRunCommand( 238 options.chromeos_root, 239 CPU_BUILDCMD_BUILD % (benchname, options.cflags, options.ldflags, 240 options.makeopts), 241 tec_options=tec_options) 242 logger.GetLogger().LogErrorIf(retval, 243 'Build of benchmark %s failed.' % arg) 244 if retval == 0 and (options.build or options.only_copy): 245 benchdir = ('%s/android_bench/v2_0/CLOSED_SOURCE/%s' % 246 (third_party, benchname)) 247 linkdir = '%s/perflab-bin/%s' % (options.workdir, arg) 248 249 # For cpu/*, we need to copy (not symlinks) of all the contents, 250 # because they are part of the test fixutre. 251 retval = CreateBinaryCopy(benchdir, linkdir, True) 252 if retval != 0: 253 return retval 254 retval = CreateRunsh(linkdir, arg) 255 if retval != 0: 256 return retval 257 elif re.match('chromeos/startup', arg): 258 if options.build: 259 # Clean for chromeos/browser and chromeos/startup is a Nop 260 # since builds are always from scratch. 261 build_args = [ 262 os.path.dirname(os.path.abspath(__file__)) + '/build_chromeos.py', 263 '--chromeos_root=' + options.chromeos_root, 264 '--board=' + options.board, '--cflags=' + options.cflags, 265 '--cxxflags=' + options.cxxflags, '--ldflags=' + options.ldflags, 266 '--clobber_board' 267 ] 268 retval = build_chromeos.Main(build_args) 269 logger.GetLogger().LogErrorIf(retval, 'Build of ChromeOS failed.') 270 if retval == 0 and (options.build or options.only_copy): 271 benchdir = '%s/src/build/images/%s/latest' % (options.chromeos_root, 272 options.board) 273 linkdir = '%s/perflab-bin/%s' % (options.workdir, arg) 274 retval = CreateBinaryCopy(benchdir, linkdir) 275 if retval != 0: 276 return retval 277 CreateRunsh(linkdir, arg) 278 if retval != 0: 279 return retval 280 elif re.match('chromeos/browser', arg): 281 if options.build: 282 # For now, re-build os. TBD: Change to call build_browser 283 build_args = [os.path.dirname(os.path.abspath(__file__)) + 284 '/build_chrome_browser.py', 285 '--chromeos_root=' + options.chromeos_root, 286 '--board=' + options.board, '--cflags=' + options.cflags, 287 '--cxxflags=' + options.cxxflags, 288 '--ldflags=' + options.ldflags] 289 retval = build_chromeos.Main(build_args) 290 logger.GetLogger().LogErrorIf(retval, 'Build of ChromeOS failed.') 291 if retval == 0 and (options.build or options.only_copy): 292 benchdir = '%s/src/build/images/%s/latest' % (options.chromeos_root, 293 options.board) 294 linkdir = '%s/perflab-bin/%s' % (options.workdir, arg) 295 retval = CreateBinaryCopy(benchdir, linkdir) 296 if retval != 0: 297 return retval 298 retval = CreateRunsh(linkdir, arg) 299 if retval != 0: 300 return retval 301 302 return 0 303 304 305if __name__ == '__main__': 306 sys.exit(Main(sys.argv)) 307