Home | History | Annotate | Download | only in kernel
      1 #!/bin/sh
      2 #
      3 # Copyright (C) 2011 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 # This script is used to rebuild the Android goldfish arm-based kernel from
     19 # sources.
     20 
     21 ###
     22 ### Utilities
     23 ###
     24 
     25 # Implementation of 'dirname' that works safely when paths contains spaces
     26 # $1: output variable name
     27 # $2: path (may contain spaces)
     28 # Usage: set_dirname FOO "/path/to/foo with spaces"
     29 set_dirname ()
     30 {
     31     eval $1="`dirname \"$2\"`"
     32 }
     33 
     34 # Same as set_dirname, but for the 'basename' command
     35 set_basename ()
     36 {
     37     eval $1="`basename \"$2\"`"
     38 }
     39 
     40 # Check the status of the previous command, and print a message and exit
     41 # if it didn't succeed.
     42 fail_panic ()
     43 {
     44     if [ $? != 0 ]; then
     45         echo "ERROR: $@"
     46         exit 1
     47     fi
     48 }
     49 
     50 # Send a message to the log. Does nothing if --verbose is not used
     51 log ()
     52 {
     53     if [ "$VERBOSE" = "yes" ] ; then
     54         echo "$@"
     55     fi
     56 }
     57 
     58 # Run a comment. Print it to the output first if --verbose is used
     59 run ()
     60 {
     61     if [ "$VERBOSE" = "yes" ] ; then
     62         echo "### COMMAND: $@"
     63         $@
     64     else
     65         $@ >/dev/null 2>&1
     66     fi
     67 }
     68 
     69 fail_ifnotdir ()
     70 {
     71     local _dir="$1"
     72     if [ ! -d "$_dir" ]; then
     73         shift
     74         echo "ERROR: $@ ($_dir)"
     75         exit 1
     76     fi
     77 }
     78 
     79 # Check wether program '$2' is in your path, and set variable $1 to its
     80 # full path, or to empty otherwise.
     81 # Example: find_program FOO foo
     82 #
     83 # $1: Variable name
     84 # $2: Program name
     85 find_program ()
     86 {
     87     local FINDPROG_=`which $2 2>/dev/null`
     88     if [ -n "$FINDPROG_" ]; then
     89         eval $1="$FINDPROG_";
     90     else
     91         eval $1=
     92     fi
     93 }
     94 
     95 set_dirname  PROGDIR  "$0"
     96 set_basename PROGNAME "$0"
     97 
     98 ###
     99 ### Get defaults
    100 ###
    101 
    102 # Location of prebuilt kernel images relative to Android top-level
    103 PREBUILT_KERNEL_DIR="prebuilt/android-arm/kernel"
    104 
    105 # Look for top-level Android build source tree if not in environment
    106 
    107 if [ -n "$ANDROID_BUILD_TOP" ] ; then
    108     OUT_DIR="$ANDROID_BUILD_TOP/$PREBUILT_KERNEL_DIR"
    109 else
    110     OUT_DIR=
    111 fi
    112 
    113 TOOLCHAIN_NAME=arm-eabi-4.4.0
    114 TOOLCHAIN_PREFIX=arm-eabi
    115 GCC="$TOOLCHAIN_PREFIX-gcc"
    116 
    117 JOBS="`cat /proc/cpuinfo | grep -e "^processor" | wc -l`"
    118 
    119 ###
    120 ### Parse options
    121 ###
    122 OPTION_HELP=no
    123 VERBOSE=no
    124 VERBOSE2=no
    125 OPTION_OUT_DIR=
    126 OPTION_CC=
    127 
    128 PARAMS=""
    129 
    130 for opt do
    131     optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
    132     case "$opt" in
    133         --help|-h|-\?) OPTION_HELP=yes
    134             ;;
    135         --verbose)
    136             if [ "$VERBOSE" = "yes" ] ; then
    137                 VERBOSE2=yes
    138             else
    139                 VERBOSE=yes
    140             fi
    141             ;;
    142         --out-dir=*)
    143             OPTION_OUT_DIR="$optarg"
    144             ;;
    145         --cc=*)
    146             OPTION_CC="$optarg"
    147             ;;
    148         --toolchain=*)
    149             TOOLCHAIN_NAME="$optarg"
    150             ;;
    151         --jobs=*)
    152             JOBS="$optarg"
    153             ;;
    154         -*)
    155             echo "unknown option '$opt', use --help"
    156             exit 1
    157             ;;
    158         *)
    159             if [ -z "$PARAMS" ] ; then
    160                 PARAMS="$opt"
    161             else
    162                 PARAMS="$PARAMS $opt"
    163             fi
    164             ;;
    165     esac
    166 done
    167 
    168 if [ "$OPTION_HELP" = "yes" ] ; then
    169     echo "Usage: $PROGNAME <options> /path/to/kernel"
    170     echo ""
    171     echo "Rebuild the prebuilt Android goldfish-specific kernel from sources."
    172     echo ""
    173     echo "Options (default are inside brackets):"
    174     echo ""
    175     echo "    --help                Print this message."
    176     echo "    --verbose             Enable verbose output."
    177     echo "    --android=<path>      Set Android top-level directory [$ANDROID_BUILD_TOP]"
    178     echo "    --out-dir=<path>      Set output directory [$OUT_DIR]"
    179     echo "    --toolchain=<name>    Toolchain name [$TOOLCHAIN_NAME]"
    180     echo "    --cc=<path>           Path to C compiler [$GCC]"
    181     echo "    --jobs=<count>        Perform <count> parallel builds [$JOBS]"
    182     echo ""
    183     echo "The --toolchain option is ignored if you use the --cc one."
    184     exit 0
    185 fi
    186 
    187 ###
    188 ### Parse parameters
    189 ###
    190 
    191 set_parameters ()
    192 {
    193     if [ -z "$1" ] ; then
    194         echo "ERROR: Please specify path of kernel sources directory. See --help for details."
    195         exit 1
    196     fi
    197     if [ -n "$2" ]; then
    198         echo "ERROR: Too many arguments. See --help for details."
    199         exit 1
    200     fi
    201     KERNEL_DIR="$1"
    202     fail_ifnotdir "$KERNEL_DIR" "Missing kernel directory"
    203     fail_ifnotdir "$KERNEL_DIR/kernel" "Missing kernel-specific directory"
    204     fail_ifnotdir "$KERNEL_DIR/arch"   "Missing kernel-specific directory"
    205     fail_ifnotdir "$KERNEL_DIR/arch/arm/mach-goldfish" "Missing goldfish-specific directory"
    206 }
    207 
    208 set_parameters $PARAMS
    209 
    210 ###
    211 ### Determine build configuration
    212 ###
    213 
    214 if [ -n "$OPTION_OUT_DIR" ] ; then
    215     OUT_DIR="$OPTION_OUT_DIR"
    216 fi
    217 
    218 if [ -z "$ANDROID_BUILD_TOP" ] ; then
    219     # Assume that we are under $ANDROID_BUILD_TOP/prebuilt/android-arm/kernel
    220     ANDROID_BUILD_TOP="`cd \"$PROGDIR\"/../../.. && pwd`"
    221     if [ -d "$ANDROID_BUILD_TOP" ]; then
    222         echo "Probed Android top-level directory: $ANDROID_BUILD_TOP"
    223     else
    224         echo "ERROR: Can't find Android top-leveld directory. Please define ANDROID_BUILD_TOP"
    225         exit 1
    226     fi
    227 fi
    228 
    229 if [ -z "$OUT_DIR" ] ; then
    230     OUT_DIR="$ANDROID_BUILD_TOP/$PREBUILT_KERNEL_DIR"
    231     if [ ! -d "$OUT_DIR" ]; then
    232         echo "ERROR: Missing default output dir: $OUT_DIR"
    233         echo "Please use --out-dir=<path> to specify alternative output directory."
    234         exit 1
    235     fi
    236 fi
    237 
    238 echo "Using output directory: $OUT_DIR"
    239 mkdir -p "$OUT_DIR"
    240 fail_panic "Could not create directory: $OUT_DIR"
    241 
    242 # Find toolchain
    243 
    244 if [ -n "$OPTION_CC" ]; then
    245     GCC="$OPTION_CC"
    246 else
    247     find_program GCC $TOOLCHAIN_PREFIX-gcc
    248 fi
    249 
    250 if [ -z "$GCC" ]; then
    251     TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilt/linux-x86/toolchain/$TOOLCHAIN_NAME/bin"
    252     if [ ! -d "$TOOLCHAIN_DIR" ] ; then
    253         echo "ERROR: Missing directory: $TOOLCHAIN_DIR"
    254         exit 1
    255     fi
    256     GCC="$TOOLCHAIN_DIR/$TOOLCHAIN_PREFIX-gcc"
    257     if [ ! -f "$GCC" ] ; then
    258         echo "ERROR: Missing program file: $GCC"
    259         exit 1
    260     fi
    261 fi
    262 
    263 CROSS_COMPILE="`echo $GCC | sed -e 's!gcc$!!g' `"
    264 echo "Using cross-toolchain prefix: $CROSS_COMPILE"
    265 
    266 # Do we have ccache in our path?
    267 find_program CCACHE ccache
    268 if [ -n "$CCACHE" ]; then
    269     echo "Using ccache program: $CCACHE"
    270     CROSS_COMPILE="ccache $CROSS_COMPILE"
    271 fi
    272 
    273 ###
    274 ### Do the build
    275 ###
    276 
    277 cd "$KERNEL_DIR"
    278 ARCH=arm
    279 SUBARCH=arm
    280 
    281 export CROSS_COMPILE ARCH SUBARCH
    282 
    283 # $1: defconfig name (e.g. goldfish or goldfish_armv7)
    284 # $2: output suffix (e.g. "" or "-armv7")
    285 do_build ()
    286 {
    287     MAKE_FLAGS="-j$JOBS"
    288     # Use --verbose --verbose to see build commands
    289     if [ "$VERBOSE2" = "yes" ] ; then
    290         MAKE_FLAGS="$MAKE_FLAGS V=1"
    291     fi
    292     echo "Cleaning up source tree."
    293     git ls-files -o | xargs rm -f
    294     echo "Setting up $1_defconfig..."
    295     run make $1_defconfig
    296     fail_panic "Could not setup $1_defconfig build!"
    297     echo "Building $1_deconfig..."
    298     run make $MAKE_FLAGS
    299     fail_panic "Could not build $1_defconfig!"
    300     echo "Copying $1_defconfig binaries to $OUT_DIR."
    301     cp -f arch/arm/boot/zImage "$OUT_DIR/kernel-qemu$2"
    302     cp -f vmlinux "$OUT_DIR/vmlinux-qemu$2"
    303 }
    304 
    305 do_build goldfish
    306 if [ -f arch/arm/configs/goldfish_armv7_defconfig ]; then
    307     do_build goldfish_armv7 -armv7
    308 fi
    309 
    310 echo "Done."
    311 exit 0
    312