# -*- coding: utf-8 -*-
# Copyright (c) 2012 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.

"""This script manages the installed toolchains in the chroot."""

from __future__ import print_function

import errno
import glob
import hashlib
import json
import os
import re
import shutil
import sys

from chromite.lib import constants
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import toolchain
from chromite.utils import key_value_store

# Needs to be after chromite imports.
import lddtree  # pylint: disable=wrong-import-order

if cros_build_lib.IsInsideChroot():
  # Only import portage after we've checked that we're inside the chroot.
  # Outside may not have portage, in which case the above may not happen.
  # We'll check in main() if the operation needs portage.
  # pylint: disable=import-error
  import portage


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


EMERGE_CMD = os.path.join(constants.CHROMITE_BIN_DIR, 'parallel_emerge')
PACKAGE_STABLE = '[stable]'

CHROMIUMOS_OVERLAY = '/usr/local/portage/chromiumos'
ECLASS_OVERLAY = '/usr/local/portage/eclass-overlay'
STABLE_OVERLAY = '/usr/local/portage/stable'
CROSSDEV_OVERLAY = '/usr/local/portage/crossdev'


# The exact list of host toolchain packages we care about.  These are the
# packages that bots/devs install only from binpkgs and rely on the SDK bot
# (chromiumos-sdk) to validate+uprev.
#
# We don't use crossdev to manage the host toolchain for us, especially since
# we diverge significantly now (with llvm/clang/etc...), and we don't need or
# want crossdev managing /etc/portage config files for the sdk
HOST_PACKAGES = (
    'dev-lang/go',
    'dev-libs/elfutils',
    'sys-devel/binutils',
    'sys-devel/gcc',
    'sys-devel/llvm',
    'sys-kernel/linux-headers',
    'sys-libs/glibc',
    'sys-libs/libcxx',
    'sys-libs/libcxxabi',
    'sys-libs/llvm-libunwind',
)

# These packages are also installed into the host SDK.  However, they require
# the cross-compilers to be installed first (because they need them to actually
# build), so we have to delay their installation.
HOST_POST_CROSS_PACKAGES = (
    'dev-lang/rust',
    'virtual/target-sdk-post-cross',
    'dev-embedded/coreboot-sdk',
)

# New packages that we're in the process of adding to the SDK.  Since the SDK
# bot hasn't had a chance to run yet, there are no binary packages available,
# so we have to list them here and wait.  Once it completes, entries here can
# be removed so they'll end up on bots & dev's systems.
NEW_PACKAGES = (
)

# Enable the Go compiler for these targets.
TARGET_GO_ENABLED = (
    'x86_64-cros-linux-gnu',
    'armv7a-cros-linux-gnueabi',
    'armv7a-cros-linux-gnueabihf',
    'aarch64-cros-linux-gnu',
)
CROSSDEV_GO_ARGS = ['--ex-pkg', 'dev-lang/go']

# Enable llvm's compiler-rt for these targets.
TARGET_COMPILER_RT_ENABLED = (
    'armv7a-cros-linux-gnueabi',
    'armv7a-cros-linux-gnueabihf',
    'aarch64-cros-linux-gnu',
    'armv7m-cros-eabi',
)
CROSSDEV_COMPILER_RT_ARGS = ['--ex-pkg', 'sys-libs/compiler-rt']

TARGET_LLVM_PKGS_ENABLED = (
    'armv7a-cros-linux-gnueabi',
    'armv7a-cros-linux-gnueabihf',
    'aarch64-cros-linux-gnu',
    'x86_64-cros-linux-gnu',
)

LLVM_PKGS_TABLE = {
    'ex_libcxxabi' : ['--ex-pkg', 'sys-libs/libcxxabi'],
    'ex_libcxx' : ['--ex-pkg', 'sys-libs/libcxx'],
    'ex_llvm-libunwind' : ['--ex-pkg', 'sys-libs/llvm-libunwind'],
}

# Overrides for {gcc,binutils}-config, pick a package with particular suffix.
CONFIG_TARGET_SUFFIXES = {
    'binutils' : {
        'aarch64-cros-linux-gnu' : '-gold',
        'armv6j-cros-linux-gnueabi': '-gold',
        'armv7a-cros-linux-gnueabi': '-gold',
        'armv7a-cros-linux-gnueabihf': '-gold',
        'i686-pc-linux-gnu' : '-gold',
        'x86_64-cros-linux-gnu' : '-gold',
    },
}


class Crossdev(object):
  """Class for interacting with crossdev and caching its output."""

  _CACHE_FILE = os.path.join(CROSSDEV_OVERLAY, '.configured.json')
  _CACHE = {}
  # Packages that needs separate handling, in addition to what we have from
  # crossdev.
  MANUAL_PKGS = {
      'llvm': 'sys-devel',
      'libcxxabi': 'sys-libs',
      'libcxx': 'sys-libs',
      'elfutils': 'dev-libs',
      'llvm-libunwind': 'sys-libs',
  }

  @classmethod
  def Load(cls, reconfig):
    """Load crossdev cache from disk.

    We invalidate the cache when crossdev updates or this script changes.
    """
    crossdev_version = GetStablePackageVersion('sys-devel/crossdev', True)
    # If we run the compiled/cached .pyc file, we'll read/hash that when we
    # really always want to track the source .py file.
    script = os.path.abspath(__file__)
    if script.endswith('.pyc'):
      script = script[:-1]
    setup_toolchains_hash = hashlib.md5(
        osutils.ReadFile(script, mode='rb')).hexdigest()

    cls._CACHE = {
        'crossdev_version': crossdev_version,
        'setup_toolchains_hash': setup_toolchains_hash,
    }

    logging.debug('cache: checking file: %s', cls._CACHE_FILE)
    if reconfig:
      logging.debug('cache: forcing regen due to reconfig')
      return

    try:
      file_data = osutils.ReadFile(cls._CACHE_FILE)
    except IOError as e:
      if e.errno != errno.ENOENT:
        logging.warning('cache: reading failed: %s', e)
        osutils.SafeUnlink(cls._CACHE_FILE)
      return

    try:
      data = json.loads(file_data)
    except ValueError as e:
      logging.warning('cache: ignoring invalid content: %s', e)
      return

    if crossdev_version != data.get('crossdev_version'):
      logging.debug('cache: rebuilding after crossdev upgrade')
    elif setup_toolchains_hash != data.get('setup_toolchains_hash'):
      logging.debug('cache: rebuilding after cros_setup_toolchains change')
    else:
      logging.debug('cache: content is up-to-date!')
      cls._CACHE = data

  @classmethod
  def Save(cls):
    """Store crossdev cache on disk."""
    # Save the cache from the successful run.
    with open(cls._CACHE_FILE, 'w') as f:
      json.dump(cls._CACHE, f)

  @classmethod
  def GetConfig(cls, target):
    """Returns a map of crossdev provided variables about a tuple."""
    CACHE_ATTR = '_target_tuple_map'

    val = cls._CACHE.setdefault(CACHE_ATTR, {})
    if not target in val:
      if target.startswith('host'):
        conf = {
            'crosspkgs': [],
            'target': toolchain.GetHostTuple(),
        }
        if target == 'host':
          packages_list = HOST_PACKAGES
        else:
          packages_list = HOST_POST_CROSS_PACKAGES
        manual_pkgs = dict((pkg, cat) for cat, pkg in
                           [x.split('/') for x in packages_list])
      else:
        # Build the crossdev command.
        cmd = ['crossdev', '--show-target-cfg', '--ex-gdb']
        if target in TARGET_COMPILER_RT_ENABLED:
          cmd.extend(CROSSDEV_COMPILER_RT_ARGS)
        if target in TARGET_GO_ENABLED:
          cmd.extend(CROSSDEV_GO_ARGS)
        if target in TARGET_LLVM_PKGS_ENABLED:
          for pkg in LLVM_PKGS_TABLE:
            cmd.extend(LLVM_PKGS_TABLE[pkg])
        cmd.extend(['-t', target])
        # Catch output of crossdev.
        out = cros_build_lib.run(
            cmd, print_cmd=False, stdout=True,
            encoding='utf-8').stdout.splitlines()
        # List of tuples split at the first '=', converted into dict.
        conf = dict((k, cros_build_lib.ShellUnquote(v))
                    for k, v in (x.split('=', 1) for x in out))
        conf['crosspkgs'] = conf['crosspkgs'].split()

        manual_pkgs = cls.MANUAL_PKGS

      for pkg, cat in manual_pkgs.items():
        conf[pkg + '_pn'] = pkg
        conf[pkg + '_category'] = cat
        if pkg not in conf['crosspkgs']:
          conf['crosspkgs'].append(pkg)

      val[target] = conf

    return val[target]

  @classmethod
  def UpdateTargets(cls, targets, usepkg, config_only=False):
    """Calls crossdev to initialize a cross target.

    Args:
      targets: The list of targets to initialize using crossdev.
      usepkg: Copies the commandline opts.
      config_only: Just update.
    """
    configured_targets = cls._CACHE.setdefault('configured_targets', [])

    cmdbase = ['crossdev', '--show-fail-log']
    cmdbase.extend(['--env', 'FEATURES=splitdebug'])
    # Pick stable by default, and override as necessary.
    cmdbase.extend(['-P', '--oneshot'])
    if usepkg:
      cmdbase.extend(['-P', '--getbinpkg',
                      '-P', '--usepkgonly',
                      '--without-headers'])

    overlays = ' '.join((CHROMIUMOS_OVERLAY, ECLASS_OVERLAY, STABLE_OVERLAY))
    cmdbase.extend(['--overlays', overlays])
    cmdbase.extend(['--ov-output', CROSSDEV_OVERLAY])

    # Build target by the reversed alphabetical order to make sure
    # armv7a-cros-linux-gnueabihf builds before armv7a-cros-linux-gnueabi
    # because some dependency issue. This can be reverted once we
    # migrated to armv7a-cros-linux-gnueabihf. crbug.com/711369
    for target in sorted(targets, reverse=True):
      if config_only and target in configured_targets:
        continue

      cmd = cmdbase + ['-t', target]

      for pkg in GetTargetPackages(target):
        if pkg == 'gdb':
          # Gdb does not have selectable versions.
          cmd.append('--ex-gdb')
        elif pkg == 'ex_compiler-rt':
          cmd.extend(CROSSDEV_COMPILER_RT_ARGS)
        elif pkg == 'ex_go':
          # Go does not have selectable versions.
          cmd.extend(CROSSDEV_GO_ARGS)
        elif pkg in LLVM_PKGS_TABLE:
          cmd.extend(LLVM_PKGS_TABLE[pkg])
        elif pkg in cls.MANUAL_PKGS:
          pass
        else:
          # The first of the desired versions is the "primary" one.
          version = GetDesiredPackageVersions(target, pkg)[0]
          cmd.extend(['--%s' % pkg, version])

      cmd.extend(targets[target]['crossdev'].split())
      if config_only:
        # In this case we want to just quietly reinit
        cmd.append('--init-target')
        cros_build_lib.run(cmd, print_cmd=False, stdout=True)
      else:
        cros_build_lib.run(cmd)

      configured_targets.append(target)


def GetTargetPackages(target):
  """Returns a list of packages for a given target."""
  conf = Crossdev.GetConfig(target)
  # Undesired packages are denoted by empty ${pkg}_pn variable.
  return [x for x in conf['crosspkgs'] if conf.get(x+'_pn')]


# Portage helper functions:
def GetPortagePackage(target, package):
  """Returns a package name for the given target."""
  conf = Crossdev.GetConfig(target)
  # Portage category:
  if target.startswith('host') or package in Crossdev.MANUAL_PKGS:
    category = conf[package + '_category']
  else:
    category = conf['category']
  # Portage package:
  pn = conf[package + '_pn']
  # Final package name:
  assert category
  assert pn
  return '%s/%s' % (category, pn)


def PortageTrees(root):
  """Return the portage trees for a given root."""
  if root == '/':
    return portage.db['/']
  # The portage logic requires the path always end in a slash.
  root = root.rstrip('/') + '/'
  return portage.create_trees(target_root=root, config_root=root)[root]


def GetInstalledPackageVersions(atom, root='/'):
  """Extracts the list of current versions of a target, package pair.

  Args:
    atom: The atom to operate on (e.g. sys-devel/gcc)
    root: The root to check for installed packages.

  Returns:
    The list of versions of the package currently installed.
  """
  versions = []
  for pkg in PortageTrees(root)['vartree'].dbapi.match(atom, use_cache=0):
    version = portage.versions.cpv_getversion(pkg)
    versions.append(version)
  return versions


def GetStablePackageVersion(atom, installed, root='/'):
  """Extracts the current stable version for a given package.

  Args:
    atom: The target/package to operate on eg. i686-pc-linux-gnu,gcc
    installed: Whether we want installed packages or ebuilds
    root: The root to use when querying packages.

  Returns:
    A string containing the latest version.
  """
  pkgtype = 'vartree' if installed else 'porttree'
  cpv = portage.best(PortageTrees(root)[pkgtype].dbapi.match(atom, use_cache=0))
  return portage.versions.cpv_getversion(cpv) if cpv else None


def VersionListToNumeric(target, package, versions, installed, root='/'):
  """Resolves keywords in a given version list for a particular package.

  Resolving means replacing PACKAGE_STABLE with the actual number.

  Args:
    target: The target to operate on (e.g. i686-pc-linux-gnu)
    package: The target/package to operate on (e.g. gcc)
    versions: List of versions to resolve
    installed: Query installed packages
    root: The install root to use; ignored if |installed| is False.

  Returns:
    List of purely numeric versions equivalent to argument
  """
  resolved = []
  atom = GetPortagePackage(target, package)
  if not installed:
    root = '/'
  for version in versions:
    if version == PACKAGE_STABLE:
      resolved.append(GetStablePackageVersion(atom, installed, root=root))
    else:
      resolved.append(version)
  return resolved


def GetDesiredPackageVersions(target, package):
  """Produces the list of desired versions for each target, package pair.

  The first version in the list is implicitly treated as primary, ie.
  the version that will be initialized by crossdev and selected.

  If the version is PACKAGE_STABLE, it really means the current version which
  is emerged by using the package atom with no particular version key.
  Since crossdev unmasks all packages by default, this will actually
  mean 'unstable' in most cases.

  Args:
    target: The target to operate on (e.g. i686-pc-linux-gnu)
    package: The target/package to operate on (e.g. gcc)

  Returns:
    A list composed of either a version string, PACKAGE_STABLE
  """
  if package in GetTargetPackages(target):
    return [PACKAGE_STABLE]
  else:
    return []


def TargetIsInitialized(target):
  """Verifies if the given list of targets has been correctly initialized.

  This determines whether we have to call crossdev while emerging
  toolchain packages or can do it using emerge. Emerge is naturally
  preferred, because all packages can be updated in a single pass.

  Args:
    target: The target to operate on (e.g. i686-pc-linux-gnu)

  Returns:
    True if |target| is completely initialized, else False
  """
  # Check if packages for the given target all have a proper version.
  try:
    for package in GetTargetPackages(target):
      atom = GetPortagePackage(target, package)
      # Do we even want this package && is it initialized?
      if not (GetStablePackageVersion(atom, True) and
              GetStablePackageVersion(atom, False)):
        return False
    return True
  except cros_build_lib.RunCommandError:
    # Fails - The target has likely never been initialized before.
    return False


def RemovePackageMask(target):
  """Removes a package.mask file for the given platform.

  The pre-existing package.mask files can mess with the keywords.

  Args:
    target: The target to operate on (e.g. i686-pc-linux-gnu)
  """
  maskfile = os.path.join('/etc/portage/package.mask', 'cross-' + target)
  osutils.SafeUnlink(maskfile)


# Main functions performing the actual update steps.
def RebuildLibtool(root='/'):
  """Rebuild libtool as needed

  Libtool hardcodes full paths to internal gcc files, so whenever we upgrade
  gcc, libtool will break.  We can't use binary packages either as those will
  most likely be compiled against the previous version of gcc.

  Args:
    root: The install root where we want libtool rebuilt.
  """
  needs_update = False
  with open(os.path.join(root, 'usr/bin/libtool')) as f:
    for line in f:
      # Look for a line like:
      #   sys_lib_search_path_spec="..."
      # It'll be a list of paths and gcc will be one of them.
      if line.startswith('sys_lib_search_path_spec='):
        line = line.rstrip()
        for path in line.split('=', 1)[1].strip('"').split():
          root_path = os.path.join(root, path.lstrip(os.path.sep))
          logging.debug('Libtool: checking %s', root_path)
          if not os.path.exists(root_path):
            logging.info('Rebuilding libtool after gcc upgrade')
            logging.info(' %s', line)
            logging.info(' missing path: %s', path)
            needs_update = True
            break

      if needs_update:
        break

  if needs_update:
    cmd = [EMERGE_CMD, '--oneshot']
    if root != '/':
      cmd.extend(['--sysroot=%s' % root, '--root=%s' % root])
    cmd.append('sys-devel/libtool')
    cros_build_lib.run(cmd)
  else:
    logging.debug('Libtool is up-to-date; no need to rebuild')


def UpdateTargets(targets, usepkg, root='/'):
  """Determines which packages need update/unmerge and defers to portage.

  Args:
    targets: The list of targets to update
    usepkg: Copies the commandline option
    root: The install root in which we want packages updated.
  """
  # For each target, we do two things. Figure out the list of updates,
  # and figure out the appropriate keywords/masks. Crossdev will initialize
  # these, but they need to be regenerated on every update.
  logging.info('Determining required toolchain updates...')
  mergemap = {}
  for target in targets:
    logging.debug('Updating target %s', target)
    # Record the highest needed version for each target, for masking purposes.
    RemovePackageMask(target)
    for package in GetTargetPackages(target):
      # Portage name for the package
      logging.debug('   Checking package %s', package)
      pkg = GetPortagePackage(target, package)
      current = GetInstalledPackageVersions(pkg, root=root)
      desired = GetDesiredPackageVersions(target, package)
      desired_num = VersionListToNumeric(target, package, desired, False)
      if pkg in NEW_PACKAGES and usepkg:
        # Skip this binary package (for now).
        continue
      mergemap[pkg] = set(desired_num).difference(current)
      logging.debug('      %s -> %s', current, desired_num)

  packages = [pkg for pkg, vers in mergemap.items() if vers]
  if not packages:
    logging.info('Nothing to update!')
    return False

  logging.info('Updating packages:')
  logging.info('%s', packages)

  cmd = [EMERGE_CMD, '--oneshot', '--update']
  if usepkg:
    cmd.extend(['--getbinpkg', '--usepkgonly'])
  if root != '/':
    cmd.extend(['--sysroot=%s' % root, '--root=%s' % root])

  cmd.extend(packages)
  cros_build_lib.run(cmd)
  return True


def CleanTargets(targets, root='/'):
  """Unmerges old packages that are assumed unnecessary.

  Args:
    targets: The list of targets to clean up.
    root: The install root in which we want packages cleaned up.
  """
  unmergemap = {}
  for target in targets:
    logging.debug('Cleaning target %s', target)
    for package in GetTargetPackages(target):
      logging.debug('   Cleaning package %s', package)
      pkg = GetPortagePackage(target, package)
      current = GetInstalledPackageVersions(pkg, root=root)
      desired = GetDesiredPackageVersions(target, package)
      # NOTE: This refers to installed packages (vartree) rather than the
      # Portage version (porttree and/or bintree) when determining the current
      # version. While this isn't the most accurate thing to do, it is probably
      # a good simple compromise, which should have the desired result of
      # uninstalling everything but the latest installed version. In
      # particular, using the bintree (--usebinpkg) requires a non-trivial
      # binhost sync and is probably more complex than useful.
      desired_num = VersionListToNumeric(target, package, desired, True)
      if not set(desired_num).issubset(current):
        logging.warning('Error detecting stable version for %s, '
                        'skipping clean!', pkg)
        return
      unmergemap[pkg] = set(current).difference(desired_num)

  # Cleaning doesn't care about consistency and rebuilding package.* files.
  packages = []
  for pkg, vers in unmergemap.items():
    packages.extend('=%s-%s' % (pkg, ver) for ver in vers if ver != '9999')

  if packages:
    logging.info('Cleaning packages:')
    logging.info('%s', packages)
    cmd = [EMERGE_CMD, '--unmerge']
    if root != '/':
      cmd.extend(['--sysroot=%s' % root, '--root=%s' % root])
    cmd.extend(packages)
    cros_build_lib.run(cmd)
  else:
    logging.info('Nothing to clean!')


def SelectActiveToolchains(targets, suffixes, root='/'):
  """Runs gcc-config and binutils-config to select the desired.

  Args:
    targets: The targets to select
    suffixes: Optional target-specific hacks
    root: The root where we want to select toolchain versions.
  """
  for package in ['gcc', 'binutils']:
    for target in targets:
      # See if this package is part of this target.
      if package not in GetTargetPackages(target):
        logging.debug('%s: %s is not used', target, package)
        continue

      # Pick the first version in the numbered list as the selected one.
      desired = GetDesiredPackageVersions(target, package)
      desired_num = VersionListToNumeric(target, package, desired, True,
                                         root=root)
      desired = desired_num[0]
      # *-config does not play revisions, strip them, keep just PV.
      desired = portage.versions.pkgsplit('%s-%s' % (package, desired))[1]

      if target.startswith('host'):
        # *-config is the only tool treating host identically (by tuple).
        target = toolchain.GetHostTuple()

      # And finally, attach target to it.
      desired = '%s-%s' % (target, desired)

      # Target specific hacks
      if package in suffixes:
        if target in suffixes[package]:
          desired += suffixes[package][target]

      extra_env = {'CHOST': target}
      if root != '/':
        extra_env['ROOT'] = root
      cmd = ['%s-config' % package, '-c', target]
      result = cros_build_lib.run(
          cmd, print_cmd=False, stdout=True, encoding='utf-8',
          extra_env=extra_env)
      current = result.output.splitlines()[0]

      # Do not reconfig when the current is live or nothing needs to be done.
      extra_env = {'ROOT': root} if root != '/' else None
      if current != desired and current != '9999':
        cmd = [package + '-config', desired]
        cros_build_lib.run(cmd, print_cmd=False, extra_env=extra_env)


def ExpandTargets(targets_wanted):
  """Expand any possible toolchain aliases into full targets

  This will expand 'all' and 'sdk' into the respective toolchain tuples.

  Args:
    targets_wanted: The targets specified by the user.

  Returns:
    Dictionary of concrete targets and their toolchain tuples.
  """
  targets_wanted = set(targets_wanted)
  if targets_wanted == set(['boards']):
    # Only pull targets from the included boards.
    return {}

  all_targets = toolchain.GetAllTargets()
  if targets_wanted == set(['all']):
    return all_targets
  if targets_wanted == set(['sdk']):
    # Filter out all the non-sdk toolchains as we don't want to mess
    # with those in all of our builds.
    return toolchain.FilterToolchains(all_targets, 'sdk', True)

  # Verify user input.
  nonexistent = targets_wanted.difference(all_targets)
  if nonexistent:
    raise ValueError('Invalid targets: %s' % (','.join(nonexistent),))
  return {t: all_targets[t] for t in targets_wanted}


def UpdateToolchains(usepkg, deleteold, hostonly, reconfig,
                     targets_wanted, boards_wanted, root='/'):
  """Performs all steps to create a synchronized toolchain enviroment.

  Args:
    usepkg: Use prebuilt packages
    deleteold: Unmerge deprecated packages
    hostonly: Only setup the host toolchain
    reconfig: Reload crossdev config and reselect toolchains
    targets_wanted: All the targets to update
    boards_wanted: Load targets from these boards
    root: The root in which to install the toolchains.
  """
  targets, crossdev_targets, reconfig_targets = {}, {}, {}
  if not hostonly:
    # For hostonly, we can skip most of the below logic, much of which won't
    # work on bare systems where this is useful.
    targets = ExpandTargets(targets_wanted)

    # Now re-add any targets that might be from this board. This is to
    # allow unofficial boards to declare their own toolchains.
    for board in boards_wanted:
      targets.update(toolchain.GetToolchainsForBoard(board))

    # First check and initialize all cross targets that need to be.
    for target in targets:
      if TargetIsInitialized(target):
        reconfig_targets[target] = targets[target]
      else:
        crossdev_targets[target] = targets[target]
    if crossdev_targets:
      logging.info('The following targets need to be re-initialized:')
      logging.info('%s', crossdev_targets)
      Crossdev.UpdateTargets(crossdev_targets, usepkg)
    # Those that were not initialized may need a config update.
    Crossdev.UpdateTargets(reconfig_targets, usepkg, config_only=True)

    # If we're building a subset of toolchains for a board, we might not have
    # all the tuples that the packages expect.  We don't define the "full" set
    # of tuples currently other than "whatever the full sdk has normally".
    if usepkg or set(('all', 'sdk')) & targets_wanted:
      # Since we have cross-compilers now, we can update these packages.
      targets['host-post-cross'] = {}

  # We want host updated.
  targets['host'] = {}

  # Now update all packages.
  if UpdateTargets(targets, usepkg, root=root) or crossdev_targets or reconfig:
    SelectActiveToolchains(targets, CONFIG_TARGET_SUFFIXES, root=root)

  if deleteold:
    CleanTargets(targets, root=root)

  # Now that we've cleared out old versions, see if we need to rebuild
  # anything.  Can't do this earlier as it might not be broken.
  RebuildLibtool(root=root)


def ShowConfig(name):
  """Show the toolchain tuples used by |name|

  Args:
    name: The board name to query.
  """
  toolchains = toolchain.GetToolchainsForBoard(name)
  # Make sure we display the default toolchain first.
  # Note: Do not use logging here as this is meant to be used by other tools.
  print(','.join(
      list(toolchain.FilterToolchains(toolchains, 'default', True)) +
      list(toolchain.FilterToolchains(toolchains, 'default', False))))


def GeneratePathWrapper(root, wrappath, path):
  """Generate a shell script to execute another shell script

  Since we can't symlink a wrapped ELF (see GenerateLdsoWrapper) because the
  argv[0] won't be pointing to the correct path, generate a shell script that
  just executes another program with its full path.

  Args:
    root: The root tree to generate scripts inside of
    wrappath: The full path (inside |root|) to create the wrapper
    path: The target program which this wrapper will execute
  """
  replacements = {
      'path': path,
      'relroot': os.path.relpath('/', os.path.dirname(wrappath)),
  }

  # Do not use exec here, because exec invokes script with absolute path in
  # argv0. Keeping relativeness allows us to remove abs path from compile result
  # and leads directory independent build cache sharing in some distributed
  # build system.
  wrapper = """#!/bin/sh
basedir=$(dirname "$0")
"${basedir}/%(relroot)s%(path)s" "$@"
exit "$?"
""" % replacements
  root_wrapper = root + wrappath
  if os.path.islink(root_wrapper):
    os.unlink(root_wrapper)
  else:
    osutils.SafeMakedirs(os.path.dirname(root_wrapper))
  osutils.WriteFile(root_wrapper, wrapper)
  os.chmod(root_wrapper, 0o755)


def FixClangXXWrapper(root, path):
  """Fix wrapper shell scripts and symlinks for invoking clang++

  In a typical installation, clang++ symlinks to clang, which symlinks to the
  elf executable. The executable distinguishes between clang and clang++ based
  on argv[0].

  When invoked through the LdsoWrapper, argv[0] always contains the path to the
  executable elf file, making clang/clang++ invocations indistinguishable.

  This function detects if the elf executable being wrapped is clang-X.Y, and
  fixes wrappers/symlinks as necessary so that clang++ will work correctly.

  The calling sequence now becomes:
  -) clang++ invocation turns into clang++-3.9 (which is a copy of clang-3.9,
     the Ldsowrapper).
  -) clang++-3.9 uses the Ldso to invoke clang++-3.9.elf, which is a symlink
     to the original clang-3.9 elf.
  -) The difference this time is that inside the elf file execution, $0 is
     set as .../usr/bin/clang++-3.9.elf, which contains 'clang++' in the name.

  Update: Starting since clang 7, the clang and clang++ are symlinks to
  clang-7 binary, not clang-7.0. The pattern match is extended to handle
  both clang-7 and clang-7.0 cases for now. (https://crbug.com/837889)

  Args:
    root: The root tree to generate scripts / symlinks inside of
    path: The target elf for which LdsoWrapper was created
  """
  if re.match(r'/usr/bin/clang-\d+(\.\d+)*$', path):
    logging.info('fixing clang++ invocation for %s', path)
    clangdir = os.path.dirname(root + path)
    clang = os.path.basename(path)
    clangxx = clang.replace('clang', 'clang++')

    # Create a symlink clang++-X.Y.elf to point to clang-X.Y.elf
    os.symlink(clang + '.elf', os.path.join(clangdir, clangxx + '.elf'))

    # Create a hardlink clang++-X.Y pointing to clang-X.Y
    os.link(os.path.join(clangdir, clang), os.path.join(clangdir, clangxx))

    # Adjust the clang++ symlink to point to clang++-X.Y
    os.unlink(os.path.join(clangdir, 'clang++'))
    os.symlink(clangxx, os.path.join(clangdir, 'clang++'))


def FileIsCrosSdkElf(elf):
  """Determine if |elf| is an ELF that we execute in the cros_sdk

  We don't need this to be perfect, just quick.  It makes sure the ELF
  is a 64bit LSB x86_64 ELF.  That is the native type of cros_sdk.

  Args:
    elf: The file to check

  Returns:
    True if we think |elf| is a native ELF
  """
  with open(elf, 'rb') as f:
    data = f.read(20)
    # Check the magic number, EI_CLASS, EI_DATA, and e_machine.
    return (data[0:4] == b'\x7fELF' and
            data[4:5] == b'\x02' and
            data[5:6] == b'\x01' and
            data[18:19] == b'\x3e')


def IsPathPackagable(ptype, path):
  """Should the specified file be included in a toolchain package?

  We only need to handle files as we'll create dirs as we need them.

  Further, trim files that won't be useful:
   - non-english translations (.mo) since it'd require env vars
   - debug files since these are for the host compiler itself
   - info/man pages as they're big, and docs are online, and the
     native docs should work fine for the most part (`man gcc`)

  Args:
    ptype: A string describing the path type (i.e. 'file' or 'dir' or 'sym')
    path: The full path to inspect

  Returns:
    True if we want to include this path in the package
  """
  return not (ptype in ('dir',) or
              path.startswith('/usr/lib/debug/') or
              os.path.splitext(path)[1] == '.mo' or
              ('/man/' in path or '/info/' in path))


def ReadlinkRoot(path, root):
  """Like os.readlink(), but relative to a |root|

  Args:
    path: The symlink to read
    root: The path to use for resolving absolute symlinks

  Returns:
    A fully resolved symlink path
  """
  while os.path.islink(root + path):
    path = os.path.join(os.path.dirname(path), os.readlink(root + path))
  return path


def _GetFilesForTarget(target, root='/'):
  """Locate all the files to package for |target|

  This does not cover ELF dependencies.

  Args:
    target: The toolchain target name
    root: The root path to pull all packages from

  Returns:
    A tuple of a set of all packable paths, and a set of all paths which
    are also native ELFs
  """
  paths = set()
  elfs = set()

  # Find all the files owned by the packages for this target.
  for pkg in GetTargetPackages(target):

    # Skip Go compiler from redistributable packages.
    # The "go" executable has GOROOT=/usr/lib/go/${CTARGET} hardcoded
    # into it. Due to this, the toolchain cannot be unpacked anywhere
    # else and be readily useful. To enable packaging Go, we need to:
    # -) Tweak the wrappers/environment to override GOROOT
    #    automatically based on the unpack location.
    # -) Make sure the ELF dependency checking and wrapping logic
    #    below skips the Go toolchain executables and libraries.
    # -) Make sure the packaging process maintains the relative
    #    timestamps of precompiled standard library packages.
    #    (see dev-lang/go ebuild for details).
    if pkg == 'ex_go':
      continue

    # Use armv7a-cros-linux-gnueabi/compiler-rt for
    # armv7a-cros-linux-gnueabihf/compiler-rt.
    # Currently the armv7a-cros-linux-gnueabi is actually
    # the same as armv7a-cros-linux-gnueabihf with different names.
    # Because of that, for compiler-rt, it generates the same binary in
    # the same location. To avoid the installation conflict, we do not
    # install anything for 'armv7a-cros-linux-gnueabihf'. This would cause
    # problem if other people try to use standalone armv7a-cros-linux-gnueabihf
    # toolchain.
    if 'compiler-rt' in pkg and 'armv7a-cros-linux-gnueabi' in target:
      atom = GetPortagePackage(target, pkg)
      cat, pn = atom.split('/')
      ver = GetInstalledPackageVersions(atom, root=root)[0]
      dblink = portage.dblink(cat, pn + '-' + ver, myroot=root,
                              settings=portage.settings)
      contents = dblink.getcontents()
      if not contents:
        if 'hf' in target:
          new_target = 'armv7a-cros-linux-gnueabi'
        else:
          new_target = 'armv7a-cros-linux-gnueabihf'
        atom = GetPortagePackage(new_target, pkg)
    else:
      atom = GetPortagePackage(target, pkg)

    cat, pn = atom.split('/')
    ver = GetInstalledPackageVersions(atom, root=root)[0]
    logging.info('packaging %s-%s', atom, ver)

    dblink = portage.dblink(cat, pn + '-' + ver, myroot=root,
                            settings=portage.settings)
    contents = dblink.getcontents()
    for obj in contents:
      ptype = contents[obj][0]
      if not IsPathPackagable(ptype, obj):
        continue

      if ptype == 'obj':
        # For native ELFs, we need to pull in their dependencies too.
        if FileIsCrosSdkElf(obj):
          logging.debug('Adding ELF %s', obj)
          elfs.add(obj)
      logging.debug('Adding path %s', obj)
      paths.add(obj)

  return paths, elfs


def _BuildInitialPackageRoot(output_dir, paths, elfs, ldpaths,
                             path_rewrite_func=lambda x: x, root='/'):
  """Link in all packable files and their runtime dependencies

  This also wraps up executable ELFs with helper scripts.

  Args:
    output_dir: The output directory to store files
    paths: All the files to include
    elfs: All the files which are ELFs (a subset of |paths|)
    ldpaths: A dict of static ldpath information
    path_rewrite_func: User callback to rewrite paths in output_dir
    root: The root path to pull all packages/files from
  """
  # Link in all the files.
  sym_paths = {}
  for path in paths:
    new_path = path_rewrite_func(path)
    logging.debug('Transformed %s to %s', path, new_path)
    dst = output_dir + new_path
    osutils.SafeMakedirs(os.path.dirname(dst))

    # Is this a symlink which we have to rewrite or wrap?
    # Delay wrap check until after we have created all paths.
    src = root + path
    if os.path.islink(src):
      tgt = os.readlink(src)
      if os.path.sep in tgt:
        sym_paths[lddtree.normpath(ReadlinkRoot(src, root))] = new_path

        # Rewrite absolute links to relative and then generate the symlink
        # ourselves.  All other symlinks can be hardlinked below.
        if tgt[0] == '/':
          tgt = os.path.relpath(tgt, os.path.dirname(new_path))
          os.symlink(tgt, dst)
          continue

    logging.debug('Linking path %s -> %s', src, dst)
    os.link(src, dst)

  # Locate all the dependencies for all the ELFs.  Stick them all in the
  # top level "lib" dir to make the wrapper simpler.  This exact path does
  # not matter since we execute ldso directly, and we tell the ldso the
  # exact path to search for its libraries.
  libdir = os.path.join(output_dir, 'lib')
  osutils.SafeMakedirs(libdir)
  donelibs = set()
  basenamelibs = set()
  glibc_re = re.compile(r'/lib(c|pthread)-[0-9.]+\.so$')
  for elf in elfs:
    e = lddtree.ParseELF(elf, root=root, ldpaths=ldpaths)
    logging.debug('Parsed elf %s data: %s', elf, e)
    interp = e['interp']
    # Do not create wrapper for libc. crbug.com/766827
    if interp and not glibc_re.search(elf):
      # Generate a wrapper if it is executable.
      interp = os.path.join('/lib', os.path.basename(interp))
      lddtree.GenerateLdsoWrapper(output_dir, path_rewrite_func(elf), interp,
                                  libpaths=e['rpath'] + e['runpath'])
      FixClangXXWrapper(output_dir, path_rewrite_func(elf))

      # Wrap any symlinks to the wrapper.
      if elf in sym_paths:
        link = sym_paths[elf]
        GeneratePathWrapper(output_dir, link, elf)

    # TODO(crbug.com/917193): Drop this hack once libopcodes linkage is fixed.
    if os.path.basename(elf).startswith('libopcodes-'):
      continue

    for lib, lib_data in e['libs'].items():
      src = path = lib_data['path']
      if path is None:
        logging.warning('%s: could not locate %s', elf, lib)
        continue

      # No need to try and copy the same source lib multiple times.
      if path in donelibs:
        continue
      donelibs.add(path)

      # Die if we try to normalize different source libs with the same basename.
      if lib in basenamelibs:
        logging.error('Multiple sources detected for %s:\n  new: %s\n  old: %s',
                      os.path.join('/lib', lib), path,
                      ' '.join(x for x in donelibs
                               if x != path and os.path.basename(x) == lib))
        # TODO(crbug.com/917193): Make this fatal.
        # cros_build_lib.Die('Unable to resolve lib conflicts')
        continue
      basenamelibs.add(lib)

      # Needed libs are the SONAME, but that is usually a symlink, not a
      # real file.  So link in the target rather than the symlink itself.
      # We have to walk all the possible symlinks (SONAME could point to a
      # symlink which points to a symlink), and we have to handle absolute
      # ourselves (since we have a "root" argument).
      dst = os.path.join(libdir, os.path.basename(path))
      src = ReadlinkRoot(src, root)

      logging.debug('Linking lib %s -> %s', root + src, dst)
      os.link(root + src, dst)


def _EnvdGetVar(envd, var):
  """Given a Gentoo env.d file, extract a var from it

  Args:
    envd: The env.d file to load (may be a glob path)
    var: The var to extract

  Returns:
    The value of |var|
  """
  envds = glob.glob(envd)
  assert len(envds) == 1, '%s: should have exactly 1 env.d file' % envd
  envd = envds[0]
  return key_value_store.LoadFile(envd)[var]


def _ProcessBinutilsConfig(target, output_dir):
  """Do what binutils-config would have done"""
  binpath = os.path.join('/bin', target + '-')

  # Locate the bin dir holding the gold linker.
  binutils_bin_path = os.path.join(output_dir, 'usr', toolchain.GetHostTuple(),
                                   target, 'binutils-bin')
  globpath = os.path.join(binutils_bin_path, '*-gold')
  srcpath = glob.glob(globpath)
  if not srcpath:
    # Maybe this target doesn't support gold.
    globpath = os.path.join(binutils_bin_path, '*')
    srcpath = glob.glob(globpath)
    assert len(srcpath) == 1, ('%s: matched more than one path (but not *-gold)'
                               % globpath)
    srcpath = srcpath[0]
    ld_path = os.path.join(srcpath, 'ld')
    assert os.path.exists(ld_path), '%s: linker is missing!' % ld_path
    ld_path = os.path.join(srcpath, 'ld.bfd')
    assert os.path.exists(ld_path), '%s: linker is missing!' % ld_path
    ld_path = os.path.join(srcpath, 'ld.gold')
    assert not os.path.exists(ld_path), ('%s: exists, but gold dir does not!'
                                         % ld_path)

    # Nope, no gold support to be found.
    gold_supported = False
    logging.warning('%s: binutils lacks support for the gold linker', target)
  else:
    assert len(srcpath) == 1, '%s: did not match exactly 1 path' % globpath
    srcpath = srcpath[0]

    # Package the binutils-bin directory without the '-gold' suffix
    # if gold is not enabled as the default linker for this target.
    gold_supported = CONFIG_TARGET_SUFFIXES['binutils'].get(target) == '-gold'
    if not gold_supported:
      srcpath = srcpath[:-len('-gold')]
      ld_path = os.path.join(srcpath, 'ld')
      assert os.path.exists(ld_path), '%s: linker is missing!' % ld_path

  srcpath = srcpath[len(output_dir):]
  gccpath = os.path.join('/usr', 'libexec', 'gcc')
  for prog in os.listdir(output_dir + srcpath):
    # Skip binaries already wrapped.
    if not prog.endswith('.real'):
      GeneratePathWrapper(output_dir, binpath + prog,
                          os.path.join(srcpath, prog))
      GeneratePathWrapper(output_dir, os.path.join(gccpath, prog),
                          os.path.join(srcpath, prog))

  libpath = os.path.join('/usr', toolchain.GetHostTuple(), target, 'lib')
  envd = os.path.join(output_dir, 'etc', 'env.d', 'binutils', '*')
  if gold_supported:
    envd += '-gold'
  else:
    # If gold is not enabled as the default linker and 2 env.d
    # files exist, pick the one without the '-gold' suffix.
    envds = sorted(glob.glob(envd))
    if len(envds) == 2 and envds[1] == envds[0] + '-gold':
      envd = envds[0]
  srcpath = _EnvdGetVar(envd, 'LIBPATH')
  os.symlink(os.path.relpath(srcpath, os.path.dirname(libpath)),
             output_dir + libpath)


def _ProcessGccConfig(target, output_dir):
  """Do what gcc-config would have done"""
  binpath = '/bin'
  envd = os.path.join(output_dir, 'etc', 'env.d', 'gcc', '*')
  srcpath = _EnvdGetVar(envd, 'GCC_PATH')
  for prog in os.listdir(output_dir + srcpath):
    # Skip binaries already wrapped.
    if (not prog.endswith('.real') and
        not prog.endswith('.elf') and
        prog.startswith(target)):
      GeneratePathWrapper(output_dir, os.path.join(binpath, prog),
                          os.path.join(srcpath, prog))
  return srcpath


def _ProcessSysrootWrappers(_target, output_dir, srcpath):
  """Remove chroot-specific things from our sysroot wrappers"""
  # Disable ccache since we know it won't work outside of chroot.

  # Use the version of the wrapper that does not use ccache.
  for sysroot_wrapper in glob.glob(os.path.join(
      output_dir + srcpath, 'sysroot_wrapper*.ccache')):
    # Can't update the wrapper in place to not affect the chroot,
    # but only the extracted toolchain.
    os.unlink(sysroot_wrapper)
    shutil.copy(sysroot_wrapper[:-6] + 'noccache', sysroot_wrapper)
    shutil.copy(sysroot_wrapper[:-6] + 'noccache.elf', sysroot_wrapper + '.elf')


def _CreateMainLibDir(target, output_dir):
  """Create some lib dirs so that compiler can get the right Gcc paths"""
  osutils.SafeMakedirs(os.path.join(output_dir, 'usr', target, 'lib'))
  osutils.SafeMakedirs(os.path.join(output_dir, 'usr', target, 'usr/lib'))


def _ProcessDistroCleanups(target, output_dir):
  """Clean up the tree and remove all distro-specific requirements

  Args:
    target: The toolchain target name
    output_dir: The output directory to clean up
  """
  _ProcessBinutilsConfig(target, output_dir)
  gcc_path = _ProcessGccConfig(target, output_dir)
  _ProcessSysrootWrappers(target, output_dir, gcc_path)
  _CreateMainLibDir(target, output_dir)

  osutils.RmDir(os.path.join(output_dir, 'etc'))


def CreatePackagableRoot(target, output_dir, ldpaths, root='/'):
  """Setup a tree from the packages for the specified target

  This populates a path with all the files from toolchain packages so that
  a tarball can easily be generated from the result.

  Args:
    target: The target to create a packagable root from
    output_dir: The output directory to place all the files
    ldpaths: A dict of static ldpath information
    root: The root path to pull all packages/files from
  """
  # Find all the files owned by the packages for this target.
  paths, elfs = _GetFilesForTarget(target, root=root)

  # Link in all the package's files, any ELF dependencies, and wrap any
  # executable ELFs with helper scripts.
  def MoveUsrBinToBin(path):
    """Move /usr/bin to /bin so people can just use that toplevel dir

    Note we do not apply this to clang - there is correlation between clang's
    search path for libraries / inclusion and its installation path.
    """
    if path.startswith('/usr/bin/') and path.find('clang') == -1:
      return path[4:]
    return path
  _BuildInitialPackageRoot(output_dir, paths, elfs, ldpaths,
                           path_rewrite_func=MoveUsrBinToBin, root=root)

  # The packages, when part of the normal distro, have helper scripts
  # that setup paths and such.  Since we are making this standalone, we
  # need to preprocess all that ourselves.
  _ProcessDistroCleanups(target, output_dir)


def CreatePackages(targets_wanted, output_dir, root='/'):
  """Create redistributable cross-compiler packages for the specified targets

  This creates toolchain packages that should be usable in conjunction with
  a downloaded sysroot (created elsewhere).

  Tarballs (one per target) will be created in $PWD.

  Args:
    targets_wanted: The targets to package up.
    output_dir: The directory to put the packages in.
    root: The root path to pull all packages/files from.
  """
  logging.info('Writing tarballs to %s', output_dir)
  osutils.SafeMakedirs(output_dir)
  ldpaths = lddtree.LoadLdpaths(root)
  targets = ExpandTargets(targets_wanted)

  with osutils.TempDir(prefix='create-packages') as tempdir:
    logging.debug('Using tempdir: %s', tempdir)

    # We have to split the root generation from the compression stages.  This is
    # because we hardlink in all the files (to avoid overhead of reading/writing
    # the copies multiple times).  But tar gets angry if a file's hardlink count
    # changes from when it starts reading a file to when it finishes.
    with parallel.BackgroundTaskRunner(CreatePackagableRoot) as queue:
      for target in targets:
        output_target_dir = os.path.join(tempdir, target)
        queue.put([target, output_target_dir, ldpaths, root])

    # Build the tarball.
    with parallel.BackgroundTaskRunner(cros_build_lib.CreateTarball) as queue:
      for target in targets:
        tar_file = os.path.join(output_dir, target + '.tar.xz')
        queue.put([tar_file, os.path.join(tempdir, target)])


def GetParser():
  """Return a command line parser."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('-u', '--nousepkg',
                      action='store_false', dest='usepkg', default=True,
                      help='Use prebuilt packages if possible')
  parser.add_argument('-d', '--deleteold',
                      action='store_true', dest='deleteold', default=False,
                      help='Unmerge deprecated packages')
  parser.add_argument('-t', '--targets',
                      dest='targets', default='sdk',
                      help='Comma separated list of tuples. Special keywords '
                           "'host', 'sdk', 'boards', and 'all' are "
                           "allowed. Defaults to 'sdk'.")
  parser.add_argument('--include-boards', default='', metavar='BOARDS',
                      help='Comma separated list of boards whose toolchains we '
                           'will always include. Default: none')
  parser.add_argument('--hostonly',
                      dest='hostonly', default=False, action='store_true',
                      help='Only setup the host toolchain. '
                           'Useful for bootstrapping chroot')
  parser.add_argument('--show-board-cfg', '--show-cfg',
                      dest='cfg_name', default=None,
                      help='Board  to list toolchains tuples for')
  parser.add_argument('--show-packages', default=None,
                      help='List all packages the specified target uses')
  parser.add_argument('--create-packages',
                      action='store_true', default=False,
                      help='Build redistributable packages')
  parser.add_argument('--output-dir', default=os.getcwd(), type='path',
                      help='Output directory')
  parser.add_argument('--reconfig', default=False, action='store_true',
                      help='Reload crossdev config and reselect toolchains')
  parser.add_argument('--sysroot', type='path',
                      help='The sysroot in which to install the toolchains')
  return parser


def main(argv):
  parser = GetParser()
  options = parser.parse_args(argv)
  options.Freeze()

  # Figure out what we're supposed to do and reject conflicting options.
  conflicting_options = (
      options.cfg_name,
      options.show_packages,
      options.create_packages,
  )
  if sum(bool(x) for x in conflicting_options) > 1:
    parser.error('conflicting options: create-packages & show-packages & '
                 'show-board-cfg')

  targets_wanted = set(options.targets.split(','))
  boards_wanted = (set(options.include_boards.split(','))
                   if options.include_boards else set())

  if options.cfg_name:
    ShowConfig(options.cfg_name)
  elif options.show_packages is not None:
    cros_build_lib.AssertInsideChroot()
    target = options.show_packages
    Crossdev.Load(False)
    for package in GetTargetPackages(target):
      print(GetPortagePackage(target, package))
  elif options.create_packages:
    cros_build_lib.AssertInsideChroot()
    Crossdev.Load(False)
    CreatePackages(targets_wanted, options.output_dir)
  else:
    cros_build_lib.AssertInsideChroot()
    # This has to be always run as root.
    if os.geteuid() != 0:
      cros_build_lib.Die('this script must be run as root')

    Crossdev.Load(options.reconfig)
    root = options.sysroot or '/'
    UpdateToolchains(options.usepkg, options.deleteold, options.hostonly,
                     options.reconfig, targets_wanted, boards_wanted,
                     root=root)
    Crossdev.Save()

  return 0
