blob: 785f8fc60fc640ad27402751d2721f7c38215db0 [file] [log] [blame]
# Copyright (c) 2010 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.
# Script that emerges packages and their dependencies from a host development
# machine onto a target Chromium OS device
# NOTE: This script must be run from the chromiumos build chroot environment.
# Load common constants. This should be the first executable line.
# The path to should be relative to your script's location.
. /usr/lib/crosutils/ 2> /dev/null ||
(echo "Must run from within the chroot" && false) ||
exit 1
# Flags
DEFINE_string board "$DEFAULT_BOARD" \
"The board to build packages for."
DEFINE_boolean usepkg $FLAGS_FALSE \
"Use binary packages to bootstrap build when possible."
DEFINE_string build_root "/build" \
"The root location for board sysroots."
DEFINE_integer jobs -1 \
"How many packages to build in parallel at maximum."
DEFINE_boolean unmerge $FLAGS_FALSE \
"Whether to unmerge the package versus emerge it."
DEFINE_integer retries -1 \
"On build failure, the number of times to retry"
DEFINE_boolean onstatefuldev $FLAGS_TRUE \
"Build packages and install them into stateful partition on device."
DEFINE_boolean installmask $FLAGS_TRUE \
"Use INSTALL_MASK to shrink the resulting image."
DEFINE_string remote "" "remote hostname/IP of running Chromium OS instance"
# Parse command line
FLAGS_HELP="usage: $0 [flags]"
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Die on any errors.
set -e
# Checks $1 and prints out $2 is required before exiting if $1 does not exist
check_args() {
if [ -z "${1}" ] ; then
echo "Error: ${2} is required."
exit 1
# Clean up function for mount point
cleanup_sshfs_mount() {
echo "Cleaning up mount point"
sudo umount "${REMOTE_ROOT_DIR}"
check_args "${FLAGS_board}"
check_args "${FLAGS_ARGV}" "Emerge package name"
[[ $FLAGS_usepkg -eq $FLAGS_TRUE ]] &&
EMERGE_FLAGS="${EMERGE_FLAGS} --getbinpkg --usepkg --with-bdeps y"
[[ ${FLAGS_installmask} -eq ${FLAGS_TRUE} ]] && \
[[ ${FLAGS_jobs} -ne -1 ]] && EMERGE_JOBS="--jobs=${FLAGS_jobs}"
# Duplicate from build_packages to get host packages on system.
# Skip building on host if we are unmerging.
if [ ${FLAGS_unmerge} -eq ${FLAGS_FALSE} ] ; then
eretry sudo emerge -uDNv $EMERGE_FLAGS world
# Build request and install them onto the sysroot
for emerge_request in $FLAGS_ARGV; do
eretry sudo emerge-${FLAGS_board} -uDNv \
$(remove_quotes "${emerge_request}")
# Name is unique per client. This allows one to run gmergefs in parallel
# with multiple clients.
# Default is to install on stateful dev, otherwise install on root.
[ ${FLAGS_onstatefuldev} -eq $FLAGS_TRUE ] && \
# Create directory for remote image
sudo mkdir -p "${REMOTE_ROOT_DIR}"
# Mount remote fs into chroot
echo "Enter password for remote machine"
sudo sshfs -o idmap=user -o allow_other -o nonempty -o transform_symlinks \
"root@${FLAGS_remote}:/" "${REMOTE_ROOT_DIR}"
trap cleanup_sshfs_mount EXIT
# Ensure root path is created for emerge
sudo mkdir -p "${REMOTE_PATH}"
# Same arguments used in build_image to emerge these packages onto the target
for emerge_request in $FLAGS_ARGV; do
if [ ${FLAGS_unmerge} -eq ${FLAGS_FALSE} ] ; then
sudo INSTALL_MASK="$INSTALL_MASK" emerge-${FLAGS_board} \
--root="${REMOTE_PATH}" --root-deps=rdeps \
--usepkgonly $(remove_quotes "${emerge_request}") $EMERGE_JOBS
sudo emerge-${FLAGS_board} --unmerge \
--root="${REMOTE_PATH}" $(remove_quotes "${emerge_request}")
# Update of root partition if installing to /usr/local
if [ ${FLAGS_onstatefuldev} -eq $FLAGS_TRUE ] ; then
# Re-run ldconfig to fix /etc/
sudo /sbin/ldconfig -r "${REMOTE_ROOT_DIR}"
sudo umount "${REMOTE_ROOT_DIR}"
trap - EXIT