mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-09 14:06:58 +02:00
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.
209 lines
6.9 KiB
Bash
Executable File
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
|