Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 1 | # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Implementation of the 'build' chromite command.""" |
| 6 | |
| 7 | # Python imports |
| 8 | import optparse |
| 9 | import os |
| 10 | |
| 11 | |
| 12 | # Local imports |
| 13 | import chromite.lib.cros_build_lib as cros_lib |
| 14 | from chromite.shell import utils |
| 15 | from chromite.shell import subcmd |
| 16 | |
| 17 | |
| 18 | def _DoMakeChroot(chroot_config, clean_first): |
| 19 | """Build the chroot, if needed. |
| 20 | |
| 21 | Args: |
| 22 | chroot_config: A SafeConfigParser representing the config for the chroot. |
| 23 | clean_first: Delete any old chroot first. |
| 24 | """ |
| 25 | # Skip this whole command if things already exist. |
| 26 | # TODO(dianders): Theoretically, calling make_chroot a second time is OK |
| 27 | # and "fixes up" the chroot. ...but build_packages will do the fixups |
| 28 | # anyway (I think), so this isn't that important. |
| 29 | chroot_dir = utils.GetChrootAbsDir(chroot_config) |
| 30 | if (not clean_first) and utils.DoesChrootExist(chroot_config): |
| 31 | cros_lib.Info('%s already exists, skipping make_chroot.' % chroot_dir) |
| 32 | return |
| 33 | |
| 34 | cros_lib.Info('MAKING THE CHROOT') |
| 35 | |
| 36 | # Put together command. |
| 37 | cmd_list = [ |
| 38 | './make_chroot', |
| 39 | '--chroot="%s"' % chroot_dir, |
| 40 | chroot_config.get('CHROOT', 'make_chroot_flags'), |
| 41 | ] |
| 42 | if clean_first: |
| 43 | cmd_list.insert(1, '--replace') |
| 44 | |
| 45 | # We're going convert to a string and force the shell to do all of the |
| 46 | # splitting of arguments, since we're throwing all of the flags from the |
| 47 | # config file in there. |
| 48 | cmd = ' '.join(cmd_list) |
| 49 | |
| 50 | # We'll put CWD as src/scripts when running the command. Since everyone |
| 51 | # running by hand has their cwd there, it is probably the safest. |
| 52 | cwd = os.path.join(utils.SRCROOT_PATH, 'src', 'scripts') |
| 53 | |
| 54 | # Run it. Exceptions will cause the program to exit. |
| 55 | cros_lib.RunCommand(cmd, shell=True, cwd=cwd, ignore_sigint=True) |
| 56 | |
| 57 | |
| 58 | def _DoSetupBoard(build_config, clean_first): |
| 59 | """Setup the board, if needed. |
| 60 | |
| 61 | This just runs the setup_board command with the proper args, if needed. |
| 62 | |
| 63 | Args: |
| 64 | build_config: A SafeConfigParser representing the build config. |
| 65 | clean_first: Delete any old board config first. |
| 66 | """ |
| 67 | # Skip this whole command if things already exist. |
| 68 | board_dir = utils.GetBoardDir(build_config) |
| 69 | if (not clean_first) and os.path.isdir(board_dir): |
| 70 | cros_lib.Info('%s already exists, skipping setup_board.' % board_dir) |
| 71 | return |
| 72 | |
| 73 | cros_lib.Info('SETTING UP THE BOARD') |
| 74 | |
| 75 | # Put together command. |
| 76 | cmd_list = [ |
| 77 | './setup_board', |
| 78 | '--board="%s"' % build_config.get('BUILD', 'target'), |
| 79 | build_config.get('BUILD', 'setup_board_flags'), |
| 80 | ] |
| 81 | if clean_first: |
| 82 | cmd_list.insert(1, '--force') |
| 83 | |
| 84 | # We're going convert to a string and force the shell to do all of the |
| 85 | # splitting of arguments, since we're throwing all of the flags from the |
| 86 | # config file in there. |
| 87 | cmd = ' '.join(cmd_list) |
| 88 | |
| 89 | # We'll put CWD as src/scripts when running the command. Since everyone |
| 90 | # running by hand has their cwd there, it is probably the safest. |
| 91 | cwd = os.path.join(utils.SRCROOT_PATH, 'src', 'scripts') |
| 92 | |
| 93 | # Run it. Exceptions will cause the program to exit. |
| 94 | cros_lib.RunCommand(cmd, shell=True, cwd=cwd, ignore_sigint=True) |
| 95 | |
| 96 | |
| 97 | def _DoBuildPackages(build_config): |
| 98 | """Build packages. |
| 99 | |
| 100 | This just runs the build_packages command with the proper args. |
| 101 | |
| 102 | Args: |
| 103 | build_config: A SafeConfigParser representing the build config. |
| 104 | """ |
| 105 | cros_lib.Info('BUILDING PACKAGES') |
| 106 | |
| 107 | # Put together command. We're going to force the shell to do all of the |
| 108 | # splitting of arguments, since we're throwing all of the flags from the |
| 109 | # config file in there. |
| 110 | cmd = './build_packages --board="%s" %s' % ( |
| 111 | build_config.get('BUILD', 'target'), |
| 112 | build_config.get('BUILD', 'build_packages_flags') |
| 113 | ) |
| 114 | |
| 115 | # We'll put CWD as src/scripts when running the command. Since everyone |
| 116 | # running by hand has their cwd there, it is probably the safest. |
| 117 | cwd = os.path.join(utils.SRCROOT_PATH, 'src', 'scripts') |
| 118 | |
| 119 | # Run it. Exceptions will cause the program to exit. |
| 120 | cros_lib.RunCommand(cmd, shell=True, cwd=cwd, ignore_sigint=True) |
| 121 | |
| 122 | |
| 123 | def _DoBuildImage(build_config): |
| 124 | """Build an image. |
| 125 | |
| 126 | This just runs the build_image command with the proper args. |
| 127 | |
| 128 | Args: |
| 129 | build_config: A SafeConfigParser representing the build config. |
| 130 | """ |
| 131 | cros_lib.Info('BUILDING THE IMAGE') |
| 132 | |
| 133 | # Put together command. We're going to force the shell to do all of the |
| 134 | # splitting of arguments, since we're throwing all of the flags from the |
| 135 | # config file in there. |
| 136 | cmd = './build_image --board="%s" %s' % ( |
| 137 | build_config.get('BUILD', 'target'), |
| 138 | build_config.get('IMAGE', 'build_image_flags') |
| 139 | ) |
| 140 | |
| 141 | # We'll put CWD as src/scripts when running the command. Since everyone |
| 142 | # running by hand has their cwd there, it is probably the safest. |
| 143 | cwd = os.path.join(utils.SRCROOT_PATH, 'src', 'scripts') |
| 144 | |
| 145 | # Run it. Exceptions will cause the program to exit. |
| 146 | cros_lib.RunCommand(cmd, shell=True, cwd=cwd, ignore_sigint=True) |
| 147 | |
| 148 | |
| 149 | class BuildCmd(subcmd.ChromiteCmd): |
| 150 | """Build the chroot (if needed), the packages for a target, and the image.""" |
| 151 | |
| 152 | def Run(self, raw_argv, chroot_config=None, |
| 153 | loaded_config=False, build_config=None): |
| 154 | """Run the command. |
| 155 | |
| 156 | Args: |
| 157 | raw_argv: Command line arguments, including this command's name, but not |
| 158 | the chromite command name or chromite options. |
| 159 | chroot_config: A SafeConfigParser for the chroot config; or None chromite |
| 160 | was called from within the chroot. |
| 161 | loaded_config: If True, we've already loaded the config. |
| 162 | build_config: None when called normally, but contains the SafeConfigParser |
| 163 | for the build config if we call ourselves with _DoEnterChroot(). Note |
| 164 | that even when called through _DoEnterChroot(), could still be None |
| 165 | if user chose 'HOST' as the target. |
| 166 | """ |
| 167 | # Parse options for command... |
| 168 | usage_str = ('usage: %%prog [chromite_options] %s [options] [target]' % |
| 169 | raw_argv[0]) |
| 170 | parser = optparse.OptionParser(usage=usage_str) |
| 171 | parser.add_option('--clean', default=False, action='store_true', |
| 172 | help='Clean before building.') |
| 173 | (options, argv) = parser.parse_args(raw_argv[1:]) |
| 174 | |
| 175 | # Load the build config if needed... |
| 176 | if not loaded_config: |
| 177 | argv, build_config = utils.GetBuildConfigFromArgs(argv) |
| 178 | if argv: |
| 179 | cros_lib.Die('Unknown arguments: %s' % ' '.join(argv)) |
| 180 | |
| 181 | if not cros_lib.IsInsideChroot(): |
| 182 | # Note: we only want to clean the chroot if they do --clean and have the |
| 183 | # host target. If they do --clean and have a board target, it means |
| 184 | # that they just want to clean the board... |
| 185 | want_clean_chroot = options.clean and build_config is None |
| 186 | |
| 187 | _DoMakeChroot(chroot_config, want_clean_chroot) |
| 188 | |
| 189 | if build_config is not None: |
| 190 | utils.EnterChroot(chroot_config, (self, 'Run'), raw_argv, |
| 191 | build_config=build_config, loaded_config=True) |
| 192 | |
| 193 | cros_lib.Info('Done building.') |
| 194 | else: |
| 195 | if build_config is None: |
| 196 | cros_lib.Die("You can't build the host chroot from within the chroot.") |
| 197 | |
| 198 | _DoSetupBoard(build_config, options.clean) |
| 199 | _DoBuildPackages(build_config) |
| 200 | _DoBuildImage(build_config) |