| #!/bin/bash |
| # Copyright 2017 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. |
| |
| # Loads script libraries. |
| CONTRIB_DIR=$(dirname "$(readlink -f "$0")") |
| . "${CONTRIB_DIR}/common.sh" || exit 1 |
| |
| FLAGS_HELP=" |
| Command to rebuild firmware after a config change. |
| |
| After you make a change to the firmware version in the master configuration, |
| run this script to test it. It will rebuild the master configuration, update |
| the Manifest and build the new firmware. You can then submit your CL to update |
| the master configuration, safe in the knowledge that you have tested it. |
| |
| Usage: |
| cros_update_firmware <board> [project] |
| |
| where <board> is the board whose firmware needs updating (e.g. 'coral'). |
| [project] is the project the board belongs to. |
| " |
| |
| # Flags |
| DEFINE_string board "${DEFAULT_BOARD}" "Which board the firmware is for" b |
| DEFINE_string project "${DEFAULT_PROJECT}" "Which project this board is for" p |
| DEFINE_boolean quiet "${FLAGS_FALSE}" "Reduce emerge build output" q |
| DEFINE_boolean append_srcuris "${FLAGS_TRUE}" "Only applicable when the project |
| flag is set. Append firmware uris to srcuris instead of overwriting. This is |
| usually needed if you have limited access to project config repos, so |
| overwriting would delete some uris." |
| |
| # Parse command line. |
| FLAGS "$@" || exit 1 |
| eval set -- "${FLAGS_ARGV}" |
| set -e |
| |
| # Script must be run inside the chroot. |
| assert_inside_chroot |
| |
| start_workon() { |
| local board="$1" |
| local pkg item |
| if [[ -z "$2" ]]; then |
| echo "Empty package. Skipping..." |
| return 1 |
| fi |
| pkg=$(cros workon --board="${board}" info "$2" | cut -d ' ' -f 1) |
| shift 2 |
| for item in "$@"; do |
| if [[ "${pkg}" == "${item}" ]]; then |
| echo "Already workon ${pkg}. Skipping..." |
| return 1 |
| fi |
| done |
| cros workon --board="${board}" start "${pkg}" |
| return $? |
| } |
| |
| stop_workon() { |
| cros workon --board="$1" stop "$2" |
| } |
| |
| update_firmware() { |
| local board="$1" |
| local project="$2" |
| local base ebuild srcuris cfg_bsp_pkg cfg_bsp_baseboard_pkg |
| local current_workon_pkg_list start_pkg result i quiet |
| [[ "$3" == "${FLAGS_TRUE}" ]] && quiet="--quiet-build" |
| local append_srcuris="$4" |
| |
| set -e |
| |
| # query the current working package |
| mapfile -t current_workon_pkg_list < <(cros workon --board="${board}" list) |
| |
| # check if chromeos-config-bsp is a virtual package |
| cfg_bsp_pkg="chromeos-config-bsp" |
| equery-"${board}" w chromeos-base/chromeos-config-bsp > /dev/null 2>&1 \ |
| || cfg_bsp_pkg="chromeos-config-bsp-${board}-private" |
| # check if chromeos-config-bsp-baseboard is in use |
| cfg_bsp_baseboard_pkg="chromeos-config-bsp-baseboard" |
| equery-"${board}" w chromeos-base/chromeos-config-bsp-baseboard \ |
| > /dev/null 2>&1 || cfg_bsp_baseboard_pkg= |
| |
| start_pkg=("${cfg_bsp_pkg}") |
| start_pkg+=("chromeos-firmware-${board}") |
| start_pkg+=("${cfg_bsp_baseboard_pkg}") |
| |
| for i in "${!start_pkg[@]}"; do |
| result[i]=0 |
| start_workon "${board}" "${start_pkg[i]}" "${current_workon_pkg_list[@]}" \ |
| || result[i]=$? |
| done |
| |
| overlay="${GCLIENT_ROOT}/src/private-overlays/overlay-${board}-private" |
| metadata="${overlay}/metadata" |
| edb_cache="/var/cache/edb/dep/mnt/host/source/src/private-overlays/overlay-${board}-private" |
| base="${overlay}/chromeos-base" |
| ebuild="${base}/chromeos-firmware-${board}/chromeos-firmware-${board}-9999.ebuild" |
| srcuris="${base}/chromeos-firmware-${board}/files/srcuris" |
| yaml_config="/build/${board}/usr/share/chromeos-config/yaml/config.yaml" |
| |
| # Check project config repo exists -- if so generate the config first. |
| if [[ -d "${GCLIENT_ROOT}/src/project/${project}" ]]; then |
| pushd "${GCLIENT_ROOT}/src/project/${project}" > /dev/null |
| for brd in *; do |
| if [[ -d "${brd}" && -x "${brd}/config/bin/gen_config" && -f "${brd}/config.star" ]]; then |
| pushd "${brd}" > /dev/null |
| ./config/bin/gen_config config.star |
| popd > /dev/null |
| fi |
| done |
| popd > /dev/null |
| fi |
| |
| "emerge-${board}" -j ${quiet} ${cfg_bsp_baseboard_pkg} "${cfg_bsp_pkg}" chromeos-config |
| |
| # If the append_srcuris and project flags are set, append uris that aren't |
| # already in srcuris. Otherwise, overwrite srcuris. |
| if [[ -n "${project}" && "${append_srcuris}" == "${FLAGS_TRUE}" ]]; then |
| for uri in $(cros_config_host -c "${yaml_config}" get-firmware-uris); do |
| if ! grep -q "${uri}" "${srcuris}"; then |
| # Append uri to the last line of srcuris (srcuris should be a file with |
| # one line per-uri). |
| echo "${uri}" >> "${srcuris}" |
| fi |
| done |
| else |
| # Put each uri on its own line for easier merging in git. |
| cros_config_host -c "${yaml_config}" get-firmware-uris | tr ' ' '\n' > "${srcuris}" |
| fi |
| |
| touch "${ebuild}" |
| |
| # Clean metadata cache to make sure SRC_URI is fetched from ${srcuris} |
| # instead from portage cache which maybe out of sync. |
| # Note: this workaround is needed because we break the SRC_URI API contract |
| # which is supposed to be a static (see |
| # https://devmanual.gentoo.org/general-concepts/portage-cache/index.html). |
| # TODO(crbug.com/927917): find a different way to generate SRC_URI and remove |
| # these cache cleanup code. |
| rm -rf "${metadata}/cache" "${metadata}/md5-cache" "${edb_cache}" |
| "ebuild-${board}" "${ebuild}" manifest |
| "emerge-${board}" -j ${quiet} "chromeos-firmware-${board}" |
| |
| for i in "${!result[@]}"; do |
| if [[ "${result[i]}" -eq "0" ]]; then |
| stop_workon "${board}" "${start_pkg[i]}" |
| fi |
| done |
| } |
| |
| main() { |
| if [[ -z "${FLAGS_board}" ]]; then |
| die "-b or --board required." |
| fi |
| |
| update_firmware "${FLAGS_board}" "${FLAGS_project}" "${FLAGS_quiet}" "${FLAGS_append_srcuris}" |
| } |
| |
| main "$@" |