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