#!/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. . "$(dirname "$0")/common.sh" || exit 1 . "${SRC_ROOT}/platform/dev/toolchain_utils.sh" # Script must run inside the chroot restart_in_chroot_if_needed "$@" get_default_board # 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 to bootstrap." 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 board_overlay "" \ "Location of the board overlay." DEFINE_string binutils_version "2.21-r4" \ "Version of binutils to use." DEFINE_boolean fast ${DEFAULT_FAST} "Call many emerges in parallel" DEFINE_string gcc_version "[stable]" \ "Version of gcc to use." DEFINE_integer jobs -1 \ "How many packages to build in parallel at maximum." DEFINE_string kernel_version "[stable]" \ "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_string libc_version "[stable]" \ "Version of libc to use." 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." DEFINE_boolean skip_chroot_upgrade $FLAGS_FALSE \ "Don't run the chroot upgrade automatically; use with care." DEFINE_string toolchain "" \ "Toolchain. For example: i686-pc-linux-gnu, armv7a-softfloat-linux-gnueabi" DEFINE_string variant "" \ "Board variant." # The --reuse_pkgs_from_local_boards flag tells Portage to share binary # packages between boards that are built locally, so that the total time # required to build several boards is reduced. This flag is only useful # when you are not able to use remote binary packages, since remote binary # packages are usually more up to date than anything you have locally. DEFINE_boolean reuse_pkgs_from_local_boards $FLAGS_FALSE \ "Bootstrap from local packages instead of remote packages." # 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 # 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}" \ --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 \ qcheck qfile qlist ; 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" 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 --select=y $PACKAGES sudo cp -a "${PKGDIR}" $BOARD_ROOT/packages # Install cross-compilers. COMPILERS=$(equery l cross-*/* --format='=$cpv') sudo -E $EMERGE_CMD $HOST_FLAGS --select=n $COMPILERS # Setup needed symlinks for cross-compilers. sudo mkdir -p $BOARD_ROOT/usr/local/portage sudo cp -a ${CROSSDEV_OVERLAY} $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=$(sed 's:#.*::' $(printf '%s/toolchain.conf ' ${ALL_OVERLAYS}) \ 2>/dev/null | sort -u) for target in ${TARGETS}; do libc=$(eval $(crossdev --show-target-cfg "${target}"); echo ${libc_pn}) if [[ ${libc} == "glibc" ]] ; then # 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 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 # Now that the portageq-* wrappers have been created, we can add the binhost # config to make.conf.board. print_board_binhost_config | sudo_append $BOARD_ETC/make.conf.board # # Emerge the kernel headers into the board build root. # KERNEL_EMERGE_FLAGS="--select --quiet" if [[ "${FLAGS_usepkg}" -eq "${FLAGS_TRUE}" || "${FLAGS_reuse_pkgs_from_local_boards}" -eq "${FLAGS_TRUE}" ]]; then KERNEL_EMERGE_FLAGS+=" --getbinpkg --usepkg" fi sudo -E "${EMERGE_WRAPPER}" ${KERNEL_EMERGE_FLAGS} \ chromeos-base/kernel-headers unset KERNEL_EMERGE_FLAGS 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