envsetup.sh revision 515ab1e2d11052069f2e3127bb6ab71c347b4eba
1function hmm() {
2cat <<EOF
3Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
4- lunch:   lunch <product_name>-<build_variant>
5- tapas:   tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
6- croot:   Changes directory to the top of the tree.
7- m:       Makes from the top of the tree.
8- mm:      Builds all of the modules in the current directory, but not their dependencies.
9- mmm:     Builds all of the modules in the supplied directories, but not their dependencies.
10           To limit the modules being built use the syntax: mmm dir/:target1,target2.
11- mma:     Builds all of the modules in the current directory, and their dependencies.
12- mmma:    Builds all of the modules in the supplied directories, and their dependencies.
13- cgrep:   Greps on all local C/C++ files.
14- ggrep:   Greps on all local Gradle files.
15- jgrep:   Greps on all local Java files.
16- resgrep: Greps on all local res/*.xml files.
17- mangrep: Greps on all local AndroidManifest.xml files.
18- mgrep:   Greps on all local Makefiles files.
19- sepgrep: Greps on all local sepolicy files.
20- sgrep:   Greps on all local source files.
21- godir:   Go to the directory containing a file.
22
23Environemnt options:
24- SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
25                 ASAN_OPTIONS=detect_leaks=0 will be set by default until the
26                 build is leak-check clean.
27
28Look at the source to view more functions. The complete list is:
29EOF
30    T=$(gettop)
31    local A
32    A=""
33    for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
34      A="$A $i"
35    done
36    echo $A
37}
38
39# Get the value of a build variable as an absolute path.
40function get_abs_build_var()
41{
42    T=$(gettop)
43    if [ ! "$T" ]; then
44        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
45        return
46    fi
47    (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
48      command make --no-print-directory -f build/core/config.mk dumpvar-abs-$1)
49}
50
51# Get the exact value of a build variable.
52function get_build_var()
53{
54    T=$(gettop)
55    if [ ! "$T" ]; then
56        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
57        return
58    fi
59    (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
60      command make --no-print-directory -f build/core/config.mk dumpvar-$1)
61}
62
63# check to see if the supplied product is one we can build
64function check_product()
65{
66    T=$(gettop)
67    if [ ! "$T" ]; then
68        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
69        return
70    fi
71        TARGET_PRODUCT=$1 \
72        TARGET_BUILD_VARIANT= \
73        TARGET_BUILD_TYPE= \
74        TARGET_BUILD_APPS= \
75        get_build_var TARGET_DEVICE > /dev/null
76    # hide successful answers, but allow the errors to show
77}
78
79VARIANT_CHOICES=(user userdebug eng)
80
81# check to see if the supplied variant is valid
82function check_variant()
83{
84    for v in ${VARIANT_CHOICES[@]}
85    do
86        if [ "$v" = "$1" ]
87        then
88            return 0
89        fi
90    done
91    return 1
92}
93
94function setpaths()
95{
96    T=$(gettop)
97    if [ ! "$T" ]; then
98        echo "Couldn't locate the top of the tree.  Try setting TOP."
99        return
100    fi
101
102    ##################################################################
103    #                                                                #
104    #              Read me before you modify this code               #
105    #                                                                #
106    #   This function sets ANDROID_BUILD_PATHS to what it is adding  #
107    #   to PATH, and the next time it is run, it removes that from   #
108    #   PATH.  This is required so lunch can be run more than once   #
109    #   and still have working paths.                                #
110    #                                                                #
111    ##################################################################
112
113    # Note: on windows/cygwin, ANDROID_BUILD_PATHS will contain spaces
114    # due to "C:\Program Files" being in the path.
115
116    # out with the old
117    if [ -n "$ANDROID_BUILD_PATHS" ] ; then
118        export PATH=${PATH/$ANDROID_BUILD_PATHS/}
119    fi
120    if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then
121        export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/}
122        # strip leading ':', if any
123        export PATH=${PATH/:%/}
124    fi
125
126    # and in with the new
127    prebuiltdir=$(getprebuilt)
128    gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS)
129
130    # defined in core/config.mk
131    targetgccversion=$(get_build_var TARGET_GCC_VERSION)
132    targetgccversion2=$(get_build_var 2ND_TARGET_GCC_VERSION)
133    export TARGET_GCC_VERSION=$targetgccversion
134
135    # The gcc toolchain does not exists for windows/cygwin. In this case, do not reference it.
136    export ANDROID_TOOLCHAIN=
137    export ANDROID_TOOLCHAIN_2ND_ARCH=
138    local ARCH=$(get_build_var TARGET_ARCH)
139    case $ARCH in
140        x86) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
141            ;;
142        x86_64) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
143            ;;
144        arm) toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin
145            ;;
146        arm64) toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin;
147               toolchaindir2=arm/arm-linux-androideabi-$targetgccversion2/bin
148            ;;
149        mips|mips64) toolchaindir=mips/mips64el-linux-android-$targetgccversion/bin
150            ;;
151        *)
152            echo "Can't find toolchain for unknown architecture: $ARCH"
153            toolchaindir=xxxxxxxxx
154            ;;
155    esac
156    if [ -d "$gccprebuiltdir/$toolchaindir" ]; then
157        export ANDROID_TOOLCHAIN=$gccprebuiltdir/$toolchaindir
158    fi
159
160    if [ -d "$gccprebuiltdir/$toolchaindir2" ]; then
161        export ANDROID_TOOLCHAIN_2ND_ARCH=$gccprebuiltdir/$toolchaindir2
162    fi
163
164    unset ANDROID_KERNEL_TOOLCHAIN_PATH
165    case $ARCH in
166        arm)
167            # Legacy toolchain configuration used for ARM kernel compilation
168            toolchaindir=arm/arm-eabi-$targetgccversion/bin
169            if [ -d "$gccprebuiltdir/$toolchaindir" ]; then
170                 export ARM_EABI_TOOLCHAIN="$gccprebuiltdir/$toolchaindir"
171                 ANDROID_KERNEL_TOOLCHAIN_PATH="$ARM_EABI_TOOLCHAIN":
172            fi
173            ;;
174        *)
175            # No need to set ARM_EABI_TOOLCHAIN for other ARCHs
176            ;;
177    esac
178
179    export ANDROID_DEV_SCRIPTS=$T/development/scripts:$T/prebuilts/devtools/tools:$T/external/selinux/prebuilts/bin
180    export ANDROID_BUILD_PATHS=$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_TOOLCHAIN:$ANDROID_TOOLCHAIN_2ND_ARCH:$ANDROID_KERNEL_TOOLCHAIN_PATH$ANDROID_DEV_SCRIPTS:
181
182    # If prebuilts/android-emulator/<system>/ exists, prepend it to our PATH
183    # to ensure that the corresponding 'emulator' binaries are used.
184    case $(uname -s) in
185        Darwin)
186            ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/darwin-x86_64
187            ;;
188        Linux)
189            ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/linux-x86_64
190            ;;
191        *)
192            ANDROID_EMULATOR_PREBUILTS=
193            ;;
194    esac
195    if [ -n "$ANDROID_EMULATOR_PREBUILTS" -a -d "$ANDROID_EMULATOR_PREBUILTS" ]; then
196        ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS$ANDROID_EMULATOR_PREBUILTS:
197        export ANDROID_EMULATOR_PREBUILTS
198    fi
199
200    export PATH=$ANDROID_BUILD_PATHS$PATH
201    export PYTHONPATH=$T/system/core:$PYTHONPATH
202
203    unset ANDROID_JAVA_TOOLCHAIN
204    unset ANDROID_PRE_BUILD_PATHS
205    if [ -n "$JAVA_HOME" ]; then
206        export ANDROID_JAVA_TOOLCHAIN=$JAVA_HOME/bin
207        export ANDROID_PRE_BUILD_PATHS=$ANDROID_JAVA_TOOLCHAIN:
208        export PATH=$ANDROID_PRE_BUILD_PATHS$PATH
209    fi
210
211    unset ANDROID_PRODUCT_OUT
212    export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)
213    export OUT=$ANDROID_PRODUCT_OUT
214
215    unset ANDROID_HOST_OUT
216    export ANDROID_HOST_OUT=$(get_abs_build_var HOST_OUT)
217
218    # needed for building linux on MacOS
219    # TODO: fix the path
220    #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
221}
222
223function printconfig()
224{
225    T=$(gettop)
226    if [ ! "$T" ]; then
227        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
228        return
229    fi
230    get_build_var report_config
231}
232
233function set_stuff_for_environment()
234{
235    settitle
236    set_java_home
237    setpaths
238    set_sequence_number
239
240    export ANDROID_BUILD_TOP=$(gettop)
241    # With this environment variable new GCC can apply colors to warnings/errors
242    export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
243    export ASAN_OPTIONS=detect_leaks=0
244}
245
246function set_sequence_number()
247{
248    export BUILD_ENV_SEQUENCE_NUMBER=10
249}
250
251function settitle()
252{
253    if [ "$STAY_OFF_MY_LAWN" = "" ]; then
254        local arch=$(gettargetarch)
255        local product=$TARGET_PRODUCT
256        local variant=$TARGET_BUILD_VARIANT
257        local apps=$TARGET_BUILD_APPS
258        if [ -z "$apps" ]; then
259            export PROMPT_COMMAND="echo -ne \"\033]0;[${arch}-${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""
260        else
261            export PROMPT_COMMAND="echo -ne \"\033]0;[$arch $apps $variant] ${USER}@${HOSTNAME}: ${PWD}\007\""
262        fi
263    fi
264}
265
266function addcompletions()
267{
268    local T dir f
269
270    # Keep us from trying to run in something that isn't bash.
271    if [ -z "${BASH_VERSION}" ]; then
272        return
273    fi
274
275    # Keep us from trying to run in bash that's too old.
276    if [ ${BASH_VERSINFO[0]} -lt 3 ]; then
277        return
278    fi
279
280    dir="sdk/bash_completion"
281    if [ -d ${dir} ]; then
282        for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do
283            echo "including $f"
284            . $f
285        done
286    fi
287}
288
289function choosetype()
290{
291    echo "Build type choices are:"
292    echo "     1. release"
293    echo "     2. debug"
294    echo
295
296    local DEFAULT_NUM DEFAULT_VALUE
297    DEFAULT_NUM=1
298    DEFAULT_VALUE=release
299
300    export TARGET_BUILD_TYPE=
301    local ANSWER
302    while [ -z $TARGET_BUILD_TYPE ]
303    do
304        echo -n "Which would you like? ["$DEFAULT_NUM"] "
305        if [ -z "$1" ] ; then
306            read ANSWER
307        else
308            echo $1
309            ANSWER=$1
310        fi
311        case $ANSWER in
312        "")
313            export TARGET_BUILD_TYPE=$DEFAULT_VALUE
314            ;;
315        1)
316            export TARGET_BUILD_TYPE=release
317            ;;
318        release)
319            export TARGET_BUILD_TYPE=release
320            ;;
321        2)
322            export TARGET_BUILD_TYPE=debug
323            ;;
324        debug)
325            export TARGET_BUILD_TYPE=debug
326            ;;
327        *)
328            echo
329            echo "I didn't understand your response.  Please try again."
330            echo
331            ;;
332        esac
333        if [ -n "$1" ] ; then
334            break
335        fi
336    done
337
338    set_stuff_for_environment
339}
340
341#
342# This function isn't really right:  It chooses a TARGET_PRODUCT
343# based on the list of boards.  Usually, that gets you something
344# that kinda works with a generic product, but really, you should
345# pick a product by name.
346#
347function chooseproduct()
348{
349    if [ "x$TARGET_PRODUCT" != x ] ; then
350        default_value=$TARGET_PRODUCT
351    else
352        default_value=aosp_arm
353    fi
354
355    export TARGET_PRODUCT=
356    local ANSWER
357    while [ -z "$TARGET_PRODUCT" ]
358    do
359        echo -n "Which product would you like? [$default_value] "
360        if [ -z "$1" ] ; then
361            read ANSWER
362        else
363            echo $1
364            ANSWER=$1
365        fi
366
367        if [ -z "$ANSWER" ] ; then
368            export TARGET_PRODUCT=$default_value
369        else
370            if check_product $ANSWER
371            then
372                export TARGET_PRODUCT=$ANSWER
373            else
374                echo "** Not a valid product: $ANSWER"
375            fi
376        fi
377        if [ -n "$1" ] ; then
378            break
379        fi
380    done
381
382    set_stuff_for_environment
383}
384
385function choosevariant()
386{
387    echo "Variant choices are:"
388    local index=1
389    local v
390    for v in ${VARIANT_CHOICES[@]}
391    do
392        # The product name is the name of the directory containing
393        # the makefile we found, above.
394        echo "     $index. $v"
395        index=$(($index+1))
396    done
397
398    local default_value=eng
399    local ANSWER
400
401    export TARGET_BUILD_VARIANT=
402    while [ -z "$TARGET_BUILD_VARIANT" ]
403    do
404        echo -n "Which would you like? [$default_value] "
405        if [ -z "$1" ] ; then
406            read ANSWER
407        else
408            echo $1
409            ANSWER=$1
410        fi
411
412        if [ -z "$ANSWER" ] ; then
413            export TARGET_BUILD_VARIANT=$default_value
414        elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
415            if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then
416                export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[$(($ANSWER-1))]}
417            fi
418        else
419            if check_variant $ANSWER
420            then
421                export TARGET_BUILD_VARIANT=$ANSWER
422            else
423                echo "** Not a valid variant: $ANSWER"
424            fi
425        fi
426        if [ -n "$1" ] ; then
427            break
428        fi
429    done
430}
431
432function choosecombo()
433{
434    choosetype $1
435
436    echo
437    echo
438    chooseproduct $2
439
440    echo
441    echo
442    choosevariant $3
443
444    echo
445    set_stuff_for_environment
446    printconfig
447}
448
449# Clear this variable.  It will be built up again when the vendorsetup.sh
450# files are included at the end of this file.
451unset LUNCH_MENU_CHOICES
452function add_lunch_combo()
453{
454    local new_combo=$1
455    local c
456    for c in ${LUNCH_MENU_CHOICES[@]} ; do
457        if [ "$new_combo" = "$c" ] ; then
458            return
459        fi
460    done
461    LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
462}
463
464# add the default one here
465add_lunch_combo aosp_arm-eng
466add_lunch_combo aosp_arm64-eng
467add_lunch_combo aosp_mips-eng
468add_lunch_combo aosp_mips64-eng
469add_lunch_combo aosp_x86-eng
470add_lunch_combo aosp_x86_64-eng
471
472function print_lunch_menu()
473{
474    local uname=$(uname)
475    echo
476    echo "You're building on" $uname
477    echo
478    echo "Lunch menu... pick a combo:"
479
480    local i=1
481    local choice
482    for choice in ${LUNCH_MENU_CHOICES[@]}
483    do
484        echo "     $i. $choice"
485        i=$(($i+1))
486    done
487
488    echo
489}
490
491function lunch()
492{
493    local answer
494
495    if [ "$1" ] ; then
496        answer=$1
497    else
498        print_lunch_menu
499        echo -n "Which would you like? [aosp_arm-eng] "
500        read answer
501    fi
502
503    local selection=
504
505    if [ -z "$answer" ]
506    then
507        selection=aosp_arm-eng
508    elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
509    then
510        if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
511        then
512            selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
513        fi
514    elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
515    then
516        selection=$answer
517    fi
518
519    if [ -z "$selection" ]
520    then
521        echo
522        echo "Invalid lunch combo: $answer"
523        return 1
524    fi
525
526    export TARGET_BUILD_APPS=
527
528    local product=$(echo -n $selection | sed -e "s/-.*$//")
529    check_product $product
530    if [ $? -ne 0 ]
531    then
532        echo
533        echo "** Don't have a product spec for: '$product'"
534        echo "** Do you have the right repo manifest?"
535        product=
536    fi
537
538    local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
539    check_variant $variant
540    if [ $? -ne 0 ]
541    then
542        echo
543        echo "** Invalid variant: '$variant'"
544        echo "** Must be one of ${VARIANT_CHOICES[@]}"
545        variant=
546    fi
547
548    if [ -z "$product" -o -z "$variant" ]
549    then
550        echo
551        return 1
552    fi
553
554    export TARGET_PRODUCT=$product
555    export TARGET_BUILD_VARIANT=$variant
556    export TARGET_BUILD_TYPE=release
557
558    echo
559
560    set_stuff_for_environment
561    printconfig
562}
563
564# Tab completion for lunch.
565function _lunch()
566{
567    local cur prev opts
568    COMPREPLY=()
569    cur="${COMP_WORDS[COMP_CWORD]}"
570    prev="${COMP_WORDS[COMP_CWORD-1]}"
571
572    COMPREPLY=( $(compgen -W "${LUNCH_MENU_CHOICES[*]}" -- ${cur}) )
573    return 0
574}
575complete -F _lunch lunch
576
577# Configures the build to build unbundled apps.
578# Run tapas with one or more app names (from LOCAL_PACKAGE_NAME)
579function tapas()
580{
581    local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5|arm64|x86_64|mips64)$' | xargs)"
582    local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)"
583    local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
584    local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|armv5|arm64|x86_64|mips64|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)"
585
586    if [ $(echo $arch | wc -w) -gt 1 ]; then
587        echo "tapas: Error: Multiple build archs supplied: $arch"
588        return
589    fi
590    if [ $(echo $variant | wc -w) -gt 1 ]; then
591        echo "tapas: Error: Multiple build variants supplied: $variant"
592        return
593    fi
594    if [ $(echo $density | wc -w) -gt 1 ]; then
595        echo "tapas: Error: Multiple densities supplied: $density"
596        return
597    fi
598
599    local product=aosp_arm
600    case $arch in
601      x86)    product=aosp_x86;;
602      mips)   product=aosp_mips;;
603      armv5)  product=generic_armv5;;
604      arm64)  product=aosp_arm64;;
605      x86_64) product=aosp_x86_64;;
606      mips64)  product=aosp_mips64;;
607    esac
608    if [ -z "$variant" ]; then
609        variant=eng
610    fi
611    if [ -z "$apps" ]; then
612        apps=all
613    fi
614    if [ -z "$density" ]; then
615        density=alldpi
616    fi
617
618    export TARGET_PRODUCT=$product
619    export TARGET_BUILD_VARIANT=$variant
620    export TARGET_BUILD_DENSITY=$density
621    export TARGET_BUILD_TYPE=release
622    export TARGET_BUILD_APPS=$apps
623
624    set_stuff_for_environment
625    printconfig
626}
627
628function gettop
629{
630    local TOPFILE=build/core/envsetup.mk
631    if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
632        # The following circumlocution ensures we remove symlinks from TOP.
633        (cd $TOP; PWD= /bin/pwd)
634    else
635        if [ -f $TOPFILE ] ; then
636            # The following circumlocution (repeated below as well) ensures
637            # that we record the true directory name and not one that is
638            # faked up with symlink names.
639            PWD= /bin/pwd
640        else
641            local HERE=$PWD
642            T=
643            while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
644                \cd ..
645                T=`PWD= /bin/pwd -P`
646            done
647            \cd $HERE
648            if [ -f "$T/$TOPFILE" ]; then
649                echo $T
650            fi
651        fi
652    fi
653}
654
655# Return driver for "make", if any (eg. static analyzer)
656function getdriver()
657{
658    local T="$1"
659    test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER
660    if [ -n "$WITH_STATIC_ANALYZER" ]; then
661        echo "\
662$T/prebuilts/misc/linux-x86/analyzer/tools/scan-build/scan-build \
663--use-analyzer $T/prebuilts/misc/linux-x86/analyzer/bin/analyzer \
664--status-bugs \
665--top=$T"
666    fi
667}
668
669function m()
670{
671    local T=$(gettop)
672    local DRV=$(getdriver $T)
673    if [ "$T" ]; then
674        $DRV make -C $T -f build/core/main.mk $@
675    else
676        echo "Couldn't locate the top of the tree.  Try setting TOP."
677        return 1
678    fi
679}
680
681function findmakefile()
682{
683    TOPFILE=build/core/envsetup.mk
684    local HERE=$PWD
685    T=
686    while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
687        T=`PWD= /bin/pwd`
688        if [ -f "$T/Android.mk" ]; then
689            echo $T/Android.mk
690            \cd $HERE
691            return
692        fi
693        \cd ..
694    done
695    \cd $HERE
696}
697
698function mm()
699{
700    local T=$(gettop)
701    local DRV=$(getdriver $T)
702    # If we're sitting in the root of the build tree, just do a
703    # normal make.
704    if [ -f build/core/envsetup.mk -a -f Makefile ]; then
705        $DRV make $@
706    else
707        # Find the closest Android.mk file.
708        local M=$(findmakefile)
709        local MODULES=
710        local GET_INSTALL_PATH=
711        local ARGS=
712        # Remove the path to top as the makefilepath needs to be relative
713        local M=`echo $M|sed 's:'$T'/::'`
714        if [ ! "$T" ]; then
715            echo "Couldn't locate the top of the tree.  Try setting TOP."
716            return 1
717        elif [ ! "$M" ]; then
718            echo "Couldn't locate a makefile from the current directory."
719            return 1
720        else
721            for ARG in $@; do
722                case $ARG in
723                  GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;;
724                esac
725            done
726            if [ -n "$GET_INSTALL_PATH" ]; then
727              MODULES=
728              ARGS=GET-INSTALL-PATH
729            else
730              MODULES=all_modules
731              ARGS=$@
732            fi
733            ONE_SHOT_MAKEFILE=$M $DRV make -C $T -f build/core/main.mk $MODULES $ARGS
734        fi
735    fi
736}
737
738function mmm()
739{
740    local T=$(gettop)
741    local DRV=$(getdriver $T)
742    if [ "$T" ]; then
743        local MAKEFILE=
744        local MODULES=
745        local ARGS=
746        local DIR TO_CHOP
747        local GET_INSTALL_PATH=
748        local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
749        local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
750        for DIR in $DIRS ; do
751            MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`
752            if [ "$MODULES" = "" ]; then
753                MODULES=all_modules
754            fi
755            DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
756            if [ -f $DIR/Android.mk ]; then
757                local TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
758                local TO_CHOP=`expr $TO_CHOP + 1`
759                local START=`PWD= /bin/pwd`
760                local MFILE=`echo $START | cut -c${TO_CHOP}-`
761                if [ "$MFILE" = "" ] ; then
762                    MFILE=$DIR/Android.mk
763                else
764                    MFILE=$MFILE/$DIR/Android.mk
765                fi
766                MAKEFILE="$MAKEFILE $MFILE"
767            else
768                case $DIR in
769                  showcommands | snod | dist | incrementaljavac) ARGS="$ARGS $DIR";;
770                  GET-INSTALL-PATH) GET_INSTALL_PATH=$DIR;;
771                  *) echo "No Android.mk in $DIR."; return 1;;
772                esac
773            fi
774        done
775        if [ -n "$GET_INSTALL_PATH" ]; then
776          ARGS=$GET_INSTALL_PATH
777          MODULES=
778        fi
779        ONE_SHOT_MAKEFILE="$MAKEFILE" $DRV make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $ARGS
780    else
781        echo "Couldn't locate the top of the tree.  Try setting TOP."
782        return 1
783    fi
784}
785
786function mma()
787{
788  local T=$(gettop)
789  local DRV=$(getdriver $T)
790  if [ -f build/core/envsetup.mk -a -f Makefile ]; then
791    $DRV make $@
792  else
793    if [ ! "$T" ]; then
794      echo "Couldn't locate the top of the tree.  Try setting TOP."
795      return 1
796    fi
797    local MY_PWD=`PWD= /bin/pwd|sed 's:'$T'/::'`
798    $DRV make -C $T -f build/core/main.mk $@ all_modules BUILD_MODULES_IN_PATHS="$MY_PWD"
799  fi
800}
801
802function mmma()
803{
804  local T=$(gettop)
805  local DRV=$(getdriver $T)
806  if [ "$T" ]; then
807    local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
808    local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
809    local MY_PWD=`PWD= /bin/pwd`
810    if [ "$MY_PWD" = "$T" ]; then
811      MY_PWD=
812    else
813      MY_PWD=`echo $MY_PWD|sed 's:'$T'/::'`
814    fi
815    local DIR=
816    local MODULE_PATHS=
817    local ARGS=
818    for DIR in $DIRS ; do
819      if [ -d $DIR ]; then
820        if [ "$MY_PWD" = "" ]; then
821          MODULE_PATHS="$MODULE_PATHS $DIR"
822        else
823          MODULE_PATHS="$MODULE_PATHS $MY_PWD/$DIR"
824        fi
825      else
826        case $DIR in
827          showcommands | snod | dist | incrementaljavac) ARGS="$ARGS $DIR";;
828          *) echo "Couldn't find directory $DIR"; return 1;;
829        esac
830      fi
831    done
832    $DRV make -C $T -f build/core/main.mk $DASH_ARGS $ARGS all_modules BUILD_MODULES_IN_PATHS="$MODULE_PATHS"
833  else
834    echo "Couldn't locate the top of the tree.  Try setting TOP."
835    return 1
836  fi
837}
838
839function croot()
840{
841    T=$(gettop)
842    if [ "$T" ]; then
843        \cd $(gettop)
844    else
845        echo "Couldn't locate the top of the tree.  Try setting TOP."
846    fi
847}
848
849function cproj()
850{
851    TOPFILE=build/core/envsetup.mk
852    local HERE=$PWD
853    T=
854    while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
855        T=$PWD
856        if [ -f "$T/Android.mk" ]; then
857            \cd $T
858            return
859        fi
860        \cd ..
861    done
862    \cd $HERE
863    echo "can't find Android.mk"
864}
865
866# simplified version of ps; output in the form
867# <pid> <procname>
868function qpid() {
869    local prepend=''
870    local append=''
871    if [ "$1" = "--exact" ]; then
872        prepend=' '
873        append='$'
874        shift
875    elif [ "$1" = "--help" -o "$1" = "-h" ]; then
876		echo "usage: qpid [[--exact] <process name|pid>"
877		return 255
878	fi
879
880    local EXE="$1"
881    if [ "$EXE" ] ; then
882		qpid | \grep "$prepend$EXE$append"
883	else
884		adb shell ps \
885			| tr -d '\r' \
886			| sed -e 1d -e 's/^[^ ]* *\([0-9]*\).* \([^ ]*\)$/\1 \2/'
887	fi
888}
889
890function pid()
891{
892    local prepend=''
893    local append=''
894    if [ "$1" = "--exact" ]; then
895        prepend=' '
896        append='$'
897        shift
898    fi
899    local EXE="$1"
900    if [ "$EXE" ] ; then
901        local PID=`adb shell ps \
902            | tr -d '\r' \
903            | \grep "$prepend$EXE$append" \
904            | sed -e 's/^[^ ]* *\([0-9]*\).*$/\1/'`
905        echo "$PID"
906    else
907        echo "usage: pid [--exact] <process name>"
908		return 255
909    fi
910}
911
912# coredump_setup - enable core dumps globally for any process
913#                  that has the core-file-size limit set correctly
914#
915# NOTE: You must call also coredump_enable for a specific process
916#       if its core-file-size limit is not set already.
917# NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
918
919function coredump_setup()
920{
921	echo "Getting root...";
922	adb root;
923	adb wait-for-device;
924
925	echo "Remounting root parition read-write...";
926	adb shell mount -w -o remount -t rootfs rootfs;
927	sleep 1;
928	adb wait-for-device;
929	adb shell mkdir -p /cores;
930	adb shell mount -t tmpfs tmpfs /cores;
931	adb shell chmod 0777 /cores;
932
933	echo "Granting SELinux permission to dump in /cores...";
934	adb shell restorecon -R /cores;
935
936	echo "Set core pattern.";
937	adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
938
939	echo "Done."
940}
941
942# coredump_enable - enable core dumps for the specified process
943# $1 = PID of process (e.g., $(pid mediaserver))
944#
945# NOTE: coredump_setup must have been called as well for a core
946#       dump to actually be generated.
947
948function coredump_enable()
949{
950	local PID=$1;
951	if [ -z "$PID" ]; then
952		printf "Expecting a PID!\n";
953		return;
954	fi;
955	echo "Setting core limit for $PID to infinite...";
956	adb shell prlimit $PID 4 -1 -1
957}
958
959# core - send SIGV and pull the core for process
960# $1 = PID of process (e.g., $(pid mediaserver))
961#
962# NOTE: coredump_setup must be called once per boot for core dumps to be
963#       enabled globally.
964
965function core()
966{
967	local PID=$1;
968
969	if [ -z "$PID" ]; then
970		printf "Expecting a PID!\n";
971		return;
972	fi;
973
974	local CORENAME=core.$PID;
975	local COREPATH=/cores/$CORENAME;
976	local SIG=SEGV;
977
978	coredump_enable $1;
979
980	local done=0;
981	while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
982		printf "\tSending SIG%s to %d...\n" $SIG $PID;
983		adb shell kill -$SIG $PID;
984		sleep 1;
985	done;
986
987	adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
988	echo "Done: core is under $COREPATH on device.";
989}
990
991# systemstack - dump the current stack trace of all threads in the system process
992# to the usual ANR traces file
993function systemstack()
994{
995    stacks system_server
996}
997
998function stacks()
999{
1000    if [[ $1 =~ ^[0-9]+$ ]] ; then
1001        local PID="$1"
1002    elif [ "$1" ] ; then
1003        local PIDLIST="$(pid $1)"
1004        if [[ $PIDLIST =~ ^[0-9]+$ ]] ; then
1005            local PID="$PIDLIST"
1006        elif [ "$PIDLIST" ] ; then
1007            echo "more than one process: $1"
1008        else
1009            echo "no such process: $1"
1010        fi
1011    else
1012        echo "usage: stacks [pid|process name]"
1013    fi
1014
1015    if [ "$PID" ] ; then
1016        # Determine whether the process is native
1017        if adb shell ls -l /proc/$PID/exe | grep -q /system/bin/app_process ; then
1018            # Dump stacks of Dalvik process
1019            local TRACES=/data/anr/traces.txt
1020            local ORIG=/data/anr/traces.orig
1021            local TMP=/data/anr/traces.tmp
1022
1023            # Keep original traces to avoid clobbering
1024            adb shell mv $TRACES $ORIG
1025
1026            # Make sure we have a usable file
1027            adb shell touch $TRACES
1028            adb shell chmod 666 $TRACES
1029
1030            # Dump stacks and wait for dump to finish
1031            adb shell kill -3 $PID
1032            adb shell notify $TRACES >/dev/null
1033
1034            # Restore original stacks, and show current output
1035            adb shell mv $TRACES $TMP
1036            adb shell mv $ORIG $TRACES
1037            adb shell cat $TMP
1038        else
1039            # Dump stacks of native process
1040            local USE64BIT="$(is64bit $PID)"
1041            adb shell debuggerd$USE64BIT -b $PID
1042        fi
1043    fi
1044}
1045
1046# Read the ELF header from /proc/$PID/exe to determine if the process is
1047# 64-bit.
1048function is64bit()
1049{
1050    local PID="$1"
1051    if [ "$PID" ] ; then
1052        if [[ "$(adb shell cat /proc/$PID/exe | xxd -l 1 -s 4 -ps)" -eq "02" ]] ; then
1053            echo "64"
1054        else
1055            echo ""
1056        fi
1057    else
1058        echo ""
1059    fi
1060}
1061
1062case `uname -s` in
1063    Darwin)
1064        function sgrep()
1065        {
1066            find -E . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.(c|h|cc|cpp|S|java|xml|sh|mk|aidl)' -print0 | xargs -0 grep --color -n "$@"
1067        }
1068
1069        ;;
1070    *)
1071        function sgrep()
1072        {
1073            find . -name .repo -prune -o -name .git -prune -o  -type f -iregex '.*\.\(c\|h\|cc\|cpp\|S\|java\|xml\|sh\|mk\|aidl\)' -print0 | xargs -0 grep --color -n "$@"
1074        }
1075        ;;
1076esac
1077
1078function gettargetarch
1079{
1080    get_build_var TARGET_ARCH
1081}
1082
1083function ggrep()
1084{
1085    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.gradle" -print0 | xargs -0 grep --color -n "$@"
1086}
1087
1088function jgrep()
1089{
1090    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" -print0 | xargs -0 grep --color -n "$@"
1091}
1092
1093function cgrep()
1094{
1095    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) -print0 | xargs -0 grep --color -n "$@"
1096}
1097
1098function resgrep()
1099{
1100    for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do find $dir -type f -name '*\.xml' -print0 | xargs -0 grep --color -n "$@"; done;
1101}
1102
1103function mangrep()
1104{
1105    find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'AndroidManifest.xml' -print0 | xargs -0 grep --color -n "$@"
1106}
1107
1108function sepgrep()
1109{
1110    find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d -print0 | xargs -0 grep --color -n -r --exclude-dir=\.git "$@"
1111}
1112
1113case `uname -s` in
1114    Darwin)
1115        function mgrep()
1116        {
1117            find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -print0 | xargs -0 grep --color -n "$@"
1118        }
1119
1120        function treegrep()
1121        {
1122            find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n -i "$@"
1123        }
1124
1125        ;;
1126    *)
1127        function mgrep()
1128        {
1129            find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f -print0 | xargs -0 grep --color -n "$@"
1130        }
1131
1132        function treegrep()
1133        {
1134            find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "$@"
1135        }
1136
1137        ;;
1138esac
1139
1140function getprebuilt
1141{
1142    get_abs_build_var ANDROID_PREBUILTS
1143}
1144
1145function tracedmdump()
1146{
1147    T=$(gettop)
1148    if [ ! "$T" ]; then
1149        echo "Couldn't locate the top of the tree.  Try setting TOP."
1150        return
1151    fi
1152    local prebuiltdir=$(getprebuilt)
1153    local arch=$(gettargetarch)
1154    local KERNEL=$T/prebuilts/qemu-kernel/$arch/vmlinux-qemu
1155
1156    local TRACE=$1
1157    if [ ! "$TRACE" ] ; then
1158        echo "usage:  tracedmdump  tracename"
1159        return
1160    fi
1161
1162    if [ ! -r "$KERNEL" ] ; then
1163        echo "Error: cannot find kernel: '$KERNEL'"
1164        return
1165    fi
1166
1167    local BASETRACE=$(basename $TRACE)
1168    if [ "$BASETRACE" = "$TRACE" ] ; then
1169        TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE
1170    fi
1171
1172    echo "post-processing traces..."
1173    rm -f $TRACE/qtrace.dexlist
1174    post_trace $TRACE
1175    if [ $? -ne 0 ]; then
1176        echo "***"
1177        echo "*** Error: malformed trace.  Did you remember to exit the emulator?"
1178        echo "***"
1179        return
1180    fi
1181    echo "generating dexlist output..."
1182    /bin/ls $ANDROID_PRODUCT_OUT/system/framework/*.jar $ANDROID_PRODUCT_OUT/system/app/*.apk $ANDROID_PRODUCT_OUT/data/app/*.apk 2>/dev/null | xargs dexlist > $TRACE/qtrace.dexlist
1183    echo "generating dmtrace data..."
1184    q2dm -r $ANDROID_PRODUCT_OUT/symbols $TRACE $KERNEL $TRACE/dmtrace || return
1185    echo "generating html file..."
1186    dmtracedump -h $TRACE/dmtrace >| $TRACE/dmtrace.html || return
1187    echo "done, see $TRACE/dmtrace.html for details"
1188    echo "or run:"
1189    echo "    traceview $TRACE/dmtrace"
1190}
1191
1192# communicate with a running device or emulator, set up necessary state,
1193# and run the hat command.
1194function runhat()
1195{
1196    # process standard adb options
1197    local adbTarget=""
1198    if [ "$1" = "-d" -o "$1" = "-e" ]; then
1199        adbTarget=$1
1200        shift 1
1201    elif [ "$1" = "-s" ]; then
1202        adbTarget="$1 $2"
1203        shift 2
1204    fi
1205    local adbOptions=${adbTarget}
1206    #echo adbOptions = ${adbOptions}
1207
1208    # runhat options
1209    local targetPid=$1
1210
1211    if [ "$targetPid" = "" ]; then
1212        echo "Usage: runhat [ -d | -e | -s serial ] target-pid"
1213        return
1214    fi
1215
1216    # confirm hat is available
1217    if [ -z $(which hat) ]; then
1218        echo "hat is not available in this configuration."
1219        return
1220    fi
1221
1222    # issue "am" command to cause the hprof dump
1223    local devFile=/data/local/tmp/hprof-$targetPid
1224    echo "Poking $targetPid and waiting for data..."
1225    echo "Storing data at $devFile"
1226    adb ${adbOptions} shell am dumpheap $targetPid $devFile
1227    echo "Press enter when logcat shows \"hprof: heap dump completed\""
1228    echo -n "> "
1229    read
1230
1231    local localFile=/tmp/$$-hprof
1232
1233    echo "Retrieving file $devFile..."
1234    adb ${adbOptions} pull $devFile $localFile
1235
1236    adb ${adbOptions} shell rm $devFile
1237
1238    echo "Running hat on $localFile"
1239    echo "View the output by pointing your browser at http://localhost:7000/"
1240    echo ""
1241    hat -JXmx512m $localFile
1242}
1243
1244function getbugreports()
1245{
1246    local reports=(`adb shell ls /sdcard/bugreports | tr -d '\r'`)
1247
1248    if [ ! "$reports" ]; then
1249        echo "Could not locate any bugreports."
1250        return
1251    fi
1252
1253    local report
1254    for report in ${reports[@]}
1255    do
1256        echo "/sdcard/bugreports/${report}"
1257        adb pull /sdcard/bugreports/${report} ${report}
1258        gunzip ${report}
1259    done
1260}
1261
1262function getsdcardpath()
1263{
1264    adb ${adbOptions} shell echo -n \$\{EXTERNAL_STORAGE\}
1265}
1266
1267function getscreenshotpath()
1268{
1269    echo "$(getsdcardpath)/Pictures/Screenshots"
1270}
1271
1272function getlastscreenshot()
1273{
1274    local screenshot_path=$(getscreenshotpath)
1275    local screenshot=`adb ${adbOptions} ls ${screenshot_path} | grep Screenshot_[0-9-]*.*\.png | sort -rk 3 | cut -d " " -f 4 | head -n 1`
1276    if [ "$screenshot" = "" ]; then
1277        echo "No screenshots found."
1278        return
1279    fi
1280    echo "${screenshot}"
1281    adb ${adbOptions} pull ${screenshot_path}/${screenshot}
1282}
1283
1284function startviewserver()
1285{
1286    local port=4939
1287    if [ $# -gt 0 ]; then
1288            port=$1
1289    fi
1290    adb shell service call window 1 i32 $port
1291}
1292
1293function stopviewserver()
1294{
1295    adb shell service call window 2
1296}
1297
1298function isviewserverstarted()
1299{
1300    adb shell service call window 3
1301}
1302
1303function key_home()
1304{
1305    adb shell input keyevent 3
1306}
1307
1308function key_back()
1309{
1310    adb shell input keyevent 4
1311}
1312
1313function key_menu()
1314{
1315    adb shell input keyevent 82
1316}
1317
1318function smoketest()
1319{
1320    if [ ! "$ANDROID_PRODUCT_OUT" ]; then
1321        echo "Couldn't locate output files.  Try running 'lunch' first." >&2
1322        return
1323    fi
1324    T=$(gettop)
1325    if [ ! "$T" ]; then
1326        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
1327        return
1328    fi
1329
1330    (\cd "$T" && mmm tests/SmokeTest) &&
1331      adb uninstall com.android.smoketest > /dev/null &&
1332      adb uninstall com.android.smoketest.tests > /dev/null &&
1333      adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTestApp.apk &&
1334      adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTest.apk &&
1335      adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner
1336}
1337
1338# simple shortcut to the runtest command
1339function runtest()
1340{
1341    T=$(gettop)
1342    if [ ! "$T" ]; then
1343        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
1344        return
1345    fi
1346    ("$T"/development/testrunner/runtest.py $@)
1347}
1348
1349function godir () {
1350    if [[ -z "$1" ]]; then
1351        echo "Usage: godir <regex>"
1352        return
1353    fi
1354    T=$(gettop)
1355    if [[ ! -f $T/filelist ]]; then
1356        echo -n "Creating index..."
1357        (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > filelist)
1358        echo " Done"
1359        echo ""
1360    fi
1361    local lines
1362    lines=($(\grep "$1" $T/filelist | sed -e 's/\/[^/]*$//' | sort | uniq))
1363    if [[ ${#lines[@]} = 0 ]]; then
1364        echo "Not found"
1365        return
1366    fi
1367    local pathname
1368    local choice
1369    if [[ ${#lines[@]} > 1 ]]; then
1370        while [[ -z "$pathname" ]]; do
1371            local index=1
1372            local line
1373            for line in ${lines[@]}; do
1374                printf "%6s %s\n" "[$index]" $line
1375                index=$(($index + 1))
1376            done
1377            echo
1378            echo -n "Select one: "
1379            unset choice
1380            read choice
1381            if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then
1382                echo "Invalid choice"
1383                continue
1384            fi
1385            pathname=${lines[$(($choice-1))]}
1386        done
1387    else
1388        pathname=${lines[0]}
1389    fi
1390    \cd $T/$pathname
1391}
1392
1393# Force JAVA_HOME to point to java 1.7 if it isn't already set.
1394#
1395# Note that the MacOS path for java 1.7 includes a minor revision number (sigh).
1396# For some reason, installing the JDK doesn't make it show up in the
1397# JavaVM.framework/Versions/1.7/ folder.
1398function set_java_home() {
1399    # Clear the existing JAVA_HOME value if we set it ourselves, so that
1400    # we can reset it later, depending on the version of java the build
1401    # system needs.
1402    #
1403    # If we don't do this, the JAVA_HOME value set by the first call to
1404    # build/envsetup.sh will persist forever.
1405    if [ -n "$ANDROID_SET_JAVA_HOME" ]; then
1406      export JAVA_HOME=""
1407    fi
1408
1409    if [ ! "$JAVA_HOME" ]; then
1410      case `uname -s` in
1411          Darwin)
1412              export JAVA_HOME=$(/usr/libexec/java_home -v 1.7)
1413              ;;
1414          *)
1415              export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
1416              ;;
1417      esac
1418
1419      # Keep track of the fact that we set JAVA_HOME ourselves, so that
1420      # we can change it on the next envsetup.sh, if required.
1421      export ANDROID_SET_JAVA_HOME=true
1422    fi
1423}
1424
1425# Print colored exit condition
1426function pez {
1427    "$@"
1428    local retval=$?
1429    if [ $retval -ne 0 ]
1430    then
1431        echo $'\E'"[0;31mFAILURE\e[00m"
1432    else
1433        echo $'\E'"[0;32mSUCCESS\e[00m"
1434    fi
1435    return $retval
1436}
1437
1438function get_make_command()
1439{
1440  echo command make
1441}
1442
1443function make()
1444{
1445    local start_time=$(date +"%s")
1446    $(get_make_command) "$@"
1447    local ret=$?
1448    local end_time=$(date +"%s")
1449    local tdiff=$(($end_time-$start_time))
1450    local hours=$(($tdiff / 3600 ))
1451    local mins=$((($tdiff % 3600) / 60))
1452    local secs=$(($tdiff % 60))
1453    local ncolors=$(tput colors 2>/dev/null)
1454    if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
1455        color_failed=$'\E'"[0;31m"
1456        color_success=$'\E'"[0;32m"
1457        color_reset=$'\E'"[00m"
1458    else
1459        color_failed=""
1460        color_success=""
1461        color_reset=""
1462    fi
1463    echo
1464    if [ $ret -eq 0 ] ; then
1465        echo -n "${color_success}#### make completed successfully "
1466    else
1467        echo -n "${color_failed}#### make failed to build some targets "
1468    fi
1469    if [ $hours -gt 0 ] ; then
1470        printf "(%02g:%02g:%02g (hh:mm:ss))" $hours $mins $secs
1471    elif [ $mins -gt 0 ] ; then
1472        printf "(%02g:%02g (mm:ss))" $mins $secs
1473    elif [ $secs -gt 0 ] ; then
1474        printf "(%s seconds)" $secs
1475    fi
1476    echo " ####${color_reset}"
1477    echo
1478    return $ret
1479}
1480
1481if [ "x$SHELL" != "x/bin/bash" ]; then
1482    case `ps -o command -p $$` in
1483        *bash*)
1484            ;;
1485        *)
1486            echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results"
1487            ;;
1488    esac
1489fi
1490
1491# Execute the contents of any vendorsetup.sh files we can find.
1492for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \
1493         `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort`
1494do
1495    echo "including $f"
1496    . $f
1497done
1498unset f
1499
1500addcompletions
1501