mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-07 21:16:57 +02:00
345 lines
11 KiB
Bash
Executable File
345 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# 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.
|
|
|
|
. "$(dirname "$0")/common.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/toolchain_util.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 name of the board to set up."
|
|
DEFINE_boolean default "${FLAGS_FALSE}" \
|
|
"Set board to the default board in your chroot"
|
|
DEFINE_boolean force "${FLAGS_FALSE}" \
|
|
"Force re-creating board root."
|
|
DEFINE_boolean usepkg "${FLAGS_TRUE}" \
|
|
"Use binary packages when possible."
|
|
DEFINE_boolean usepkgonly "${FLAGS_FALSE}" \
|
|
"Only use/download binary packages."
|
|
DEFINE_boolean getbinpkg "${FLAGS_TRUE}" \
|
|
"Download binary packages from remote repository."
|
|
DEFINE_string getbinpkgver "" \
|
|
"Use binary packages from a specific version."
|
|
DEFINE_boolean toolchainpkgonly "${FLAGS_FALSE}" \
|
|
"Use binary packages only for the board toolchain."
|
|
DEFINE_integer jobs "${NUM_JOBS}" \
|
|
"How many packages to build in parallel at maximum."
|
|
DEFINE_boolean skip_toolchain_update "${FLAGS_FALSE}" \
|
|
"Don't update toolchain automatically."
|
|
DEFINE_boolean skip_chroot_upgrade "${FLAGS_FALSE}" \
|
|
"Don't run the chroot upgrade automatically; use with care."
|
|
DEFINE_boolean regen_configs "${FLAGS_FALSE}" \
|
|
"Regenerate all config files (useful for modifying profiles w/out rebuild)."
|
|
DEFINE_boolean regen_configs_only "${FLAGS_FALSE}" \
|
|
"Regenerate all config files and nothing else, even if nothing else is installed."
|
|
|
|
FLAGS_HELP="usage: $(basename $0) [flags]
|
|
|
|
setup_board sets up the sysroot for a particular board. This script is called
|
|
automatically when you run build_packages, so there is typically no need to
|
|
call it directly, unless you want to blow away your board (using --force).
|
|
"
|
|
show_help_if_requested "$@"
|
|
|
|
# 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 libc_version "[stable]" \
|
|
"Version of libc to use."
|
|
DEFINE_boolean quiet $FLAGS_FALSE \
|
|
"Don't print warnings when board already exists."
|
|
DEFINE_string variant "" \
|
|
"Board variant."
|
|
|
|
|
|
# builds wrappers like equery-arm-generic.
|
|
# args:
|
|
# $1: command to wrap
|
|
# rest: extra arguments to pass to the command
|
|
_generate_wrapper() {
|
|
local command="${1}"
|
|
shift
|
|
local extra_args="$@"
|
|
|
|
|
|
local target="/usr/local/bin/${command}-${BOARD_VARIANT}"
|
|
sudo_clobber "${target}" <<EOF
|
|
#!/bin/bash
|
|
|
|
export PORTAGE_CONFIGROOT="$BOARD_ROOT"
|
|
export SYSROOT="\${SYSROOT:-$BOARD_ROOT}"
|
|
export ROOT="$BOARD_ROOT"
|
|
exec sudo -E ${command} ${extra_args} "\$@"
|
|
EOF
|
|
# Note: parent will process these.
|
|
wrappers+=( "${target}" )
|
|
upper=${command^^}
|
|
eval ${upper/-/_}_WRAPPER="${target}" # ${foo^^} returns toupper($foo)
|
|
}
|
|
|
|
generate_all_wrappers() {
|
|
local cmds=() wrappers=()
|
|
local wrapper
|
|
|
|
info "Generating wrapper scripts"
|
|
|
|
for wrapper in 'emerge --root-deps' ebuild eclean equery portageq \
|
|
qcheck qfile qlist emaint glsa-check; do
|
|
_generate_wrapper ${wrapper}
|
|
done
|
|
|
|
wrapper="/usr/local/bin/cros_workon-${BOARD_VARIANT}"
|
|
sudo_clobber "${wrapper}" <<EOF
|
|
#!/bin/bash
|
|
exec cros_workon --board ${BOARD_VARIANT} "\$@"
|
|
EOF
|
|
wrappers+=( "${wrapper}" )
|
|
|
|
wrapper="/usr/local/bin/gdb-${BOARD_VARIANT}"
|
|
sudo_clobber "${wrapper}" <<EOF
|
|
#!/bin/bash
|
|
exec ${BOARD_CHOST}-gdb -iex 'set sysroot ${BOARD_ROOT}' "\$@"
|
|
EOF
|
|
wrappers+=( "${wrapper}" )
|
|
|
|
cmds+=(
|
|
"chmod a+rx ${wrappers[*]}"
|
|
"chown root:root ${wrappers[*]}"
|
|
)
|
|
|
|
sudo_multi "${cmds[@]}"
|
|
}
|
|
|
|
generate_binhost_list() {
|
|
local t
|
|
[[ "${FLAGS_toolchainpkgonly}" -eq "${FLAGS_TRUE}" ]] && t="-t"
|
|
FLAGS_getbinpkgver="${FLAGS_getbinpkgver/current/${COREOS_VERSION_ID}}"
|
|
FLAGS_getbinpkgver="${FLAGS_getbinpkgver/latest/${COREOS_VERSION_ID}}"
|
|
FLAGS_getbinpkgver="${FLAGS_getbinpkgver/sdk/${COREOS_SDK_VERSION}}"
|
|
|
|
get_board_binhost $t "${BOARD}" ${FLAGS_getbinpkgver}
|
|
}
|
|
|
|
# Parse command line flags
|
|
FLAGS "$@" || exit 1
|
|
eval set -- "${FLAGS_ARGV}"
|
|
|
|
# Only now can we die on error. shflags functions leak non-zero error codes,
|
|
# so will die prematurely if 'switch_to_strict_mode' is specified before now.
|
|
switch_to_strict_mode
|
|
|
|
if [ -z "$FLAGS_board" ] ; then
|
|
error "--board required."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${FLAGS_usepkgonly}" -eq "${FLAGS_TRUE}" ]]; then
|
|
for flag in usepkg getbinpkg; do
|
|
fvar="FLAGS_${flag}"
|
|
if [[ "${!fvar}" -ne "${FLAGS_TRUE}" ]]; then
|
|
die_notrace "--usepkgonly is incompatible with --no${flag}"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
get_board_and_variant $FLAGS_board $FLAGS_variant
|
|
|
|
# Locations we will need
|
|
COREOS_OVERLAY="${REPO_ROOT}/src/third_party/coreos-overlay"
|
|
COREOS_CONFIG="${COREOS_OVERLAY}/coreos/config"
|
|
BOARD_ROOT="/build/${BOARD_VARIANT}"
|
|
BOARD_ETC="${BOARD_ROOT}/etc"
|
|
BOARD_ARCH=$(get_board_arch "$BOARD")
|
|
BOARD_CHOST=$(get_board_chost ${BOARD})
|
|
PORTAGE_PROFILE=$(get_board_profile "$BOARD")
|
|
BOARD_BINHOST=$(generate_binhost_list)
|
|
|
|
if [[ ${FLAGS_regen_configs_only} -eq ${FLAGS_TRUE} ]]; then
|
|
FLAGS_regen_configs=${FLAGS_TRUE}
|
|
FLAGS_skip_chroot_upgrade=${FLAGS_TRUE}
|
|
elif [[ -d "${BOARD_ROOT}" ]]; then
|
|
if [[ ${FLAGS_force} -eq ${FLAGS_TRUE} ]]; then
|
|
info "--force set. Re-creating ${BOARD_ROOT}..."
|
|
# Removal takes long. Make it asynchronous.
|
|
TEMP_DIR=`mktemp -d`
|
|
sudo mv "${BOARD_ROOT}" "${TEMP_DIR}"
|
|
sudo rm -rf "${TEMP_DIR}" &
|
|
elif [[ ${FLAGS_regen_configs} -eq ${FLAGS_FALSE} ]]; then
|
|
if [[ ${FLAGS_quiet} -eq ${FLAGS_FALSE} ]]; then
|
|
warn "Board output directory '$BOARD_ROOT' already exists."
|
|
warn "Not setting up board root. "
|
|
warn "Use --force to clobber the board root and start again."
|
|
fi
|
|
exit 0
|
|
fi
|
|
else
|
|
# Missing board root and --regen_configs_only wasn't used.
|
|
FLAGS_regen_configs=${FLAGS_FALSE}
|
|
fi
|
|
|
|
# Before we can run any tools, we need to update chroot
|
|
UPDATE_ARGS="--toolchain_boards=${BOARD}"
|
|
if [ "${FLAGS_usepkg}" -eq "${FLAGS_TRUE}" ]; then
|
|
UPDATE_ARGS+=" --usepkg"
|
|
if [[ "${FLAGS_usepkgonly}" -eq "${FLAGS_TRUE}" ]]; then
|
|
UPDATE_ARGS+=" --usepkgonly"
|
|
else
|
|
UPDATE_ARGS+=" --nousepkgonly"
|
|
fi
|
|
if [[ "${FLAGS_getbinpkg}" -eq "${FLAGS_TRUE}" ]]; then
|
|
UPDATE_ARGS+=" --getbinpkg "
|
|
else
|
|
UPDATE_ARGS+=" --nogetbinpkg "
|
|
fi
|
|
else
|
|
UPDATE_ARGS+=" --nousepkg"
|
|
fi
|
|
if [[ "${FLAGS_jobs}" -ne -1 ]]; then
|
|
UPDATE_ARGS+=" --jobs=${FLAGS_jobs}"
|
|
fi
|
|
if [ "${FLAGS_skip_toolchain_update}" -eq "${FLAGS_TRUE}" ]; then
|
|
UPDATE_ARGS+=" --skip_toolchain_update"
|
|
fi
|
|
if [ "${FLAGS_skip_chroot_upgrade}" -eq "${FLAGS_FALSE}" ] ; then
|
|
"${SRC_ROOT}/scripts"/update_chroot ${UPDATE_ARGS}
|
|
fi
|
|
|
|
# Migrate board roots that were created before the package location
|
|
# was standardized to /var/lib/portage/pkgs, build_image will fail if we
|
|
# simply forget about the old location and start writing to the new.
|
|
# Keep /packages as a compatibility symlink until everyone is updated.
|
|
if [[ ! -L "${BOARD_ROOT}/packages" ]]; then
|
|
if [[ ! -d "${BOARD_ROOT}/var/lib/portage/pkgs" ]]; then
|
|
if [[ -d "${BOARD_ROOT}/packages" ]]; then
|
|
warn "Moving board package directory to ${BOARD_ROOT}/var/lib/portage/pkgs"
|
|
sudo mkdir -p "${BOARD_ROOT}/var/lib/portage"
|
|
sudo mv "${BOARD_ROOT}/packages" "${BOARD_ROOT}/var/lib/portage/pkgs"
|
|
else
|
|
sudo mkdir -p "${BOARD_ROOT}/var/lib/portage/pkgs"
|
|
fi
|
|
fi
|
|
sudo ln -sfT "var/lib/portage/pkgs" "${BOARD_ROOT}/packages"
|
|
fi
|
|
|
|
info "Configuring portage in ${BOARD_ROOT}"
|
|
sudo mkdir -p "${BOARD_ETC}/portage/"{profile,repos.conf}
|
|
sudo ROOT="${BOARD_ROOT}" eselect profile set --force "${PORTAGE_PROFILE}"
|
|
|
|
# Cleanup/migrate from older make.conf files
|
|
sudo rm -f "${BOARD_ETC}/make.conf" "${BOARD_ETC}/make.conf.common"
|
|
if [[ -f "${BOARD_ETC}/make.conf.user" ]]; then
|
|
sudo mv "${BOARD_ETC}/make.conf.user" \
|
|
"${BOARD_ETC}/portage/make.conf.user"
|
|
else
|
|
sudo touch "${BOARD_ETC}/portage/make.conf.user"
|
|
fi
|
|
|
|
sudo_clobber "${BOARD_ETC}/portage/make.conf" <<EOF
|
|
# Created by setup_board
|
|
|
|
# Settings derived from the host environment
|
|
CBUILD="$(portageq envvar CHOST)"
|
|
HOSTCC="$(portageq envvar CHOST)-gcc"
|
|
PORTDIR="$(portageq envvar PORTDIR)"
|
|
PORTDIR_OVERLAY="$(portageq envvar PORTDIR_OVERLAY)"
|
|
DISTDIR="$(portageq envvar DISTDIR)"
|
|
MAKEOPTS="$(portageq envvar MAKEOPTS)"
|
|
PORTAGE_USERNAME="$(portageq envvar PORTAGE_USERNAME)"
|
|
|
|
# Board specific settings
|
|
CHOST="${BOARD_CHOST}"
|
|
ROOT="${BOARD_ROOT}/"
|
|
PKGDIR="${BOARD_ROOT}/var/lib/portage/pkgs"
|
|
PORT_LOGDIR="${BOARD_ROOT}/var/log/portage"
|
|
PORTAGE_TMPDIR="${BOARD_ROOT}/var/tmp"
|
|
PORTAGE_BINHOST="${BOARD_BINHOST}"
|
|
|
|
# Generally there isn't any need to add packages to @world by default.
|
|
# You can use --select to override this.
|
|
EMERGE_DEFAULT_OPTS="--oneshot"
|
|
|
|
# Allow the user to override or define additional settings.
|
|
source "${BOARD_ETC}/portage/make.conf.user"
|
|
EOF
|
|
|
|
sudo cp /etc/portage/repos.conf/* "${BOARD_ETC}"/portage/repos.conf/
|
|
|
|
# required when using --regen_configs_only
|
|
sudo mkdir -p --mode=01777 "${BOARD_ROOT}"{/tmp,/var/tmp}
|
|
|
|
# make it easy to find debug symbols
|
|
sudo mkdir -p /usr/lib/debug/build
|
|
sudo ln -sfT ${BOARD_ROOT}/usr/lib/debug /usr/lib/debug/${BOARD_ROOT}
|
|
|
|
# remove bogus pkg-config wrapper
|
|
sudo rm -f "${BOARD_ROOT}/build/bin/${BOARD_CHOST}-pkg-config"
|
|
|
|
generate_all_wrappers
|
|
|
|
# Unclear why this is required but it doesn't happen automatically
|
|
info "Performing package updates..."
|
|
${EMAINT_WRAPPER} --fix movebin
|
|
${EMAINT_WRAPPER} --fix moveinst
|
|
${EMAINT_WRAPPER} --fix world
|
|
|
|
if [[ ${FLAGS_regen_configs} -eq ${FLAGS_FALSE} ]]; then
|
|
EMERGE_FLAGS="--select --quiet --root-deps=rdeps"
|
|
if [[ "${FLAGS_jobs}" -ne -1 ]]; then
|
|
EMERGE_FLAGS+=" --jobs=${FLAGS_jobs}"
|
|
fi
|
|
EMERGE_TOOLCHAIN_FLAGS="${EMERGE_FLAGS}"
|
|
|
|
if [[ "${FLAGS_usepkg}" -eq "${FLAGS_TRUE}" && \
|
|
"${FLAGS_getbinpkg}" -eq "${FLAGS_TRUE}" ]]
|
|
then
|
|
if [[ "${FLAGS_usepkgonly}" -eq "${FLAGS_TRUE}" ]]; then
|
|
EMERGE_FLAGS+=" --usepkgonly --rebuilt-binaries n"
|
|
else
|
|
EMERGE_FLAGS+=" --usepkg"
|
|
fi
|
|
EMERGE_FLAGS+=" --getbinpkg"
|
|
EMERGE_TOOLCHAIN_FLAGS+=" --usepkgonly --getbinpkg --rebuilt-binaries n"
|
|
else
|
|
# When binary packages are disabled we need to make sure the cross
|
|
# sysroot includes any build dependencies for the toolchain.
|
|
info "Installing toolchain build dependencies"
|
|
install_cross_libs "${BOARD_CHOST}" ${EMERGE_FLAGS} --buildpkg=n
|
|
fi
|
|
|
|
info "Installing baselayout"
|
|
"${EMERGE_WRAPPER}" ${EMERGE_FLAGS} --nodeps sys-apps/baselayout
|
|
|
|
info "Installing toolchain"
|
|
SYSROOT="/usr/${BOARD_CHOST}" "${EMERGE_WRAPPER}" \
|
|
${EMERGE_TOOLCHAIN_FLAGS} "${TOOLCHAIN_PKGS[@]}"
|
|
fi
|
|
|
|
if [[ ${FLAGS_regen_configs_only} -eq ${FLAGS_FALSE} ]]; then
|
|
# Setup BOARD_ROOT for QEMU user emulation.
|
|
setup_qemu_static "${BOARD_ROOT}"
|
|
fi
|
|
|
|
if [ $FLAGS_default -eq $FLAGS_TRUE ] ; then
|
|
echo $BOARD_VARIANT > "$GCLIENT_ROOT/src/scripts/.default_board"
|
|
fi
|
|
|
|
command_completed
|
|
info "The SYSROOT is: ${BOARD_ROOT}"
|
|
|
|
# NOTE: Printing the working-on ebuilds does not only serve the informative
|
|
# purpose. It also causes the ${BOARD_ROOT}/etc/portage/package.* files to be
|
|
# regenerated.
|
|
WORKING_ON=$(cros_workon --board=${FLAGS_board} list)
|
|
if [ -n "${WORKING_ON}" ]; then
|
|
info
|
|
info "Currently working on the following ebuilds for this board:"
|
|
info "${WORKING_ON}"
|
|
fi
|