| # Copyright 2015 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Utilities for updating and building in the chroot environment.""" |
| |
| from __future__ import print_function |
| |
| import os |
| |
| from chromite.cbuildbot import constants |
| from chromite.lib import cros_build_lib |
| from chromite.lib import cros_logging as logging |
| |
| if cros_build_lib.IsInsideChroot(): |
| # These import libraries outside chromite. See brbug.com/472. |
| from chromite.scripts import cros_setup_toolchains as toolchain |
| from chromite.scripts import cros_list_modified_packages as workon |
| |
| |
| _HOST_PKGS = ('virtual/target-sdk', 'world',) |
| |
| |
| def _GetToolchainPackages(): |
| """Get a list of host toolchain packages.""" |
| # Load crossdev cache first for faster performance. |
| toolchain.Crossdev.Load(False) |
| packages = toolchain.GetTargetPackages('host') |
| return [toolchain.GetPortagePackage('host', x) for x in packages] |
| |
| |
| def GetEmergeCommand(board=None): |
| """Returns the emerge command to use for |board| (host if None).""" |
| cmd = [os.path.join(constants.CHROMITE_BIN_DIR, 'parallel_emerge')] |
| if board is not None: |
| cmd += ['--board=%s' % board] |
| return cmd |
| |
| |
| def Emerge(packages, brick=None, board=None, host=False, with_deps=True, |
| rebuild_deps=True, use_binary=True, jobs=None, debug_output=False): |
| """Emerge the specified |packages|. |
| |
| Args: |
| packages: List of packages to emerge. |
| brick: The brick to build packages for. Ignored if |host|. |
| board: The board name to build for. Ignored if |host| or |brick|. |
| host: If True, emerge to host. |
| with_deps: Whether to include dependencies. |
| rebuild_deps: Whether to rebuild dependencies. |
| use_binary: Whether to use binary packages. |
| jobs: Number of jobs to run in parallel. |
| debug_output: Emit debug level output. |
| |
| Raises: |
| cros_build_lib.RunCommandError: If emerge returns an error. |
| """ |
| if not packages: |
| raise ValueError('No packages provided') |
| |
| if host: |
| brick = board = None |
| elif brick: |
| board = brick.FriendlyName() |
| |
| cmd = GetEmergeCommand(board=board) |
| cmd.append('-uNv') |
| |
| modified_packages = list(workon.ListModifiedWorkonPackages( |
| None if brick else board, brick, host)) |
| if modified_packages: |
| mod_pkg_list = ' '.join(modified_packages) |
| cmd += ['--reinstall-atoms=' + mod_pkg_list, |
| '--usepkg-exclude=' + mod_pkg_list] |
| |
| cmd.append('--deep' if with_deps else '--nodeps') |
| if use_binary: |
| cmd += ['-g', '--with-bdeps=y'] |
| if host: |
| # Only update toolchains in the chroot when binpkgs are available. The |
| # toolchain rollout process only takes place when the chromiumos sdk |
| # builder finishes a successful build and pushes out binpkgs. |
| cmd += ['--useoldpkg-atoms=%s' % ' '.join(_GetToolchainPackages())] |
| |
| if rebuild_deps: |
| cmd.append('--rebuild-if-unbuilt') |
| if jobs: |
| cmd.append('--jobs=%d' % jobs) |
| if debug_output: |
| cmd.append('--show-output') |
| |
| cros_build_lib.SudoRunCommand(cmd + packages) |
| |
| |
| def UpdateChroot(): |
| """Update the chroot.""" |
| # Run chroot update hooks. |
| cmd = [os.path.join(constants.CROSUTILS_DIR, 'run_chroot_version_hooks')] |
| cros_build_lib.RunCommand(cmd, debug_level=logging.DEBUG) |
| |
| # Update toolchains. |
| cmd = [os.path.join(constants.CHROMITE_BIN_DIR, 'cros_setup_toolchains')] |
| cros_build_lib.SudoRunCommand(cmd, debug_level=logging.DEBUG) |
| |
| # Update the host before updating the board. |
| Emerge(list(_HOST_PKGS), host=True) |
| |
| # Automatically discard all CONFIG_PROTECT'ed files. Those that are |
| # protected should not be overwritten until the variable is changed. |
| # Autodiscard is option "-9" followed by the "YES" confirmation. |
| cros_build_lib.SudoRunCommand(['etc-update'], input='-9\nYES\n', |
| debug_level=logging.DEBUG) |
| |
| |
| def SetupBoard(brick=None, board=None, use_binary=True): |
| """Set up a sysroot for |brick| or |board| (either must be provided). |
| |
| Args: |
| brick: Brick object we need to set up a sysroot for. |
| board: Board name to set up a sysroot for. Ignored if |brick| is provided. |
| use_binary: If okay to use binary packages during the update. |
| """ |
| cmd = [os.path.join(constants.CROSUTILS_DIR, 'setup_board'), |
| '--skip_toolchain_update', '--skip_chroot_upgrade'] |
| |
| if brick: |
| brick.GeneratePortageConfig() |
| cmd.append('--brick=%s' % brick.brick_locator) |
| elif board: |
| cmd.append('--board=%s' % board) |
| else: |
| raise ValueError('Either brick or board must be provided') |
| |
| if not use_binary: |
| cmd.append('--nousepkg') |
| |
| cros_build_lib.RunCommand(cmd) |