#!/bin/sh # # Copyright (C) 2011 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This script is used to rebuild the Android goldfish arm-based kernel from # sources. ### ### Utilities ### # Implementation of 'dirname' that works safely when paths contains spaces # $1: output variable name # $2: path (may contain spaces) # Usage: set_dirname FOO "/path/to/foo with spaces" set_dirname () { eval $1="`dirname \"$2\"`" } # Same as set_dirname, but for the 'basename' command set_basename () { eval $1="`basename \"$2\"`" } # Check the status of the previous command, and print a message and exit # if it didn't succeed. fail_panic () { if [ $? != 0 ]; then echo "ERROR: $@" exit 1 fi } # Send a message to the log. Does nothing if --verbose is not used log () { if [ "$VERBOSE" = "yes" ] ; then echo "$@" fi } # Run a comment. Print it to the output first if --verbose is used run () { if [ "$VERBOSE" = "yes" ] ; then echo "### COMMAND: $@" $@ else $@ >/dev/null 2>&1 fi } fail_ifnotdir () { local _dir="$1" if [ ! -d "$_dir" ]; then shift echo "ERROR: $@ ($_dir)" exit 1 fi } # Check wether program '$2' is in your path, and set variable $1 to its # full path, or to empty otherwise. # Example: find_program FOO foo # # $1: Variable name # $2: Program name find_program () { local FINDPROG_=`which $2 2>/dev/null` if [ -n "$FINDPROG_" ]; then eval $1="$FINDPROG_"; else eval $1= fi } set_dirname PROGDIR "$0" set_basename PROGNAME "$0" ### ### Get defaults ### # Location of prebuilt kernel images relative to Android top-level PREBUILT_KERNEL_DIR="prebuilts/qemu-kernel/arm" # Look for top-level Android build source tree if not in environment if [ -n "$ANDROID_BUILD_TOP" ] ; then OUT_DIR="$ANDROID_BUILD_TOP/$PREBUILT_KERNEL_DIR" else OUT_DIR= fi TOOLCHAIN_NAME=arm-eabi-4.4.0 TOOLCHAIN_PREFIX=arm-eabi GCC="$TOOLCHAIN_PREFIX-gcc" JOBS="`cat /proc/cpuinfo | grep -e "^processor" | wc -l`" ### ### Parse options ### OPTION_HELP=no VERBOSE=no VERBOSE2=no OPTION_OUT_DIR= OPTION_CC= PARAMS="" for opt do optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` case "$opt" in --help|-h|-\?) OPTION_HELP=yes ;; --verbose) if [ "$VERBOSE" = "yes" ] ; then VERBOSE2=yes else VERBOSE=yes fi ;; --out-dir=*) OPTION_OUT_DIR="$optarg" ;; --cc=*) OPTION_CC="$optarg" ;; --toolchain=*) TOOLCHAIN_NAME="$optarg" ;; --jobs=*) JOBS="$optarg" ;; -*) echo "unknown option '$opt', use --help" exit 1 ;; *) if [ -z "$PARAMS" ] ; then PARAMS="$opt" else PARAMS="$PARAMS $opt" fi ;; esac done if [ "$OPTION_HELP" = "yes" ] ; then echo "Usage: $PROGNAME /path/to/kernel" echo "" echo "Rebuild the prebuilt Android goldfish-specific kernel from sources." echo "" echo "Options (default are inside brackets):" echo "" echo " --help Print this message." echo " --verbose Enable verbose output." echo " --android= Set Android top-level directory [$ANDROID_BUILD_TOP]" echo " --out-dir= Set output directory [$OUT_DIR]" echo " --toolchain= Toolchain name [$TOOLCHAIN_NAME]" echo " --cc= Path to C compiler [$GCC]" echo " --jobs= Perform parallel builds [$JOBS]" echo "" echo "The --toolchain option is ignored if you use the --cc one." exit 0 fi ### ### Parse parameters ### set_parameters () { if [ -z "$1" ] ; then echo "ERROR: Please specify path of kernel sources directory. See --help for details." exit 1 fi if [ -n "$2" ]; then echo "ERROR: Too many arguments. See --help for details." exit 1 fi KERNEL_DIR="$1" fail_ifnotdir "$KERNEL_DIR" "Missing kernel directory" fail_ifnotdir "$KERNEL_DIR/kernel" "Missing kernel-specific directory" fail_ifnotdir "$KERNEL_DIR/arch" "Missing kernel-specific directory" fail_ifnotdir "$KERNEL_DIR/arch/arm/mach-goldfish" "Missing goldfish-specific directory" } set_parameters $PARAMS ### ### Determine build configuration ### if [ -n "$OPTION_OUT_DIR" ] ; then OUT_DIR="$OPTION_OUT_DIR" fi if [ -z "$ANDROID_BUILD_TOP" ] ; then # Assume that we are under $ANDROID_BUILD_TOP/prebuilt/android-arm/kernel ANDROID_BUILD_TOP="`cd \"$PROGDIR\"/../../.. && pwd`" if [ -d "$ANDROID_BUILD_TOP" ]; then echo "Probed Android top-level directory: $ANDROID_BUILD_TOP" else echo "ERROR: Can't find Android top-leveld directory. Please define ANDROID_BUILD_TOP" exit 1 fi fi if [ -z "$OUT_DIR" ] ; then OUT_DIR="$ANDROID_BUILD_TOP/$PREBUILT_KERNEL_DIR" if [ ! -d "$OUT_DIR" ]; then echo "ERROR: Missing default output dir: $OUT_DIR" echo "Please use --out-dir= to specify alternative output directory." exit 1 fi fi echo "Using output directory: $OUT_DIR" mkdir -p "$OUT_DIR" fail_panic "Could not create directory: $OUT_DIR" # Find toolchain if [ -n "$OPTION_CC" ]; then GCC="$OPTION_CC" else find_program GCC $TOOLCHAIN_PREFIX-gcc fi if [ -z "$GCC" ]; then TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilt/linux-x86/toolchain/$TOOLCHAIN_NAME/bin" if [ ! -d "$TOOLCHAIN_DIR" ] ; then echo "ERROR: Missing directory: $TOOLCHAIN_DIR" exit 1 fi GCC="$TOOLCHAIN_DIR/$TOOLCHAIN_PREFIX-gcc" if [ ! -f "$GCC" ] ; then echo "ERROR: Missing program file: $GCC" exit 1 fi fi CROSS_COMPILE="`echo $GCC | sed -e 's!gcc$!!g' `" echo "Using cross-toolchain prefix: $CROSS_COMPILE" # Do we have ccache in our path? find_program CCACHE ccache if [ -n "$CCACHE" ]; then echo "Using ccache program: $CCACHE" CROSS_COMPILE="ccache $CROSS_COMPILE" fi ### ### Do the build ### cd "$KERNEL_DIR" ARCH=arm SUBARCH=arm export CROSS_COMPILE ARCH SUBARCH # $1: defconfig name (e.g. goldfish or goldfish_armv7) # $2: output suffix (e.g. "" or "-armv7") do_build () { MAKE_FLAGS="-j$JOBS" # Use --verbose --verbose to see build commands if [ "$VERBOSE2" = "yes" ] ; then MAKE_FLAGS="$MAKE_FLAGS V=1" fi echo "Cleaning up source tree." git ls-files -o | xargs rm -f echo "Setting up $1_defconfig..." run make $1_defconfig fail_panic "Could not setup $1_defconfig build!" echo "Building $1_deconfig..." run make $MAKE_FLAGS fail_panic "Could not build $1_defconfig!" echo "Copying $1_defconfig binaries to $OUT_DIR." cp -f arch/arm/boot/zImage "$OUT_DIR/kernel-qemu$2" cp -f vmlinux "$OUT_DIR/vmlinux-qemu$2" } do_build goldfish if [ -f arch/arm/configs/goldfish_armv7_defconfig ]; then do_build goldfish_armv7 -armv7 fi echo "Done." exit 0