blob: 867f015da52812a3b39a4318ea674131674e8f67 [file] [log] [blame]
# -*- 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.
"""Generates a sysroot tarball for building a specific package.
Meant for use after setup_board and build_packages have been run.
"""
from __future__ import print_function
import os
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import commandline
from chromite.lib import osutils
from chromite.lib import sudo
from chromite.lib import sysroot_lib
from chromite.lib import toolchain
DEFAULT_NAME = 'sysroot_%(package)s.tar.xz'
PACKAGE_SEPARATOR = '/'
SYSROOT = 'sysroot'
def ParseCommandLine(argv):
"""Parse args, and run environment-independent checks."""
parser = commandline.ArgumentParser(description=__doc__)
parser.add_argument('--board', required=True,
help='The board to generate the sysroot for.')
parser.add_argument('--package', required=True,
help='The packages to generate the sysroot for.')
parser.add_argument('--deps-only', action='store_true',
default=False,
help='Build dependencies only.')
parser.add_argument('--out-dir', type='path', required=True,
help='Directory to place the generated tarball.')
parser.add_argument('--out-file', default=DEFAULT_NAME,
help='The name to give to the tarball. '
'Defaults to %(default)s.')
options = parser.parse_args(argv)
options.out_file %= {
'package': options.package.split()[0].replace(PACKAGE_SEPARATOR, '_'),
}
return options
class GenerateSysroot(object):
"""Wrapper for generation functionality."""
PARALLEL_EMERGE = os.path.join(constants.CHROMITE_BIN_DIR, 'parallel_emerge')
def __init__(self, sysroot, options):
"""Initialize
Args:
sysroot: Path to sysroot.
options: Parsed options.
"""
self.sysroot = sysroot
self.options = options
self.extra_env = {'ROOT': self.sysroot, 'USE': os.environ.get('USE', '')}
def _Emerge(self, *args, **kwargs):
"""Emerge the given packages using parallel_emerge."""
cmd = [self.PARALLEL_EMERGE, '--board=%s' % self.options.board,
'--usepkgonly', '--noreplace'] + list(args)
kwargs.setdefault('extra_env', self.extra_env)
cros_build_lib.SudoRunCommand(cmd, **kwargs)
def _InstallToolchain(self):
# Create the sysroot's config.
sysroot = sysroot_lib.Sysroot(self.sysroot)
sysroot.WriteConfig(sysroot.GenerateBoardSetupConfig(self.options.board))
toolchain.InstallToolchain(sysroot, configure=False)
def _InstallKernelHeaders(self):
self._Emerge('sys-kernel/linux-headers')
def _InstallBuildDependencies(self):
# Calculate buildtime deps that are not runtime deps.
raw_sysroot = cros_build_lib.GetSysroot(board=self.options.board)
packages = []
if not self.options.deps_only:
packages = self.options.package.split()
else:
for pkg in self.options.package.split():
cmd = ['qdepends', '-q', '-C', pkg]
output = cros_build_lib.RunCommand(
cmd, extra_env={'ROOT': raw_sysroot}, capture_output=True).output
if output.count('\n') > 1:
raise AssertionError('Too many packages matched for given pattern')
# qdepend outputs "package: deps", so only grab the deps.
deps = output.partition(':')[2].split()
packages.extend(deps)
# Install the required packages.
if packages:
self._Emerge(*packages)
def _CreateTarball(self):
target = os.path.join(self.options.out_dir, self.options.out_file)
cros_build_lib.CreateTarball(target, self.sysroot, sudo=True)
def Perform(self):
"""Generate the sysroot."""
self._InstallToolchain()
self._InstallKernelHeaders()
self._InstallBuildDependencies()
self._CreateTarball()
def FinishParsing(options):
"""Run environment dependent checks on parsed args."""
target = os.path.join(options.out_dir, options.out_file)
if os.path.exists(target):
cros_build_lib.Die('Output file %r already exists.' % target)
if not os.path.isdir(options.out_dir):
cros_build_lib.Die(
'Non-existent directory %r specified for --out-dir' % options.out_dir)
def main(argv):
options = ParseCommandLine(argv)
FinishParsing(options)
cros_build_lib.AssertInsideChroot()
with sudo.SudoKeepAlive(ttyless_sudo=False):
with osutils.TempDir(set_global=True, sudo_rm=True) as tempdir:
sysroot = os.path.join(tempdir, SYSROOT)
os.mkdir(sysroot)
GenerateSysroot(sysroot, options).Perform()