#!/bin/bash # Copyright (c) 2011 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. # This script sets up a the sysroot for a particular target board. # Load common CrOS utilities. Inside the chroot this file is installed in # /usr/lib/crosutils. Outside the chroot we find it relative to the script's # location. find_common_sh() { local common_paths=(/usr/lib/crosutils $(dirname "$0")) local path SCRIPT_ROOT= for path in "${common_paths[@]}"; do local common="${path}/common.sh" if ([ -r "${common}" ] && . "${common}" && [ -d "${SCRIPTS_DIR}" ]); then SCRIPT_ROOT=${path} break fi done } find_common_sh . "${SCRIPT_ROOT}/common.sh" || ! echo "Unable to load common.sh" || exit 1 # Script must run inside the chroot restart_in_chroot_if_needed "$@" get_default_board # Flags DEFINE_string board "$DEFAULT_BOARD" \ "The name of the board to set up." DEFINE_string build_root "/build" \ "The root location for board sysroots." DEFINE_string board_overlay "" \ "Location of the board overlay." DEFINE_string variant "" \ "Board variant." DEFINE_string toolchain "" \ "Toolchain. For example: i686-pc-linux-gnu, armv7a-softfloat-linux-gnueabi" DEFINE_boolean usepkg $FLAGS_TRUE \ "Use binary packages to bootstrap." DEFINE_boolean force $FLAGS_FALSE \ "Force re-creating board root." DEFINE_string binutils_version "2.21-r3" \ "Version of binutils to use." DEFINE_string gcc_version "4.6.0-r13" \ "Version of gcc to use." DEFINE_string libc_version "2.11.1-r3" \ "Version of libc to use." DEFINE_string kernel_version "3.1" \ "Version of kernel headers to use." DEFINE_boolean latest_toolchain $FLAGS_FALSE \ "Use the latest ebuild for all toolchain packages (gcc, binutils, libc, \ kernel). This overrides the other toolchain version options." DEFINE_boolean default $FLAGS_FALSE \ "Set board to the default board in your chroot" DEFINE_boolean fast ${DEFAULT_FAST} "Call many emerges in parallel" DEFINE_string profile "" \ "The portage configuration profile to use. Profile must be located in overlay-board/profiles" DEFINE_boolean quiet $FLAGS_FALSE \ "Don't print warnings when board already exists." DEFINE_boolean skip_toolchain_update $FLAGS_FALSE \ "Don't update toolchain automatically." # 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}" < /dev/null 2>&1 # Created by setup_board CHOST="${FLAGS_toolchain}" ROOT="${BOARD_ROOT}/" BOARD_OVERLAY="${BOARD_OVERLAY_LIST}" MAKEOPTS="-j${NUM_JOBS}" PKG_CONFIG="pkg-config-${BOARD_VARIANT}" BOARD_USE="${BOARD_VARIANT}" EOF if ! ${HOST_BOARD}; then sudo ln -sf "${CHROMIUMOS_CONFIG}/make.conf.${ARCH}-target" \ "${BOARD_ETC}/make.conf" print_board_make_conf | sudo_clobber $BOARD_ETC/make.conf.board print_board_binhost_config | sudo_append $BOARD_ETC/make.conf.board # We install the toolchain related bits after the BOARD_ROOT, BOARD_PROFILE # and BOARD_ETC directories have been created. install_toolchain_in_board fi # Setup make.globals and the profile. sudo touch /etc/make.conf.user sudo ln -sf /etc/make.globals "${BOARD_ROOT}/etc/make.globals" sudo ln -sf /etc/make.conf.user "${BOARD_ROOT}/etc/make.conf.user" # Select the profile to build based on the board and profile passed to # setup_board. The developer can later change profiles by running # cros_choose_profile manually. if ! cros_choose_profile \ --board "${FLAGS_board}" \ --build_root "${FLAGS_build_root}" \ --board_overlay "${FLAGS_board_overlay}" \ --variant "${FLAGS_variant}" \ --profile "${FLAGS_profile}"; then error "Selecting profile failed, removing incomplete board directory!" sudo rm -rf "${BOARD_ROOT}" exit 1 fi for wrapper in 'emerge --root-deps' ebuild eclean equery portageq; do generate_wrapper $wrapper done generate_pkgconfig_wrapper CROS_WORKON_WRAPPER="/usr/local/bin/cros_workon-${BOARD_VARIANT}" cat < /dev/null 2>&1 #!/bin/bash exec cros_workon --board ${BOARD_VARIANT} "\$@" EOF sudo chmod +x "$CROS_WORKON_WRAPPER" # # Emerge the kernel headers into the board build root. # EMERGE_FLAGS="" if [[ $FLAGS_usepkg -eq $FLAGS_TRUE ]]; then EMERGE_FLAGS="${EMERGE_FLAGS} --getbinpkg --usepkg" fi if ${HOST_BOARD}; then EMERGE_CMD="emerge" if [[ $FLAGS_fast -eq $FLAGS_TRUE ]]; then EMERGE_CMD="${GCLIENT_ROOT}/chromite/bin/parallel_emerge" fi PACKAGES="system hard-host-depends world" # First, rebuild all packages from scratch. This is needed to make sure # we rebuild all chroot packages. sudo -E $EMERGE_CMD --emptytree --with-bdeps=y $PACKAGES sudo eclean -d packages # Next, install our rebuilt packages into our separate root. HOST_FLAGS="--root=$BOARD_ROOT --update --verbose --deep --root-deps" HOST_FLAGS+=" --with-bdeps=y --newuse --jobs=$NUM_JOBS --usepkgonly" sudo -E $EMERGE_CMD $HOST_FLAGS $PACKAGES sudo cp -a "${PKGDIR}" $BOARD_ROOT/packages # Install cross-compilers. COMPILERS=$(equery l cross-*/* --format='=$cpv') sudo -E $EMERGE_CMD $HOST_FLAGS --oneshot $COMPILERS # Setup needed symlinks for cross-compilers. sudo mkdir -p $BOARD_ROOT/usr/local/portage sudo cp -a /usr/local/portage/crossdev $BOARD_ROOT/usr/local/portage # Setup crossdev configuration for categories. sudo cp -a /etc/portage/* $BOARD_ROOT/etc/portage # The new chroot should have gcc for each target. Make sure that # the latest one is correctly selected. Ignore cat errors as not # all overlays will have a toolchain.conf. ALL_OVERLAYS=$(cros_overlay_list --all_boards) TARGETS=$(cat $(printf '%s/toolchain.conf ' ${ALL_OVERLAYS}) 2>/dev/null | \ sort -u) for target in ${TARGETS}; do # Install needed glibc tarball. cross_target_path=/var/lib/portage/pkgs/cross-$target if [[ -e "$cross_target_path" ]] ; then sudo mkdir -p ${BOARD_ROOT}$cross_target_path sudo cp -a ${cross_target_path}/glibc-* ${BOARD_ROOT}$cross_target_path fi CURRENT_GCC="$(gcc-config -c ${target})" sudo ROOT=${BOARD_ROOT} gcc-config ${CURRENT_GCC} CURRENT_BINUTILS="$(binutils-config -c ${target})" sudo ROOT=${BOARD_ROOT} binutils-config ${CURRENT_BINUTILS} done # Now cleanup paths referencing the ROOT from the *.la files. sudo find $BOARD_ROOT -type f -name '*.la' | xargs sudo \ sed -i -e "s|$BOARD_ROOT/|/|g" else sudo -E "${EMERGE_WRAPPER}" ${EMERGE_FLAGS} chromeos-base/kernel-headers fi if [ $FLAGS_default -eq $FLAGS_TRUE ] ; then echo $BOARD_VARIANT > "$GCLIENT_ROOT/src/scripts/.default_board" fi echo "Done!" echo "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 echo echo "Currently working on the following ebuilds for this board:" echo "${WORKING_ON}" fi