flatcar-scripts/install_toolchain
Michael Marineau b4b7a2e2f8 fix(install_toolchain): Exclude libc locale/info/etc from build root.
These excludes are used in images and I want to use the same checking
code as images do so the build root needs to behave the same way.

This is temporary as I'll switch to installing libc via emerge soon.
2013-11-26 16:53:52 -08:00

209 lines
6.9 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
. "${SRC_ROOT}/platform/dev/toolchain_utils.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_string board_root "" \
"Path of the board root to install into. Defaults to /build/<board>."
DEFINE_boolean configure $FLAGS_TRUE \
"Update config files in <board_root>/etc after installation."
DEFINE_boolean force $FLAGS_FALSE \
"Install toolchain even if already up to date."
DEFINE_string toolchain "" \
"Toolchain. For example: i686-pc-linux-gnu, armv7a-softfloat-linux-gnueabi"
FLAGS_HELP="usage: $(basename $0) [flags]
Installs cross toolchain libraries into a board_root. This script is not
meant to be used by developers directly. Run at your own risk.
"
show_help_if_requested "$@"
# 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
# Get the version number of a toolchain package.
cross_get_version() {
local pkg=$1
local toolchain=${2:-${FLAGS_toolchain}}
local cpv
if [[ "$CHOST" != "${toolchain}" ]]; then
if [[ "$pkg" = "gcc" ]]; then
# Users can install multiple versions of gcc at once, so we need to call
# gcc-config to find out which installed version is selected.
local path=$(CTARGET="${toolchain}" gcc-config -B || true)
cpv=$(portageq owners / "$path" | sed -e '/^\t/d')
else
cpv=$(portageq match / "cross-${toolchain}/${pkg}" || true)
fi
else
if [[ "$pkg" = glibc ]] ; then
cpv=$(portageq match / sys-libs/glibc || true)
elif [[ "$pkg" = gcc ]] ; then
cpv=$(portageq match / sys-devel/gcc || true)
else
die "Unknown pkg ${pkg}"
fi
fi
local cp=$(echo $cpv | sed -e 's/-r[0-9]*$//; s/-[^-]*$//')
local result="${cpv#$cp-}"
local count="$(echo $result | wc -w)"
if [ "$count" -gt "1" ]; then
die "Multiple versions of $pkg installed"
elif [ "$count" -lt "1" ]; then
die "Cannot find $pkg"
fi
echo $result
}
# Checks whether the libc version installed in the board
# matches the one installed by the toolchain.
board_needs_libc_update() {
if [[ ! -e "${BOARD_SETUP}" ]]; then
return 0
fi
local board_version=$(. "${BOARD_SETUP}"; echo "${LIBC_VERSION}")
local toolchain_version=$(cross_get_version glibc)
if [[ "${board_version}" = "${toolchain_version}" ]]; then
return 1
fi
return 0
}
install_toolchain_in_provided() {
local gcc_ver="$1"
local glibc_ver="$2"
# Tell portage that toolchain packages are already installed in the sysroot.
sudo_clobber "$BOARD_PROFILE/package.provided" << EOF
sys-devel/gcc-$gcc_ver
sys-libs/glibc-$glibc_ver
EOF
}
# Install all of the stuff that depends on the toolchain versions
# into the board root.
install_toolchain_in_board() {
local cmds
local gcc_ver=$(cross_get_version gcc)
local libc_ver=$(cross_get_version glibc)
if [[ -z ${gcc_ver} || -z ${libc_ver} ]]; then
die "Cannot find toolchain to install into board root"
fi
echo "Installing the toolchain into the board root."
# Untar glibc to get most of the headers required to build.
local libc_tar="glibc-${libc_ver}.tbz2"
# Install libc libraries.
if [ "${CHOST}" != "$FLAGS_toolchain" ] ; then
local libc_path="${PKGDIR}/cross-${FLAGS_toolchain}/${libc_tar}"
local libc_excludes=(
# Empty lib dirs, replaced by symlinks
'lib'
# Locales and info pages
usr/share/{i18n,info,locale}
)
cmds=(
"mkdir -p '${BOARD_ROOT}/lib64' '${BOARD_ROOT}/sbin'"
"tar jxpf '${libc_path}' -C '${BOARD_ROOT}' \
--exclude=${FLAGS_toolchain}/lib64 --exclude=${FLAGS_toolchain}/sbin \
${libc_excludes[@]/#/--exclude=} \
'./usr/${FLAGS_toolchain}' --strip-components=3"
"tar jxpf '${libc_path}' -C '${BOARD_ROOT}/lib64' \
${libc_excludes[@]/#/--exclude=} \
'./usr/${FLAGS_toolchain}/lib64' --strip-components=4"
"tar jxpf '${libc_path}' -C '${BOARD_ROOT}/sbin' \
${libc_excludes[@]/#/--exclude=} \
'./usr/${FLAGS_toolchain}/sbin' --strip-components=4"
"mkdir -p '${BOARD_ROOT}/usr/lib/debug'"
"tar jxpf '${libc_path}' -C '${BOARD_ROOT}/usr/lib/debug' \
${libc_excludes[@]/#/--exclude=} \
'./usr/lib/debug/usr/${FLAGS_toolchain}' --strip-components=6 \
|| warn 'libc debug info not copied.'"
)
# TODO(asharif): Remove this hack after a while.
local board_gcc_dir="${BOARD_ROOT}/usr/lib/gcc"
if [[ -L "${board_gcc_dir}" ]] ; then
cmd+=("rm -f '${board_gcc_dir}'")
fi
sudo_multi "${cmds[@]}"
copy_gcc_libs "${BOARD_ROOT}" "cross-$FLAGS_toolchain/gcc-$gcc_ver"
else
cmds=(
"mkdir -p '${BOARD_ROOT}'{/usr,}/lib64 '${BOARD_ROOT}/usr/lib/debug'"
"ln -sfT '${BOARD_ROOT}/usr/lib64' '${BOARD_ROOT}/usr/lib'"
"ln -sfT '${BOARD_ROOT}/lib64' '${BOARD_ROOT}/lib'"
"emerge --oneshot --nodeps -k --root='${BOARD_ROOT}' \
=sys-libs/glibc-${libc_ver}"
)
sudo_multi "${cmds[@]}"
fi
# Some header files are needed also for rpcbind (NFS support)
# TODO: Figure out a better way of doing this too?
cmds=(
"cp -a /usr/include/rpcsvc/mount.h '${BOARD_ROOT}/usr/include/rpcsvc'"
"cp -a /usr/include/rpcsvc/rquota.h '${BOARD_ROOT}/usr/include/rpcsvc'"
"cp -a /usr/include/rpcsvc/nfs_prot.h '${BOARD_ROOT}/usr/include/rpcsvc'"
"cp -a /usr/include/rpcsvc/yppasswd.h '${BOARD_ROOT}/usr/include/rpcsvc'"
)
sudo_multi "${cmds[@]}"
if [[ ${FLAGS_configure} -eq ${FLAGS_TRUE} ]]; then
install_toolchain_in_provided "$gcc_ver" "$libc_ver"
# Configure new libc version in make.conf.board_setup.
sudo sed -i -e "/^LIBC_VERSION=/d" "$BOARD_SETUP"
echo "LIBC_VERSION=\"$libc_ver\"" | sudo_append "$BOARD_SETUP"
fi
}
set -u
if [ -z "$FLAGS_board" ] ; then
die "--board required."
fi
get_board_and_variant $FLAGS_board ""
BOARD_ROOT="${FLAGS_board_root:-/build/${BOARD_VARIANT}}"
BOARD_ETC="${BOARD_ROOT}/etc"
BOARD_SETUP="${BOARD_ETC}/make.conf.board_setup"
BOARD_PROFILE="${BOARD_ETC}/portage/profile"
all_toolchains=( $(get_all_board_toolchains "${BOARD}") )
: ${FLAGS_toolchain:=${all_toolchains[0]}}
if [ -z "${FLAGS_toolchain}" ]; then
die "No toolchain specified in board overlay or on command line."
fi
eval "$(portageq envvar -v CHOST PKGDIR)"
if [[ ${FLAGS_force} -eq ${FLAGS_TRUE} ]] || \
board_needs_libc_update; then
info "Updating libc in the board."
install_toolchain_in_board
else
info "Cross toolchain already up to date. Nothing to do."
fi