Add cros_generate_sysroot script.
The script generates a sysroot tarball containing the build dependencies
of any package. The first use is for generating a sysroot for building
chromeos-base/chromeos-chrome. This allows Chrome devs to build Chrome
for ChromeOS without downloading ChromeOS source code or setting up a
chroot - see goto/simple-chrome.
BUG=chromium-os:36299
TEST=Unit tests, manually.
Change-Id: I14c6be0de673699f2f888421bef06c4f1da001da
Reviewed-on: https://gerrit.chromium.org/gerrit/38265
Tested-by: Ryan Cui <rcui@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Ready: Ryan Cui <rcui@chromium.org>
diff --git a/scripts/cros_generate_sysroot.py b/scripts/cros_generate_sysroot.py
new file mode 100644
index 0000000..b86bbbf
--- /dev/null
+++ b/scripts/cros_generate_sysroot.py
@@ -0,0 +1,116 @@
+#!/usr/bin/python
+# 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.
+"""
+
+import os
+
+from chromite.buildbot import constants
+from chromite.lib import cros_build_lib
+from chromite.lib import commandline
+from chromite.lib import osutils
+from chromite.lib import sudo
+
+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 package to generate the sysroot for.'))
+ parser.add_argument('--out-dir', type=osutils.ExpandPath, required=True,
+ help='Directory to place the generated tarball.')
+ parser.add_argument('--out-file',
+ help=('The name to give to the tarball. Defaults to %r.'
+ % DEFAULT_NAME))
+ options = parser.parse_args(argv)
+
+ if not options.out_file:
+ options.out_file = DEFAULT_NAME % {
+ 'package': options.package.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
+
+ Arguments:
+ sysroot: Path to sysroot.
+ options: Parsed options.
+ """
+ self.sysroot = sysroot
+ self.options = options
+
+ def _InstallToolchain(self):
+ cros_build_lib.RunCommand(
+ [os.path.join(constants.CROSUTILS_DIR, 'install_toolchain'),
+ '--noconfigure', '--board_root', self.sysroot, '--board',
+ self.options.board])
+
+ def _InstallKernelHeaders(self):
+ cros_build_lib.SudoRunCommand(
+ [self.PARALLEL_EMERGE, '--board=%s' % self.options.board,
+ '--root-deps=rdeps', '--getbinpkg', '--usepkg',
+ '--root=%s' % self.sysroot, 'sys-kernel/linux-headers'])
+
+ def _InstallBuildDependencies(self):
+ cros_build_lib.SudoRunCommand(
+ [self.PARALLEL_EMERGE, '--board=%s' % self.options.board,
+ '--root=%s' % self.sysroot, '--usepkg', '--onlydeps',
+ '--usepkg-exclude=%s' % self.options.package, self.options.package])
+
+ def _CreateTarball(self):
+ xz = cros_build_lib.FindCompressor(cros_build_lib.COMP_XZ)
+ cros_build_lib.SudoRunCommand(
+ ['tar', '-I', xz, '-cf',
+ os.path.join(self.options.out_dir, self.options.out_file), '.'],
+ cwd=self.sysroot)
+
+ 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)
+
+ if not cros_build_lib.IsInsideChroot():
+ cros_build_lib.Die("This needs to be run inside the chroot")
+
+ with sudo.SudoKeepAlive(ttyless_sudo=False):
+ with osutils.TempDirContextManager(sudo_rm=True) as tempdir:
+ sysroot = os.path.join(tempdir, SYSROOT)
+ os.mkdir(sysroot)
+ GenerateSysroot(sysroot, options).Perform()