• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python2
2#
3# Copyright 2010 Google Inc. All Rights Reserved.
4"""Script to checkout the ChromeOS source.
5
6This script sets up the ChromeOS source in the given directory, matching a
7particular release of ChromeOS.
8"""
9
10from __future__ import print_function
11
12__author__ = ('asharif@google.com (Ahmad Sharif) '
13              'llozano@google.com (Luis Lozano) '
14              'raymes@google.com (Raymes Khoury) '
15              'shenhan@google.com (Han Shen)')
16
17import argparse
18import os
19import sys
20
21from cros_utils import command_executer
22from cros_utils import logger
23from cros_utils import misc
24
25
26def Usage(parser, message):
27  print('ERROR: %s' % message)
28  parser.print_help()
29  sys.exit(0)
30
31
32def Main(argv):
33  """Build ChromeOS."""
34  # Common initializations
35  cmd_executer = command_executer.GetCommandExecuter()
36
37  parser = argparse.ArgumentParser()
38  parser.add_argument(
39      '--chromeos_root',
40      dest='chromeos_root',
41      help='Target directory for ChromeOS installation.')
42  parser.add_argument(
43      '--clobber_chroot',
44      dest='clobber_chroot',
45      action='store_true',
46      help='Delete the chroot and start fresh',
47      default=False)
48  parser.add_argument(
49      '--clobber_board',
50      dest='clobber_board',
51      action='store_true',
52      help='Delete the board and start fresh',
53      default=False)
54  parser.add_argument(
55      '--rebuild',
56      dest='rebuild',
57      action='store_true',
58      help='Rebuild all board packages except the toolchain.',
59      default=False)
60  parser.add_argument(
61      '--cflags',
62      dest='cflags',
63      default='',
64      help='CFLAGS for the ChromeOS packages')
65  parser.add_argument(
66      '--cxxflags',
67      dest='cxxflags',
68      default='',
69      help='CXXFLAGS for the ChromeOS packages')
70  parser.add_argument(
71      '--ldflags',
72      dest='ldflags',
73      default='',
74      help='LDFLAGS for the ChromeOS packages')
75  parser.add_argument(
76      '--board', dest='board', help='ChromeOS target board, e.g. x86-generic')
77  parser.add_argument(
78      '--package', dest='package', help='The package needs to be built')
79  parser.add_argument(
80      '--label',
81      dest='label',
82      help='Optional label symlink to point to build dir.')
83  parser.add_argument(
84      '--dev',
85      dest='dev',
86      default=False,
87      action='store_true',
88      help=('Make the final image in dev mode (eg writable, '
89            'more space on image). Defaults to False.'))
90  parser.add_argument(
91      '--debug',
92      dest='debug',
93      default=False,
94      action='store_true',
95      help=("Optional. Build chrome browser with \"-g -O0\". "
96            "Notice, this also turns on \'--dev\'. "
97            'Defaults to False.'))
98  parser.add_argument(
99      '--env', dest='env', default='', help='Env to pass to build_packages.')
100  parser.add_argument(
101      '--vanilla',
102      dest='vanilla',
103      default=False,
104      action='store_true',
105      help='Use default ChromeOS toolchain.')
106  parser.add_argument(
107      '--vanilla_image',
108      dest='vanilla_image',
109      default=False,
110      action='store_true',
111      help=('Use prebuild packages for building the image. '
112            'It also implies the --vanilla option is set.'))
113
114  options = parser.parse_args(argv[1:])
115
116  if options.chromeos_root is None:
117    Usage(parser, '--chromeos_root must be set')
118  options.chromeos_root = os.path.expanduser(options.chromeos_root)
119  scripts_dir = os.path.join(options.chromeos_root, 'src', 'scripts')
120  if not os.path.isdir(scripts_dir):
121    Usage(parser, '--chromeos_root must be set up first. Use setup_chromeos.py')
122
123  if options.board is None:
124    Usage(parser, '--board must be set')
125
126  if options.debug:
127    options.dev = True
128
129  build_packages_env = options.env
130  if build_packages_env.find('EXTRA_BOARD_FLAGS=') != -1:
131    logger.GetLogger().LogFatal(
132        ('Passing "EXTRA_BOARD_FLAGS" in "--env" is not supported. '
133         'This flags is used internally by this script. '
134         'Contact the author for more detail.'))
135
136  if options.rebuild == True:
137    build_packages_env += ' EXTRA_BOARD_FLAGS=-e'
138    # EXTRA_BOARD_FLAGS=-e should clean up the object files for the chrome
139    # browser but it doesn't. So do it here.
140    misc.RemoveChromeBrowserObjectFiles(options.chromeos_root, options.board)
141
142  # Build with afdo_use by default.
143  # To change the default use --env="USE=-afdo_use".
144  build_packages_env = misc.MergeEnvStringWithDict(
145      build_packages_env, {'USE': 'chrome_internal afdo_use -cros-debug'})
146
147  build_packages_command = misc.GetBuildPackagesCommand(
148      board=options.board, usepkg=options.vanilla_image, debug=options.debug)
149
150  if options.package:
151    build_packages_command += ' {0}'.format(options.package)
152
153  build_image_command = misc.GetBuildImageCommand(options.board, options.dev)
154
155  if options.vanilla or options.vanilla_image:
156    command = misc.GetSetupBoardCommand(
157        options.board,
158        usepkg=options.vanilla_image,
159        force=options.clobber_board)
160    command += '; ' + build_packages_env + ' ' + build_packages_command
161    command += '&& ' + build_packages_env + ' ' + build_image_command
162    ret = cmd_executer.ChrootRunCommand(options.chromeos_root, command)
163    return ret
164
165  # Setup board
166  if not os.path.isdir(options.chromeos_root + '/chroot/build/' +
167                       options.board) or options.clobber_board:
168    # Run build_tc.py from binary package
169    ret = cmd_executer.ChrootRunCommand(options.chromeos_root,
170                                        misc.GetSetupBoardCommand(
171                                            options.board,
172                                            force=options.clobber_board))
173    logger.GetLogger().LogFatalIf(ret, 'setup_board failed')
174  else:
175    logger.GetLogger().LogOutput('Did not setup_board '
176                                 'because it already exists')
177
178  if options.debug:
179    # Perform 2-step build_packages to build a debug chrome browser.
180
181    # Firstly, build everything that chromeos-chrome depends on normally.
182    if options.rebuild == True:
183      # Give warning about "--rebuild" and "--debug". Under this combination,
184      # only dependencies of "chromeos-chrome" get rebuilt.
185      logger.GetLogger().LogWarning(
186          "\"--rebuild\" does not correctly re-build every package when "
187          "\"--debug\" is enabled. ")
188
189      # Replace EXTRA_BOARD_FLAGS=-e with "-e --onlydeps"
190      build_packages_env = build_packages_env.replace(
191          'EXTRA_BOARD_FLAGS=-e', 'EXTRA_BOARD_FLAGS=\"-e --onlydeps\"')
192    else:
193      build_packages_env += ' EXTRA_BOARD_FLAGS=--onlydeps'
194
195    ret = cmd_executer.ChrootRunCommand(
196        options.chromeos_root, "CFLAGS=\"$(portageq-%s envvar CFLAGS) %s\" "
197        "CXXFLAGS=\"$(portageq-%s envvar CXXFLAGS) %s\" "
198        "LDFLAGS=\"$(portageq-%s envvar LDFLAGS) %s\" "
199        'CHROME_ORIGIN=SERVER_SOURCE '
200        '%s '
201        '%s --skip_chroot_upgrade'
202        'chromeos-chrome' % (options.board, options.cflags, options.board,
203                             options.cxxflags, options.board, options.ldflags,
204                             build_packages_env, build_packages_command))
205
206    logger.GetLogger().LogFatalIf(\
207      ret, 'build_packages failed while trying to build chromeos-chrome deps.')
208
209    # Secondly, build chromeos-chrome using debug mode.
210    # Replace '--onlydeps' with '--nodeps'.
211    if options.rebuild == True:
212      build_packages_env = build_packages_env.replace(
213          'EXTRA_BOARD_FLAGS=\"-e --onlydeps\"', 'EXTRA_BOARD_FLAGS=--nodeps')
214    else:
215      build_packages_env = build_packages_env.replace(
216          'EXTRA_BOARD_FLAGS=--onlydeps', 'EXTRA_BOARD_FLAGS=--nodeps')
217    ret = cmd_executer.ChrootRunCommand(
218        options.chromeos_root, "CFLAGS=\"$(portageq-%s envvar CFLAGS) %s\" "
219        "CXXFLAGS=\"$(portageq-%s envvar CXXFLAGS) %s\" "
220        "LDFLAGS=\"$(portageq-%s envvar LDFLAGS) %s\" "
221        'CHROME_ORIGIN=SERVER_SOURCE BUILDTYPE=Debug '
222        '%s '
223        '%s --skip_chroot_upgrade'
224        'chromeos-chrome' % (options.board, options.cflags, options.board,
225                             options.cxxflags, options.board, options.ldflags,
226                             build_packages_env, build_packages_command))
227    logger.GetLogger().LogFatalIf(
228        ret,
229        'build_packages failed while trying to build debug chromeos-chrome.')
230
231    # Now, we have built chromeos-chrome and all dependencies.
232    # Finally, remove '-e' from EXTRA_BOARD_FLAGS,
233    # otherwise, chromeos-chrome gets rebuilt.
234    build_packages_env = build_packages_env.replace(\
235      'EXTRA_BOARD_FLAGS=--nodeps', '')
236
237    # Up to now, we have a debug built chromos-chrome browser.
238    # Fall through to build the rest of the world.
239
240    # Build packages
241  ret = cmd_executer.ChrootRunCommand(
242      options.chromeos_root, "CFLAGS=\"$(portageq-%s envvar CFLAGS) %s\" "
243      "CXXFLAGS=\"$(portageq-%s envvar CXXFLAGS) %s\" "
244      "LDFLAGS=\"$(portageq-%s envvar LDFLAGS) %s\" "
245      'CHROME_ORIGIN=SERVER_SOURCE '
246      '%s '
247      '%s --skip_chroot_upgrade' %
248      (options.board, options.cflags, options.board, options.cxxflags,
249       options.board, options.ldflags, build_packages_env,
250       build_packages_command))
251
252  logger.GetLogger().LogFatalIf(ret, 'build_packages failed')
253  if options.package:
254    return 0
255  # Build image
256  ret = cmd_executer.ChrootRunCommand(
257      options.chromeos_root, build_packages_env + ' ' + build_image_command)
258
259  logger.GetLogger().LogFatalIf(ret, 'build_image failed')
260
261  flags_file_name = 'flags.txt'
262  flags_file_path = ('%s/src/build/images/%s/latest/%s' %
263                     (options.chromeos_root, options.board, flags_file_name))
264  flags_file = open(flags_file_path, 'wb')
265  flags_file.write('CFLAGS=%s\n' % options.cflags)
266  flags_file.write('CXXFLAGS=%s\n' % options.cxxflags)
267  flags_file.write('LDFLAGS=%s\n' % options.ldflags)
268  flags_file.close()
269
270  if options.label:
271    image_dir_path = ('%s/src/build/images/%s/latest' % (options.chromeos_root,
272                                                         options.board))
273    real_image_dir_path = os.path.realpath(image_dir_path)
274    command = ('ln -sf -T %s %s/%s' %
275               (os.path.basename(real_image_dir_path),
276                os.path.dirname(real_image_dir_path), options.label))
277
278    ret = cmd_executer.RunCommand(command)
279    logger.GetLogger().LogFatalIf(
280        ret, 'Failed to apply symlink label %s' % options.label)
281
282  return ret
283
284
285if __name__ == '__main__':
286  retval = Main(sys.argv)
287  sys.exit(retval)
288