flatcar-scripts/setup_board
James Le Cuirot 50d7dd1a84
Drop all references to a toolchain-specific binpkg host
This evidently hasn't been used in a very long time, if ever, and it's
just adding confusion.

Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
2025-04-22 17:59:38 +01:00

375 lines
13 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
assert_inside_chroot
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_string pkgdir "" \
"Use binary packages from a custom directory instead of /build/[ARCH]/var/lib/portage/pkgs/."
DEFINE_string binhost "" \
"Use binary packages from a specific location instead of $FLATCAR_DEV_BUILDS/... "
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 qemu
# If the QEMU user space emulator is missing for this board arch, that implies
# the board arch matches the SDK arch and therefore emulation is unnecessary.
qemu=$(type -P "qemu-${BOARD_CHOST%%-*}") || unset qemu
info "Generating wrapper scripts"
for wrapper in emerge ebuild eclean equery portageq \
qcheck qfile qlist emaint glsa-check; do
_generate_wrapper ${wrapper}
done
wrapper="/usr/local/bin/flatcar_workon-${BOARD_VARIANT}"
sudo_clobber "${wrapper}" <<EOF
#!/bin/bash
exec "${SRC_ROOT}/scripts/flatcar_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}" )
# ldconfig cannot generate caches for non-native arches. Use QEMU and the
# native ldconfig to work around that.
wrapper="/usr/local/sbin/ldconfig-${BOARD_VARIANT}"
sudo_clobber "${wrapper}" <<EOF
#!/bin/sh
exec ${qemu-} "${BOARD_ROOT}"/sbin/ldconfig -r "${BOARD_ROOT}" "\$@"
EOF
wrappers+=( "${wrapper}" )
# Create a CHOST-based ldconfig symlink for Portage to call.
sudo ln -sfT "ldconfig-${BOARD_VARIANT}" "/usr/local/sbin/${BOARD_CHOST}-ldconfig"
cmds+=(
"chmod a+rx ${wrappers[*]}"
"chown root:root ${wrappers[*]}"
)
sudo_multi "${cmds[@]}"
}
generate_binhost_list() {
FLAGS_getbinpkgver="${FLAGS_getbinpkgver/current/${FLATCAR_VERSION_ID}}"
FLAGS_getbinpkgver="${FLAGS_getbinpkgver/latest/${FLATCAR_VERSION_ID}}"
FLAGS_getbinpkgver="${FLAGS_getbinpkgver/sdk/${FLATCAR_SDK_VERSION}}"
get_board_binhost "${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="$FLAGS_binhost $(generate_binhost_list)"
BOARD_PKGDIR="${FLAGS_pkgdir:-${BOARD_ROOT}/var/lib/portage/pkgs}"
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
if [[ -n "${FLAGS_binhost}" ]]; then
UPDATE_ARGS+=" --binhost=${FLAGS_binhost} "
fi
else
UPDATE_ARGS+=" --nousepkg"
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 ln -sfT "$(portageq get_repo_path / coreos-overlay)/coreos/user-patches" \
"${BOARD_ETC}/portage/patches"
sudo cp /etc/portage/repos.conf/* "${BOARD_ETC}"/portage/repos.conf/
# set PORTAGE_CONFIGROOT to tell eselect to modify the profile inside
# /build/<arch>-usr, but set ROOT to /, so eselect will actually find
# the profile which is outside /build/<arch>-usr, set SYSROOT to / as
# well, because it must match ROOT
sudo \
PORTAGE_CONFIGROOT="${BOARD_ROOT}" ROOT=/ SYSROOT=/ \
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"
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_PKGDIR}"
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 --verbose"
# Enable provenance reporting by default. Produced files are in /usr/share/SLSA
GENERATE_SLSA_PROVENANCE="true"
# Allow the user to override or define additional settings.
source "${BOARD_ETC}/portage/make.conf.user"
EOF
# 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 --verbose "--jobs=${NUM_JOBS}" )
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 )
fi
info "Installing baselayout"
"${EMERGE_WRAPPER}" "${EMERGE_FLAGS[@]}" --nodeps sys-apps/baselayout
if [[ "${FLAGS_usepkg}" -ne "${FLAGS_TRUE}" ||
"${FLAGS_getbinpkg}" -ne "${FLAGS_TRUE}" ]]
then
# 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
info "Building toolchain dependencies"
"${EMERGE_WRAPPER}" --buildpkg --buildpkgonly \
--root="/usr/${BOARD_CHOST}" --sysroot="/usr/${BOARD_CHOST}" \
"${EMERGE_TOOLCHAIN_FLAGS[@]}" $(< "/usr/${BOARD_CHOST}/etc/portage/cross-${BOARD_CHOST}-depends")
info "Building toolchain"
"${EMERGE_WRAPPER}" --buildpkg --buildpkgonly \
--root="/usr/${BOARD_CHOST}" --sysroot="/usr/${BOARD_CHOST}" \
"${EMERGE_TOOLCHAIN_FLAGS[@]}" "${TOOLCHAIN_PKGS[@]}"
fi
info "Installing toolchain"
"${EMERGE_WRAPPER}" \
--usepkgonly --getbinpkg --rebuilt-binaries n \
"${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}"
WORKING_ON=$("${SRC_ROOT}"/scripts/flatcar_workon list --board="${FLAGS_board}")
if [ -n "${WORKING_ON}" ]; then
info
info "Currently working on the following ebuilds for this board:"
info "${WORKING_ON}"
fi