| #!/bin/bash | |
| # Copyright (c) 2011 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. | |
| . "$(dirname "$0")/common.sh" || exit 1 | |
| # Script must run inside the chroot | |
| restart_in_chroot_if_needed "$@" | |
| assert_not_root_user | |
| # Developer-visible flags. | |
| DEFINE_string board "${DEFAULT_BOARD}" \ | |
| "The board to build packages for." | |
| DEFINE_boolean usepkg "${FLAGS_TRUE}" \ | |
| "Use binary packages to bootstrap when possible." | |
| DEFINE_boolean usepkgonly "${FLAGS_FALSE}" \ | |
| "Only use binary packages to bootstrap; abort if any are missing." | |
| DEFINE_boolean workon "${FLAGS_TRUE}" \ | |
| "Force-build workon packages." | |
| DEFINE_boolean showoutput "${FLAGS_FALSE}" \ | |
| "Show all output from parallel_emerge." | |
| DEFINE_boolean withautotest "${FLAGS_TRUE}" \ | |
| "Build autotest client code." | |
| DEFINE_boolean withdebugsymbols "${FLAGS_FALSE}" \ | |
| "Install the debug symbols for all packages" | |
| DEFINE_string eventfile "${DEFAULT_EVENT_FILE}" \ | |
| "Define the file that event logs will be written." | |
| DEFINE_boolean withrevdeps "${FLAGS_TRUE}" \ | |
| "Calculate reverse dependencies on changed ebuilds." | |
| DEFINE_boolean autosetgov "${FLAGS_FALSE}" \ | |
| "Automatically set cpu governor to 'performance'." | |
| DEFINE_boolean use_any_chrome "${FLAGS_TRUE}" \ | |
| "Use any Chrome prebuilt available, even if the prebuilt doesn't match exactly." | |
| DEFINE_boolean cleanbuild "${FLAGS_FALSE}" \ | |
| "Perform a clean build; delete sysroot if it exists before building." | |
| DEFINE_boolean internal "${FLAGS_FALSE}" \ | |
| "Build the internal version of chrome (set the chrome_internal USE flag)." | |
| # The --board_root flag specifies the environment variables ROOT and PKGDIR. | |
| # This allows fetching and emerging of all packages to specified board_root. | |
| # Note that --board_root will setup the board normally in /build/$BOARD, if it's | |
| # not setup yet. It also expects the toolchain to already be installed in the | |
| # board_root. --usepkgonly and --norebuild are required, because building is not | |
| # supported when board_root is set. | |
| # enforce this)." | |
| DEFINE_string board_root "" \ | |
| "Emerge packages to board_root." | |
| FLAGS_HELP="usage: $(basename $0) [flags] [packages] | |
| build_packages updates the set of binary packages needed by Chrome OS. It will | |
| cross compile all packages that have been updated into the given target's root | |
| and build binary packages as a side-effect. The output packages will be picked | |
| up by the build_image script to put together a bootable Chrome OS image. | |
| If [packages] are specified, only build those specific packages (and any | |
| dependencies they might need). | |
| For the fastest builds, use --nowithautotest --noworkon. | |
| " | |
| # The following options are advanced options, only available to those willing | |
| # to read the source code. They are not shown in help output, since they are | |
| # not needed for the typical developer workflow. | |
| DEFINE_string accept_licenses "" \ | |
| "Licenses to append to the accept list." | |
| DEFINE_integer jobs -1 \ | |
| "How many packages to build in parallel at maximum." | |
| DEFINE_boolean norebuild "${FLAGS_FALSE}" \ | |
| "Don't automatically rebuild dependencies." | |
| DEFINE_boolean skip_chroot_upgrade "${FLAGS_FALSE}" \ | |
| "Don't run the chroot upgrade automatically; use with care." | |
| DEFINE_boolean skip_toolchain_update "${FLAGS_FALSE}" \ | |
| "Don't update toolchain automatically." | |
| DEFINE_boolean withdev "${FLAGS_TRUE}" \ | |
| "Build useful developer friendly utilities." | |
| DEFINE_boolean withdebug "${FLAGS_TRUE}" \ | |
| "Build debug versions of Chromium-OS-specific packages." | |
| DEFINE_boolean withfactory "${FLAGS_TRUE}" \ | |
| "Build factory installer." | |
| DEFINE_boolean withtest "${FLAGS_TRUE}" \ | |
| "Build packages required for testing." | |
| # The --reuse_pkgs_from_local_boards flag tells Portage to share binary | |
| # packages between boards that are built locally, so that the total time | |
| # required to build several boards is reduced. This flag is only useful | |
| # when you are not able to use remote binary packages, since remote binary | |
| # packages are usually more up to date than anything you have locally. | |
| DEFINE_boolean reuse_pkgs_from_local_boards "${FLAGS_FALSE}" \ | |
| "Bootstrap from local packages instead of remote packages." | |
| # --run_goma option is designed to be used on bots. | |
| # If you're trying to build pacakges with goma in your local dev env, this is | |
| # *not* the option you're looking for. Please see comments below. | |
| # This option; 1) starts goma, 2) builds packages (expecting that goma is | |
| # used), then 3) stops goma explicitly. | |
| # 3) is a request from the goma team, so that stats/logs can be taken. | |
| # Note: GOMA_DIR and GOMA_SERVICE_ACCOUNT_JSON_FILE are expected to be passed | |
| # via env var. | |
| # | |
| # In local dev env cases, compiler_proxy is expected to keep running. | |
| # In such a case; | |
| # $ python ${GOMA_DIR}/goma_ctl.py ensure_start | |
| # $ ./build_packages (... and options without --run_goma ...) | |
| # is an expected commandline sequence. If you set --run_goma flag while | |
| # compiler_proxy is already running, the existing compiler_proxy will be | |
| # stopped. | |
| DEFINE_boolean run_goma "${FLAGS_FALSE}" \ | |
| "If set to true, (re)starts goma, builds packages, and then stops goma." | |
| # Parse command line | |
| FLAGS "$@" || exit 1 | |
| eval set -- "${FLAGS_ARGV}" | |
| # Die on any errors. | |
| switch_to_strict_mode | |
| # Chrome packages that need to be treated the same. These are the chrome and | |
| # chrome follow-on packages that share the same version as chrome and are | |
| # updated in lock step. | |
| CHROME_PACKAGES=( | |
| "chromeos-base/chromeos-chrome" | |
| "chromeos-base/chrome-icu" | |
| ) | |
| if [[ "${FLAGS_internal}" -eq "${FLAGS_TRUE}" ]]; then | |
| export USE="${USE} chrome_internal" | |
| fi | |
| # This is a temporary measure to help the goma team check the configs while | |
| # they transition their backend service. | |
| # TODO(crbug.com/1032290): Delete after the goma RBE transition is complete. | |
| if [[ "${FLAGS_run_goma}" -eq "${FLAGS_TRUE}" ]]; then | |
| info "Environment:" | |
| env | |
| info "End Environment." | |
| fi | |
| # Right now build_packages has to be run from scripts/ | |
| . ${SRC_ROOT}/third_party/chromiumos-overlay/chromeos/config/chromeos_version.sh | |
| # On some systems, powersave can take a long time to ramp up. Inform the user | |
| # so they can get faster builds. https://crbug.com/1008932 | |
| if grep -qs powersave \ | |
| /sys/devices/system/cpu/cpufreq/policy*/scaling_governor; then | |
| # Make sure we can actually support "performance". | |
| if grep -qs performance \ | |
| /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors; then | |
| if [[ "${FLAGS_autosetgov}" -eq "${FLAGS_TRUE}" ]]; then | |
| info "Temporarily setting cpu governor to 'performance'" | |
| trap "sudo cpupower -c all frequency-set -g powersave >&/dev/null" EXIT | |
| sudo cpupower -c all frequency-set -g performance >&/dev/null | |
| else | |
| warn "Current CPU governor set to 'powersave' which can slow down builds." | |
| warn "Use --autosetgov to automatically (and temporarily) switch to" \ | |
| "'performance'." | |
| fi | |
| fi | |
| fi | |
| if [[ -z "${FLAGS_board}" ]]; then | |
| echo "Error: --board is required." | |
| exit 1 | |
| fi | |
| # Before we can run any tools, we need to update chroot or setup_board. | |
| UPDATE_ARGS=() | |
| if [[ -n ${FLAGS_accept_licenses} ]]; then | |
| UPDATE_ARGS+=( --accept-licenses "${FLAGS_accept_licenses}" ) | |
| fi | |
| if [ "${FLAGS_usepkg}" -eq "${FLAGS_TRUE}" ]; then | |
| UPDATE_ARGS+=( --usepkg ) | |
| else | |
| UPDATE_ARGS+=( --nousepkg ) | |
| fi | |
| if [[ "${FLAGS_jobs}" -ne -1 ]]; then | |
| UPDATE_ARGS+=( --jobs=${FLAGS_jobs} ) | |
| fi | |
| if [ "${FLAGS_reuse_pkgs_from_local_boards}" -eq "${FLAGS_TRUE}" ]; then | |
| UPDATE_ARGS+=( --reuse-pkgs-from-local-boards ) | |
| fi | |
| if [ "${FLAGS_skip_toolchain_update}" -eq "${FLAGS_TRUE}" ]; then | |
| UPDATE_ARGS+=( --skip-toolchain-update ) | |
| fi | |
| if [ "${FLAGS_skip_chroot_upgrade}" -eq "${FLAGS_TRUE}" ]; then | |
| UPDATE_ARGS+=( --skip-chroot-upgrade ) | |
| fi | |
| if [[ -n ${FLAGS_board_root} ]]; then | |
| UPDATE_ARGS+=( --board-root "${FLAGS_board_root}" ) | |
| fi | |
| if [ "${FLAGS_cleanbuild}" -eq "${FLAGS_TRUE}" ]; then | |
| UPDATE_ARGS+=( --force ) | |
| fi | |
| setup_board --quiet --board=${FLAGS_board} "${UPDATE_ARGS[@]}" | |
| sudo_clear_shadow_locks "/build/${FLAGS_board}" | |
| PORTAGE_BINHOST=$(portageq-${FLAGS_board} envvar 'PORTAGE_BINHOST') | |
| info "PORTAGE_BINHOST: ${PORTAGE_BINHOST}" | |
| # Setup all the emerge command/flags. | |
| EMERGE_FLAGS=( -uDNv --backtrack=30 --newrepo ) | |
| EMERGE_CMD=( | |
| "${CHROMITE_BIN}/parallel_emerge" | |
| --board=${FLAGS_board} | |
| ) | |
| if [[ "${FLAGS_use_any_chrome}" -eq "${FLAGS_TRUE}" ]]; then | |
| for pkg in "${CHROME_PACKAGES[@]}"; do | |
| EMERGE_CMD+=( "--force-remote-binary=${pkg}" ) | |
| done | |
| fi | |
| EMERGE_CMD+=( ${EXTRA_BOARD_FLAGS} ) | |
| if [[ "${FLAGS_usepkg}" -eq "${FLAGS_TRUE}" || | |
| "${FLAGS_reuse_pkgs_from_local_boards}" -eq "${FLAGS_TRUE}" || | |
| "${FLAGS_usepkgonly}" -eq "${FLAGS_TRUE}" ]]; then | |
| # Use binary packages. Include all build-time dependencies, | |
| # so as to avoid unnecessary differences between source | |
| # and binary builds. | |
| EMERGE_FLAGS+=( --getbinpkg --with-bdeps y ) | |
| if [[ ${FLAGS_usepkgonly} -eq ${FLAGS_TRUE} ]]; then | |
| EMERGE_FLAGS+=( --usepkgonly ) | |
| else | |
| EMERGE_FLAGS+=( --usepkg ) | |
| fi | |
| fi | |
| if [[ "${FLAGS_jobs}" -ne -1 ]]; then | |
| EMERGE_FLAGS+=( --jobs=${FLAGS_jobs} ) | |
| fi | |
| if [[ "${FLAGS_norebuild}" -eq "${FLAGS_FALSE}" ]]; then | |
| EMERGE_FLAGS+=( --rebuild-if-new-rev ) | |
| fi | |
| if [[ "${FLAGS_showoutput}" -eq "${FLAGS_TRUE}" ]]; then | |
| EMERGE_FLAGS+=( --show-output ) | |
| fi | |
| if [[ "${FLAGS_withdebug}" -eq "${FLAGS_FALSE}" ]]; then | |
| export USE="${USE} -cros-debug" | |
| fi | |
| # Figure out which packages we should be building. | |
| PACKAGES=( "$@" ) | |
| # Force rebuild chromeos-config because it is extremely cheap, and we do not | |
| # want to reuse stale configs. | |
| FORCE_LOCAL_BUILD_PKGS=( chromeos-base/chromeos-config ) | |
| if [[ $# -eq 0 ]]; then | |
| PACKAGES=( virtual/target-os ) | |
| if [[ "${FLAGS_withdev}" -eq "${FLAGS_TRUE}" ]]; then | |
| PACKAGES+=( virtual/target-os-dev ) | |
| fi | |
| if [[ "${FLAGS_withfactory}" -eq "${FLAGS_TRUE}" ]]; then | |
| PACKAGES+=( virtual/target-os-factory ) | |
| PACKAGES+=( virtual/target-os-factory-shim ) | |
| fi | |
| if [[ "${FLAGS_withtest}" -eq "${FLAGS_TRUE}" ]]; then | |
| PACKAGES+=( virtual/target-os-test ) | |
| # chromeos-ssh-testkeys may generate ssh keys if the right USE flag is set. | |
| # We force rebuilding this package from source every time, so that | |
| # consecutive builds don't share ssh keys. | |
| FORCE_LOCAL_BUILD_PKGS+=( chromeos-base/chromeos-ssh-testkeys ) | |
| fi | |
| if [[ "${FLAGS_withautotest}" -eq "${FLAGS_TRUE}" ]]; then | |
| PACKAGES+=( chromeos-base/autotest-all ) | |
| fi | |
| fi | |
| info "Rebuilding Portage cache" | |
| # Before running any emerge operations, regenerate the Portage dependency cache | |
| # in parallel. | |
| "${EMERGE_CMD[@]}" --regen --quiet | |
| # Verify that all packages can be emerged from scratch, without any | |
| # backtracking. Only print the output if this step fails. | |
| info "Checking package dependencies are correct: ${PACKAGES[*]}" | |
| if ! OUTPUT=$(emerge-${FLAGS_board} -pe --backtrack=0 \ | |
| "${PACKAGES[@]}" 2>&1); then | |
| printf "%s\n" "${OUTPUT}" | |
| die_notrace "emerge detected broken ebuilds. See error message above." | |
| fi | |
| # Build cros_workon packages when they are changed. | |
| CROS_WORKON_PKGS=() | |
| if [ "${FLAGS_workon}" -eq "${FLAGS_TRUE}" ]; then | |
| LIST_MODIFIED_PACKAGES="${CHROMITE_BIN}/cros_list_modified_packages" | |
| MODIFIED_PACKAGES=( $("${LIST_MODIFIED_PACKAGES}" --board=${FLAGS_board}) ) | |
| info "cros_workon modified packages '${MODIFIED_PACKAGES[*]}' detected" | |
| CROS_WORKON_PKGS+=( "${MODIFIED_PACKAGES[@]}" ) | |
| # TODO(anush): Make chrome a fake cros-workon package. | |
| if [[ -n "${CHROME_ORIGIN}" ]]; then | |
| CROS_WORKON_PKGS+=( "${CHROME_PACKAGES[@]}" ) | |
| fi | |
| fi | |
| # cros_workon packages always have to be rebuilt. | |
| FORCE_LOCAL_BUILD_PKGS+=( "${CROS_WORKON_PKGS[@]}" ) | |
| # Any package that directly depends on an active cros_workon package also needs | |
| # to be rebuilt in order to be correctly built against the current set of | |
| # changes a user may have made to the cros_workon package. | |
| if [[ ${#CROS_WORKON_PKGS[@]} -gt 0 ]]; then | |
| # Collect all installed packages that depend on active cros_workon packages. | |
| WORKON_PKG_CONSUMERS=() | |
| mapfile -t WORKON_PKG_CONSUMERS < <( \ | |
| equery-${FLAGS_board} -q depends "${CROS_WORKON_PKGS[@]}" | \ | |
| sort -u | \ | |
| grep -Ev "^\s*$" ) | |
| # Transform this list of packages with versions in to a list of just | |
| # $CATEGORY/$NAME entries, since we don't want to pass packages with explicit | |
| # version numbers as arguments to `emerge`. | |
| if [[ ${#WORKON_PKG_CONSUMERS[@]} -gt 0 ]]; then | |
| WORKON_REBUILD_PKGS=() | |
| mapfile -t WORKON_REBUILD_PKGS < <( \ | |
| equery-${FLAGS_board} list -p -o --format='$category/$name' \ | |
| "${WORKON_PKG_CONSUMERS[@]}" | sort -u ) | |
| info "The following packages depend directly on an active" \ | |
| "cros_workon package and will be rebuilt: ${WORKON_REBUILD_PKGS[*]}" | |
| FORCE_LOCAL_BUILD_PKGS+=( "${WORKON_REBUILD_PKGS[@]}" ) | |
| fi | |
| fi | |
| if [[ -n "${FLAGS_board_root}" ]]; then | |
| export ROOT="${FLAGS_board_root}" | |
| export PORTAGE_CONFIGROOT="${ROOT}" | |
| export SYSROOT="${ROOT}" | |
| export PKGDIR="${ROOT}"/packages | |
| fi | |
| # Temporarily modify the emerge flags so we can calculate the revdeps | |
| # on the modified packages. | |
| if [[ "${FLAGS_withrevdeps}" -eq "${FLAGS_TRUE}" ]]; then | |
| info "starting reverse dependency calculations ..." | |
| SIM_EMERGE_FLAGS=( "${EMERGE_FLAGS[@]}" --pretend --columns ) | |
| if [[ ${#PACKAGES[@]} -gt 0 ]]; then | |
| SIM_EMERGE_FLAGS+=( | |
| --reinstall-atoms="${PACKAGES[*]}" | |
| --usepkg-exclude="${PACKAGES[*]}" | |
| ) | |
| fi | |
| # cros-workon packages are always going to be force reinstalled, so we add | |
| # the forced reinstall behavior to the modified package calculation. This is | |
| # necessary to include when a user has already installed a 9999 ebuild and is | |
| # now reinstalling that package with additional local changes, because | |
| # otherwise the modified package calculation would not see that a 'new' | |
| # package is being installed. | |
| if [[ ${#CROS_WORKON_PKGS[@]} -gt 0 ]]; then | |
| SIM_EMERGE_FLAGS+=( | |
| --reinstall-atoms="${CROS_WORKON_PKGS[*]}" | |
| --usepkg-exclude="${CROS_WORKON_PKGS[*]}" | |
| ) | |
| fi | |
| # Calculate only the ebuild changes from the emerge simulation ignoring | |
| # the virtual packages and the forced rebuild of autotest-all package. | |
| # The lines of the following block do the following operations: | |
| # 1. Do a pretend `emerge` command to get a list of what would be built. | |
| # 2. Filter to only packages that will be installed to the board sysroot. | |
| # 3. Filter to only packages that would be built from source and rewrite the | |
| # line from Portage's full output to only $CATEGORY/$PACKAGE | |
| # 4. Filter the list of packages to a heuristic set of packages known to have | |
| # incorrectly specified dependencies. | |
| # 5. Sort the output and remove any duplicate entries. | |
| BASE_INSTALL_PKGS=( $( \ | |
| sudo -E "${EMERGE_CMD[@]}" "${SIM_EMERGE_FLAGS[@]}" "${PACKAGES[@]}" | \ | |
| grep -e 'to /build/' | \ | |
| sed -n -E '/^\[ebuild /{s:^[^]]+\] +::;s: .*::;p}' | \ | |
| grep -E '/(chromeos-config.*|coreboot-private-files.*|tast-build-deps)$' | \ | |
| sort -u ) ) | |
| MOD_PKGS=() | |
| if [[ "${#BASE_INSTALL_PKGS[@]}" -gt 0 ]]; then | |
| info "Forced rebuild packages detected: ${BASE_INSTALL_PKGS[*]}." | |
| # Convert specific versions into base package names | |
| MOD_PKGS+=( $(\ | |
| equery-${FLAGS_board} list -p -o --format='$category/$name' \ | |
| "${BASE_INSTALL_PKGS[@]}" | sort -u ) ) | |
| # Remove Chrome as rebuilding it is expensive and almost never makes sense. | |
| # Ignore grep exit status in case chromeos-chrome is the only package. | |
| grep_cmd=( grep -v ) | |
| for pkg in "${CHROME_PACKAGES[@]}"; do | |
| grep_cmd+=( -e "${pkg}" ) | |
| done | |
| MOD_PKGS=( $(printf '%s\n' "${MOD_PKGS[@]}" | "${grep_cmd[@]}" || :) ) | |
| fi | |
| FORCE_LOCAL_BUILD_PKGS+=( "${MOD_PKGS[@]}" ) | |
| if [[ "${#MOD_PKGS[@]}" -gt 0 ]]; then | |
| info "calculating reverse dependencies on packages: ${MOD_PKGS[*]}" | |
| REV_DEPS=( $(\ | |
| equery-${FLAGS_board} -q depends --indirect "${MOD_PKGS[@]}" |\ | |
| awk '{print $1}' | grep -v ^virtual/ | sort -u) ) | |
| if [[ "${#REV_DEPS[@]}" -gt 0 ]]; then | |
| # Convert specific versions into base package names | |
| RMOD_PKGS=( $(\ | |
| equery-${FLAGS_board} -q list -p -o --format='$category/$name' \ | |
| "${REV_DEPS[@]}" | sort -u ) ) | |
| # Remove Chrome as rebuilding it is expensive and almost never makes | |
| # sense. Ignore grep exit status in case chromeos-chrome is the only | |
| # package. | |
| grep_cmd=( grep -v ) | |
| for pkg in "${CHROME_PACKAGES[@]}"; do | |
| grep_cmd+=( -e "${pkg}" ) | |
| done | |
| RMOD_PKGS=( $(printf '%s\n' "${RMOD_PKGS[@]}" | "${grep_cmd[@]}" || :) ) | |
| info "final reverse dependencies that will be rebuilt: ${RMOD_PKGS[*]}" | |
| FORCE_LOCAL_BUILD_PKGS+=( "${RMOD_PKGS[@]}" ) | |
| fi | |
| fi | |
| fi # end FLAGS_withrevdeps | |
| if [[ ${#FORCE_LOCAL_BUILD_PKGS[@]} -gt 0 ]]; then | |
| EMERGE_FLAGS+=( | |
| --reinstall-atoms="${FORCE_LOCAL_BUILD_PKGS[*]}" | |
| --usepkg-exclude="${FORCE_LOCAL_BUILD_PKGS[*]}" | |
| ) | |
| fi | |
| # A list of critical system packages that should never be incidentally | |
| # reinstalled as a side effect of build_packages. All packages in this list | |
| # are special cased to prefer matching installed versions, overriding the | |
| # typical logic of upgrading to the newest available version. | |
| # | |
| # This list can't include any package that gets installed to a board! | |
| # Packages such as LLVM or binutils must not be in this list as the normal | |
| # rebuild logic must still apply to them for board targets. | |
| # | |
| # TODO(crbug/1050752): Remove this list and the corresponding arguments | |
| # to `emerge` below once we figure out how to exclude toolchain packages from | |
| # being upgraded transitively via BDEPEND relations. | |
| CRITICAL_SDK_PACKAGES=( | |
| "dev-lang/rust" | |
| "sys-libs/glibc" | |
| "sys-devel/gcc" | |
| ) | |
| info "Merging board packages now" | |
| ( | |
| # Support goma on bots. This has to run in subshell, otherwise EXIT trap | |
| # handler is overwritten. | |
| if [[ "${FLAGS_run_goma}" -eq "${FLAGS_TRUE}" ]]; then | |
| info "Starting goma compiler_proxy." | |
| goma_ctl="${GOMA_DIR:-${HOME}/goma}/goma_ctl.py" | |
| "${goma_ctl}" restart | |
| trap "'${goma_ctl}' stop" EXIT | |
| fi | |
| sudo -E "${EMERGE_CMD[@]}" "${EMERGE_FLAGS[@]}" "${PACKAGES[@]}" \ | |
| --useoldpkg-atoms="${CRITICAL_SDK_PACKAGES[*]}" \ | |
| --rebuild-exclude="${CRITICAL_SDK_PACKAGES[*]}" | |
| ) | |
| echo "Builds complete" | |
| if [[ ${FLAGS_withdebugsymbols} -eq ${FLAGS_TRUE} ]]; then | |
| info "fetching the debug symbols" | |
| sudo -E "${CHROMITE_BIN}/cros_install_debug_syms" \ | |
| "--board=${FLAGS_board}" "--all" | |
| fi | |
| command_completed | |
| echo "Done" |