build_benchmarks.py revision 88272d479f2761cc1906fea564c73033f77a6270
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