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" 29set_dirname () 30{ 31 eval $1="`dirname \"$2\"`" 32} 33 34# Same as set_dirname, but for the 'basename' command 35set_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. 42fail_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 51log () 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 59run () 60{ 61 if [ "$VERBOSE" = "yes" ] ; then 62 echo "### COMMAND: $@" 63 $@ 64 else 65 $@ >/dev/null 2>&1 66 fi 67} 68 69fail_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 85find_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 95set_dirname PROGDIR "$0" 96set_basename PROGNAME "$0" 97 98### 99### Get defaults 100### 101 102# Location of prebuilt kernel images relative to Android top-level 103PREBUILT_KERNEL_DIR="prebuilts/qemu-kernel/arm" 104 105# Look for top-level Android build source tree if not in environment 106 107if [ -n "$ANDROID_BUILD_TOP" ] ; then 108 OUT_DIR="$ANDROID_BUILD_TOP/$PREBUILT_KERNEL_DIR" 109else 110 OUT_DIR= 111fi 112 113TOOLCHAIN_NAME=arm-eabi-4.4.0 114TOOLCHAIN_PREFIX=arm-eabi 115GCC="$TOOLCHAIN_PREFIX-gcc" 116 117JOBS="`cat /proc/cpuinfo | grep -e "^processor" | wc -l`" 118 119### 120### Parse options 121### 122OPTION_HELP=no 123VERBOSE=no 124VERBOSE2=no 125OPTION_OUT_DIR= 126OPTION_CC= 127 128PARAMS="" 129 130for 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 166done 167 168if [ "$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 185fi 186 187### 188### Parse parameters 189### 190 191set_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 208set_parameters $PARAMS 209 210### 211### Determine build configuration 212### 213 214if [ -n "$OPTION_OUT_DIR" ] ; then 215 OUT_DIR="$OPTION_OUT_DIR" 216fi 217 218if [ -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 227fi 228 229if [ -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 236fi 237 238echo "Using output directory: $OUT_DIR" 239mkdir -p "$OUT_DIR" 240fail_panic "Could not create directory: $OUT_DIR" 241 242# Find toolchain 243 244if [ -n "$OPTION_CC" ]; then 245 GCC="$OPTION_CC" 246else 247 find_program GCC $TOOLCHAIN_PREFIX-gcc 248fi 249 250if [ -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 261fi 262 263CROSS_COMPILE="`echo $GCC | sed -e 's!gcc$!!g' `" 264echo "Using cross-toolchain prefix: $CROSS_COMPILE" 265 266# Do we have ccache in our path? 267find_program CCACHE ccache 268if [ -n "$CCACHE" ]; then 269 echo "Using ccache program: $CCACHE" 270 CROSS_COMPILE="ccache $CROSS_COMPILE" 271fi 272 273### 274### Do the build 275### 276 277cd "$KERNEL_DIR" 278ARCH=arm 279SUBARCH=arm 280 281export CROSS_COMPILE ARCH SUBARCH 282 283# $1: defconfig name (e.g. goldfish or goldfish_armv7) 284# $2: output suffix (e.g. "" or "-armv7") 285do_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 305do_build goldfish 306if [ -f arch/arm/configs/goldfish_armv7_defconfig ]; then 307 do_build goldfish_armv7 -armv7 308fi 309 310echo "Done." 311exit 0 312