| #!/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="prebuilt/android-arm/kernel" |
| |
| # 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 <options> /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=<path> Set Android top-level directory [$ANDROID_BUILD_TOP]" |
| echo " --out-dir=<path> Set output directory [$OUT_DIR]" |
| echo " --toolchain=<name> Toolchain name [$TOOLCHAIN_NAME]" |
| echo " --cc=<path> Path to C compiler [$GCC]" |
| echo " --jobs=<count> Perform <count> 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=<path> 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 |