envsetup.sh revision d0b274d962ad65dd051bc00f1ae532dcb71679cb
1function help() {
2cat <<EOF
3Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
4- croot:   Changes directory to the top of the tree.
5- m:       Makes from the top of the tree.
6- mm:      Builds all of the modules in the current directory.
7- mmm:     Builds all of the modules in the supplied directories.
8- cgrep:   Greps on all local C/C++ files.
9- jgrep:   Greps on all local Java files.
10- resgrep: Greps on all local res/*.xml files.
11- godir:   Go to the directory containing a file.
12
13Look at the source to view more functions. The complete list is:
14EOF
15    T=$(gettop)
16    local A
17    A=""
18    for i in `cat $T/build/envsetup.sh | sed -n "/^function /s/function \([a-z_]*\).*/\1/p" | sort`; do
19      A="$A $i"
20    done
21    echo $A
22}
23
24# Get the value of a build variable as an absolute path.
25function get_abs_build_var()
26{
27    T=$(gettop)
28    if [ ! "$T" ]; then
29        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
30        return
31    fi
32    CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
33      make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-abs-$1
34}
35
36# Get the exact value of a build variable.
37function get_build_var()
38{
39    T=$(gettop)
40    if [ ! "$T" ]; then
41        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
42        return
43    fi
44    CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
45      make --no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1
46}
47
48# check to see if the supplied product is one we can build
49function check_product()
50{
51    T=$(gettop)
52    if [ ! "$T" ]; then
53        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
54        return
55    fi
56    CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
57        TARGET_PRODUCT=$1 TARGET_BUILD_VARIANT= \
58        TARGET_SIMULATOR= TARGET_BUILD_TYPE= \
59        get_build_var TARGET_DEVICE > /dev/null
60    # hide successful answers, but allow the errors to show
61}
62
63VARIANT_CHOICES=(user userdebug eng)
64
65# check to see if the supplied variant is valid
66function check_variant()
67{
68    for v in ${VARIANT_CHOICES[@]}
69    do
70        if [ "$v" = "$1" ]
71        then
72            return 0
73        fi
74    done
75    return 1
76}
77
78function setpaths()
79{
80    T=$(gettop)
81    if [ ! "$T" ]; then
82        echo "Couldn't locate the top of the tree.  Try setting TOP."
83        return
84    fi
85
86    ##################################################################
87    #                                                                #
88    #              Read me before you modify this code               #
89    #                                                                #
90    #   This function sets ANDROID_BUILD_PATHS to what it is adding  #
91    #   to PATH, and the next time it is run, it removes that from   #
92    #   PATH.  This is required so lunch can be run more than once   #
93    #   and still have working paths.                                #
94    #                                                                #
95    ##################################################################
96
97    # out with the old
98    if [ -n $ANDROID_BUILD_PATHS ] ; then
99        export PATH=${PATH/$ANDROID_BUILD_PATHS/}
100    fi
101
102    # and in with the new
103    CODE_REVIEWS=
104    prebuiltdir=$(getprebuilt)
105    export ANDROID_EABI_TOOLCHAIN=$prebuiltdir/toolchain/arm-eabi-4.4.0/bin
106    export ANDROID_TOOLCHAIN=$ANDROID_EABI_TOOLCHAIN
107    export ANDROID_QTOOLS=$T/development/emulator/qtools
108    export ANDROID_BUILD_PATHS=:$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_QTOOLS:$ANDROID_TOOLCHAIN:$ANDROID_EABI_TOOLCHAIN$CODE_REVIEWS
109    export PATH=$PATH$ANDROID_BUILD_PATHS
110
111    unset ANDROID_PRODUCT_OUT
112    export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT)
113    export OUT=$ANDROID_PRODUCT_OUT
114
115    # needed for building linux on MacOS
116    # TODO: fix the path
117    #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
118
119    # needed for OProfile to post-process collected samples
120    export OPROFILE_EVENTS_DIR=$prebuiltdir/oprofile
121}
122
123function printconfig()
124{
125    T=$(gettop)
126    if [ ! "$T" ]; then
127        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
128        return
129    fi
130    get_build_var report_config
131}
132
133function set_stuff_for_environment()
134{
135    settitle
136    setpaths
137    set_sequence_number
138
139    # Don't try to do preoptimization until it works better on OSX.
140    export DISABLE_DEXPREOPT=true
141
142    export ANDROID_BUILD_TOP=$(gettop)
143}
144
145function set_sequence_number()
146{
147    export BUILD_ENV_SEQUENCE_NUMBER=9
148}
149
150function settitle()
151{
152    if [ "$STAY_OFF_MY_LAWN" = "" ]; then
153        local product=$(get_build_var TARGET_PRODUCT)
154        local variant=$(get_build_var TARGET_BUILD_VARIANT)
155        export PROMPT_COMMAND="echo -ne \"\033]0;[${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\""
156    fi
157}
158
159case `uname -s` in
160    Linux)
161        function choosesim()
162        {
163            echo "Build for the simulator or the device?"
164            echo "     1. Device"
165            echo "     2. Simulator"
166            echo
167
168            export TARGET_SIMULATOR=
169            local ANSWER
170            while [ -z $TARGET_SIMULATOR ]
171            do
172                echo -n "Which would you like? [1] "
173                if [ -z "$1" ] ; then
174                    read ANSWER
175                else
176                    echo $1
177                    ANSWER=$1
178                fi
179                case $ANSWER in
180                "")
181                    export TARGET_SIMULATOR=false
182                    ;;
183                1)
184                    export TARGET_SIMULATOR=false
185                    ;;
186                Device)
187                    export TARGET_SIMULATOR=false
188                    ;;
189                2)
190                    export TARGET_SIMULATOR=true
191                    ;;
192                Simulator)
193                    export TARGET_SIMULATOR=true
194                    ;;
195                *)
196                    echo
197                    echo "I didn't understand your response.  Please try again."
198                    echo
199                    ;;
200                esac
201                if [ -n "$1" ] ; then
202                    break
203                fi
204            done
205
206            set_stuff_for_environment
207        }
208        ;;
209    *)
210        function choosesim()
211        {
212            echo "Only device builds are supported for" `uname -s`
213            echo "     Forcing TARGET_SIMULATOR=false"
214            echo
215            if [ -z "$1" ]
216            then
217                echo -n "Press enter: "
218                read
219            fi
220
221            export TARGET_SIMULATOR=false
222            set_stuff_for_environment
223        }
224        ;;
225esac
226
227function choosetype()
228{
229    echo "Build type choices are:"
230    echo "     1. release"
231    echo "     2. debug"
232    echo
233
234    local DEFAULT_NUM DEFAULT_VALUE
235    if [ $TARGET_SIMULATOR = "false" ] ; then
236        DEFAULT_NUM=1
237        DEFAULT_VALUE=release
238    else
239        DEFAULT_NUM=2
240        DEFAULT_VALUE=debug
241    fi
242
243    export TARGET_BUILD_TYPE=
244    local ANSWER
245    while [ -z $TARGET_BUILD_TYPE ]
246    do
247        echo -n "Which would you like? ["$DEFAULT_NUM"] "
248        if [ -z "$1" ] ; then
249            read ANSWER
250        else
251            echo $1
252            ANSWER=$1
253        fi
254        case $ANSWER in
255        "")
256            export TARGET_BUILD_TYPE=$DEFAULT_VALUE
257            ;;
258        1)
259            export TARGET_BUILD_TYPE=release
260            ;;
261        release)
262            export TARGET_BUILD_TYPE=release
263            ;;
264        2)
265            export TARGET_BUILD_TYPE=debug
266            ;;
267        debug)
268            export TARGET_BUILD_TYPE=debug
269            ;;
270        *)
271            echo
272            echo "I didn't understand your response.  Please try again."
273            echo
274            ;;
275        esac
276        if [ -n "$1" ] ; then
277            break
278        fi
279    done
280
281    set_stuff_for_environment
282}
283
284#
285# This function isn't really right:  It chooses a TARGET_PRODUCT
286# based on the list of boards.  Usually, that gets you something
287# that kinda works with a generic product, but really, you should
288# pick a product by name.
289#
290function chooseproduct()
291{
292    if [ "x$TARGET_PRODUCT" != x ] ; then
293        default_value=$TARGET_PRODUCT
294    else
295        if [ "$TARGET_SIMULATOR" = true ] ; then
296            default_value=sim
297        else
298            default_value=generic
299        fi
300    fi
301
302    export TARGET_PRODUCT=
303    local ANSWER
304    while [ -z "$TARGET_PRODUCT" ]
305    do
306        echo -n "Which product would you like? [$default_value] "
307        if [ -z "$1" ] ; then
308            read ANSWER
309        else
310            echo $1
311            ANSWER=$1
312        fi
313
314        if [ -z "$ANSWER" ] ; then
315            export TARGET_PRODUCT=$default_value
316        else
317            if check_product $ANSWER
318            then
319                export TARGET_PRODUCT=$ANSWER
320            else
321                echo "** Not a valid product: $ANSWER"
322            fi
323        fi
324        if [ -n "$1" ] ; then
325            break
326        fi
327    done
328
329    set_stuff_for_environment
330}
331
332function choosevariant()
333{
334    echo "Variant choices are:"
335    local index=1
336    local v
337    for v in ${VARIANT_CHOICES[@]}
338    do
339        # The product name is the name of the directory containing
340        # the makefile we found, above.
341        echo "     $index. $v"
342        index=$(($index+1))
343    done
344
345    local default_value=eng
346    local ANSWER
347
348    export TARGET_BUILD_VARIANT=
349    while [ -z "$TARGET_BUILD_VARIANT" ]
350    do
351        echo -n "Which would you like? [$default_value] "
352        if [ -z "$1" ] ; then
353            read ANSWER
354        else
355            echo $1
356            ANSWER=$1
357        fi
358
359        if [ -z "$ANSWER" ] ; then
360            export TARGET_BUILD_VARIANT=$default_value
361        elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then
362            if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then
363                export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[$(($ANSWER-$_arrayoffset))]}
364            fi
365        else
366            if check_variant $ANSWER
367            then
368                export TARGET_BUILD_VARIANT=$ANSWER
369            else
370                echo "** Not a valid variant: $ANSWER"
371            fi
372        fi
373        if [ -n "$1" ] ; then
374            break
375        fi
376    done
377}
378
379function tapas()
380{
381    choosecombo
382}
383
384function choosecombo()
385{
386    choosesim $1
387
388    echo
389    echo
390    choosetype $2
391
392    echo
393    echo
394    chooseproduct $3
395
396    echo
397    echo
398    choosevariant $4
399
400    echo
401    set_stuff_for_environment
402    printconfig
403}
404
405# Clear this variable.  It will be built up again when the vendorsetup.sh
406# files are included at the end of this file.
407unset LUNCH_MENU_CHOICES
408function add_lunch_combo()
409{
410    local new_combo=$1
411    local c
412    for c in ${LUNCH_MENU_CHOICES[@]} ; do
413        if [ "$new_combo" = "$c" ] ; then
414            return
415        fi
416    done
417    LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo)
418}
419
420# add the default one here
421add_lunch_combo generic-eng
422
423# if we're on linux, add the simulator.  There is a special case
424# in lunch to deal with the simulator
425if [ "$(uname)" = "Linux" ] ; then
426    add_lunch_combo simulator
427fi
428
429function print_lunch_menu()
430{
431    local uname=$(uname)
432    echo
433    echo "You're building on" $uname
434    echo
435    echo ${LUNCH_MENU_CHOICES[@]}
436    echo "Lunch menu... pick a combo:"
437
438    local i=1
439    local choice
440    for choice in ${LUNCH_MENU_CHOICES[@]}
441    do
442        echo "     $i. $choice"
443        i=$(($i+1))
444    done
445
446    echo
447}
448
449function lunch()
450{
451    local answer
452
453    if [ "$1" ] ; then
454        answer=$1
455    else
456        print_lunch_menu
457        echo -n "Which would you like? [generic-eng] "
458        read answer
459    fi
460
461    local selection=
462
463    if [ -z "$answer" ]
464    then
465        selection=generic-eng
466    elif [ "$answer" = "simulator" ]
467    then
468        selection=simulator
469    elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
470    then
471        if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
472        then
473            selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}
474        fi
475    elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
476    then
477        selection=$answer
478    fi
479
480    if [ -z "$selection" ]
481    then
482        echo
483        echo "Invalid lunch combo: $answer"
484        return 1
485    fi
486
487    # special case the simulator
488    if [ "$selection" = "simulator" ]
489    then
490        export TARGET_PRODUCT=sim
491        export TARGET_BUILD_VARIANT=eng
492        export TARGET_SIMULATOR=true
493        export TARGET_BUILD_TYPE=debug
494    else
495        local product=$(echo -n $selection | sed -e "s/-.*$//")
496        check_product $product
497        if [ $? -ne 0 ]
498        then
499            echo
500            echo "** Don't have a product spec for: '$product'"
501            echo "** Do you have the right repo manifest?"
502            product=
503        fi
504
505        local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
506        check_variant $variant
507        if [ $? -ne 0 ]
508        then
509            echo
510            echo "** Invalid variant: '$variant'"
511            echo "** Must be one of ${VARIANT_CHOICES[@]}"
512            variant=
513        fi
514
515        if [ -z "$product" -o -z "$variant" ]
516        then
517            echo
518            return 1
519        fi
520
521        export TARGET_PRODUCT=$product
522        export TARGET_BUILD_VARIANT=$variant
523        export TARGET_SIMULATOR=false
524        export TARGET_BUILD_TYPE=release
525    fi # !simulator
526
527    echo
528
529    set_stuff_for_environment
530    printconfig
531}
532
533function gettop
534{
535    local TOPFILE=build/core/envsetup.mk
536    if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
537        echo $TOP
538    else
539        if [ -f $TOPFILE ] ; then
540            # The following circumlocution (repeated below as well) ensures
541            # that we record the true directory name and not one that is
542            # faked up with symlink names.
543            PWD= /bin/pwd
544        else
545            # We redirect cd to /dev/null in case it's aliased to
546            # a command that prints something as a side-effect
547            # (like pushd)
548            local HERE=$PWD
549            T=
550            while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
551                cd .. > /dev/null
552                T=`PWD= /bin/pwd`
553            done
554            cd $HERE > /dev/null
555            if [ -f "$T/$TOPFILE" ]; then
556                echo $T
557            fi
558        fi
559    fi
560}
561
562function m()
563{
564    T=$(gettop)
565    if [ "$T" ]; then
566        make -C $T $@
567    else
568        echo "Couldn't locate the top of the tree.  Try setting TOP."
569    fi
570}
571
572function findmakefile()
573{
574    TOPFILE=build/core/envsetup.mk
575    # We redirect cd to /dev/null in case it's aliased to
576    # a command that prints something as a side-effect
577    # (like pushd)
578    local HERE=$PWD
579    T=
580    while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
581        T=$PWD
582        if [ -f "$T/Android.mk" ]; then
583            echo $T/Android.mk
584            cd $HERE > /dev/null
585            return
586        fi
587        cd .. > /dev/null
588    done
589    cd $HERE > /dev/null
590}
591
592function mm()
593{
594    # If we're sitting in the root of the build tree, just do a
595    # normal make.
596    if [ -f build/core/envsetup.mk -a -f Makefile ]; then
597        make $@
598    else
599        # Find the closest Android.mk file.
600        T=$(gettop)
601        local M=$(findmakefile)
602        # Remove the path to top as the makefilepath needs to be relative
603        local M=`echo $M|sed 's:'$T'/::'`
604        if [ ! "$T" ]; then
605            echo "Couldn't locate the top of the tree.  Try setting TOP."
606        elif [ ! "$M" ]; then
607            echo "Couldn't locate a makefile from the current directory."
608        else
609            ONE_SHOT_MAKEFILE=$M make -C $T files $@
610        fi
611    fi
612}
613
614function mmm()
615{
616    T=$(gettop)
617    if [ "$T" ]; then
618        local MAKEFILE=
619        local ARGS=
620        local DIR TO_CHOP
621        local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
622        local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
623        for DIR in $DIRS ; do
624            DIR=`echo $DIR | sed -e 's:/$::'`
625            if [ -f $DIR/Android.mk ]; then
626                TO_CHOP=`echo $T | wc -c | tr -d ' '`
627                TO_CHOP=`expr $TO_CHOP + 1`
628                MFILE=`echo $PWD | cut -c${TO_CHOP}-`
629                if [ "$MFILE" = "" ] ; then
630                    MFILE=$DIR/Android.mk
631                else
632                    MFILE=$MFILE/$DIR/Android.mk
633                fi
634                MAKEFILE="$MAKEFILE $MFILE"
635            else
636                if [ "$DIR" = snod ]; then
637                    ARGS="$ARGS snod"
638                elif [ "$DIR" = showcommands ]; then
639                    ARGS="$ARGS showcommands"
640                else
641                    echo "No Android.mk in $DIR."
642                    return 1
643                fi
644            fi
645        done
646        ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T $DASH_ARGS files $ARGS
647    else
648        echo "Couldn't locate the top of the tree.  Try setting TOP."
649    fi
650}
651
652function croot()
653{
654    T=$(gettop)
655    if [ "$T" ]; then
656        cd $(gettop)
657    else
658        echo "Couldn't locate the top of the tree.  Try setting TOP."
659    fi
660}
661
662function cproj()
663{
664    TOPFILE=build/core/envsetup.mk
665    # We redirect cd to /dev/null in case it's aliased to
666    # a command that prints something as a side-effect
667    # (like pushd)
668    local HERE=$PWD
669    T=
670    while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
671        T=$PWD
672        if [ -f "$T/Android.mk" ]; then
673            cd $T
674            return
675        fi
676        cd .. > /dev/null
677    done
678    cd $HERE > /dev/null
679    echo "can't find Android.mk"
680}
681
682function pid()
683{
684   local EXE="$1"
685   if [ "$EXE" ] ; then
686       local PID=`adb shell ps | fgrep $1 | sed -e 's/[^ ]* *\([0-9]*\).*/\1/'`
687       echo "$PID"
688   else
689       echo "usage: pid name"
690   fi
691}
692
693# systemstack - dump the current stack trace of all threads in the system process
694# to the usual ANR traces file
695function systemstack()
696{
697    adb shell echo '""' '>>' /data/anr/traces.txt && adb shell chmod 776 /data/anr/traces.txt && adb shell kill -3 $(pid system_server)
698}
699
700function gdbclient()
701{
702   local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT)
703   local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED)
704   local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)
705   local OUT_EXE_SYMBOLS=$(get_abs_build_var TARGET_OUT_EXECUTABLES_UNSTRIPPED)
706   local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS)
707   if [ "$OUT_ROOT" -a "$PREBUILTS" ]; then
708       local EXE="$1"
709       if [ "$EXE" ] ; then
710           EXE=$1
711       else
712           EXE="app_process"
713       fi
714
715       local PORT="$2"
716       if [ "$PORT" ] ; then
717           PORT=$2
718       else
719           PORT=":5039"
720       fi
721
722       local PID
723       local PROG="$3"
724       if [ "$PROG" ] ; then
725           PID=`pid $3`
726           adb forward "tcp$PORT" "tcp$PORT"
727           adb shell gdbserver $PORT --attach $PID &
728           sleep 2
729       else
730               echo ""
731               echo "If you haven't done so already, do this first on the device:"
732               echo "    gdbserver $PORT /system/bin/$EXE"
733                   echo " or"
734               echo "    gdbserver $PORT --attach $PID"
735               echo ""
736       fi
737
738       echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS"
739       echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS"
740       echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT"
741       echo >>"$OUT_ROOT/gdbclient.cmds" ""
742
743       arm-eabi-gdb -x "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE"
744  else
745       echo "Unable to determine build system output dir."
746   fi
747
748}
749
750case `uname -s` in
751    Darwin)
752        function sgrep()
753        {
754            find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml|sh|mk)' -print0 | xargs -0 grep --color -n "$@"
755        }
756
757        ;;
758    *)
759        function sgrep()
760        {
761            find . -type f -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\|sh\|mk\)' -print0 | xargs -0 grep --color -n "$@"
762        }
763        ;;
764esac
765
766function jgrep()
767{
768    find . -type f -name "*\.java" -print0 | xargs -0 grep --color -n "$@"
769}
770
771function cgrep()
772{
773    find . -type f -name "*\.c*" -print0 | xargs -0 grep --color -n "$@"
774}
775
776function resgrep()
777{
778    for dir in `find . -name res -type d`; do find $dir -type f -name '*\.xml' -print0 | xargs -0 grep --color -n "$@"; done;
779}
780
781case `uname -s` in
782    Darwin)
783        function mgrep()
784        {
785            find -E . -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -print0 | xargs -0 grep --color -n "$@"
786        }
787
788        function treegrep()
789        {
790            find -E . -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n -i "$@"
791        }
792
793        ;;
794    *)
795        function mgrep()
796        {
797            find . -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f -print0 | xargs -0 grep --color -n "$@"
798        }
799
800        function treegrep()
801        {
802            find . -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "$@"
803        }
804
805        ;;
806esac
807
808function getprebuilt
809{
810    get_abs_build_var ANDROID_PREBUILTS
811}
812
813function tracedmdump()
814{
815    T=$(gettop)
816    if [ ! "$T" ]; then
817        echo "Couldn't locate the top of the tree.  Try setting TOP."
818        return
819    fi
820    local prebuiltdir=$(getprebuilt)
821    local KERNEL=$T/prebuilt/android-arm/kernel/vmlinux-qemu
822
823    local TRACE=$1
824    if [ ! "$TRACE" ] ; then
825        echo "usage:  tracedmdump  tracename"
826        return
827    fi
828
829    if [ ! -r "$KERNEL" ] ; then
830        echo "Error: cannot find kernel: '$KERNEL'"
831        return
832    fi
833
834    local BASETRACE=$(basename $TRACE)
835    if [ "$BASETRACE" = "$TRACE" ] ; then
836        TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE
837    fi
838
839    echo "post-processing traces..."
840    rm -f $TRACE/qtrace.dexlist
841    post_trace $TRACE
842    if [ $? -ne 0 ]; then
843        echo "***"
844        echo "*** Error: malformed trace.  Did you remember to exit the emulator?"
845        echo "***"
846        return
847    fi
848    echo "generating dexlist output..."
849    /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
850    echo "generating dmtrace data..."
851    q2dm -r $ANDROID_PRODUCT_OUT/symbols $TRACE $KERNEL $TRACE/dmtrace || return
852    echo "generating html file..."
853    dmtracedump -h $TRACE/dmtrace >| $TRACE/dmtrace.html || return
854    echo "done, see $TRACE/dmtrace.html for details"
855    echo "or run:"
856    echo "    traceview $TRACE/dmtrace"
857}
858
859# communicate with a running device or emulator, set up necessary state,
860# and run the hat command.
861function runhat()
862{
863    # process standard adb options
864    local adbTarget=""
865    if [ $1 = "-d" -o $1 = "-e" ]; then
866        adbTarget=$1
867        shift 1
868    elif [ $1 = "-s" ]; then
869        adbTarget="$1 $2"
870        shift 2
871    fi
872    local adbOptions=${adbTarget}
873    echo adbOptions = ${adbOptions}
874
875    # runhat options
876    local targetPid=$1
877    local outputFile=$2
878
879    if [ "$targetPid" = "" ]; then
880        echo "Usage: runhat [ -d | -e | -s serial ] target-pid [output-file]"
881        return
882    fi
883
884    # confirm hat is available
885    if [ -z $(which hat) ]; then
886        echo "hat is not available in this configuration."
887        return
888    fi
889
890    adb ${adbOptions} shell >/dev/null mkdir /data/misc
891    adb ${adbOptions} shell chmod 777 /data/misc
892
893    # send a SIGUSR1 to cause the hprof dump
894    echo "Poking $targetPid and waiting for data..."
895    adb ${adbOptions} shell kill -10 $targetPid
896    echo "Press enter when logcat shows \"hprof: heap dump completed\""
897    echo -n "> "
898    read
899
900    local availFiles=( $(adb ${adbOptions} shell ls /data/misc | grep '^heap-dump' | sed -e 's/.*heap-dump-/heap-dump-/' | sort -r | tr '[:space:][:cntrl:]' ' ') )
901    local devFile=/data/misc/${availFiles[0]}
902    local localFile=/tmp/$$-hprof
903
904    echo "Retrieving file $devFile..."
905    adb ${adbOptions} pull $devFile $localFile
906
907    adb ${adbOptions} shell rm $devFile
908
909    echo "Running hat on $localFile"
910    echo "View the output by pointing your browser at http://localhost:7000/"
911    echo ""
912    hat $localFile
913}
914
915function getbugreports()
916{
917    local reports=(`adb shell ls /sdcard/bugreports | tr -d '\r'`)
918
919    if [ ! "$reports" ]; then
920        echo "Could not locate any bugreports."
921        return
922    fi
923
924    local report
925    for report in ${reports[@]}
926    do
927        echo "/sdcard/bugreports/${report}"
928        adb pull /sdcard/bugreports/${report} ${report}
929        gunzip ${report}
930    done
931}
932
933function startviewserver()
934{
935    local port=4939
936    if [ $# -gt 0 ]; then
937            port=$1
938    fi
939    adb shell service call window 1 i32 $port
940}
941
942function stopviewserver()
943{
944    adb shell service call window 2
945}
946
947function isviewserverstarted()
948{
949    adb shell service call window 3
950}
951
952function smoketest()
953{
954    if [ ! "$ANDROID_PRODUCT_OUT" ]; then
955        echo "Couldn't locate output files.  Try running 'lunch' first." >&2
956        return
957    fi
958    T=$(gettop)
959    if [ ! "$T" ]; then
960        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
961        return
962    fi
963
964    (cd "$T" && mmm tests/SmokeTest) &&
965      adb uninstall com.android.smoketest > /dev/null &&
966      adb uninstall com.android.smoketest.tests > /dev/null &&
967      adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTestApp.apk &&
968      adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTest.apk &&
969      adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner
970}
971
972# simple shortcut to the runtest command
973function runtest()
974{
975    T=$(gettop)
976    if [ ! "$T" ]; then
977        echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
978        return
979    fi
980    ("$T"/development/testrunner/runtest.py $@)
981}
982
983function godir () {
984    if [[ -z "$1" ]]; then
985        echo "Usage: godir <regex>"
986        return
987    fi
988    if [[ ! -f $T/filelist ]]; then
989        echo -n "Creating index..."
990        (cd $T; find . -wholename ./out -prune -o -type f > filelist)
991        echo " Done"
992        echo ""
993    fi
994    local lines
995    lines=($(grep "$1" $T/filelist | sed -e 's/\/[^/]*$//' | sort | uniq)) 
996    if [[ ${#lines[@]} = 0 ]]; then
997        echo "Not found"
998        return
999    fi
1000    local pathname
1001    local choice
1002    if [[ ${#lines[@]} > 1 ]]; then
1003        while [[ -z "$pathname" ]]; do
1004            local index=1
1005            local line
1006            for line in ${lines[@]}; do
1007                printf "%6s %s\n" "[$index]" $line
1008                index=$(($index + 1)) 
1009            done
1010            echo
1011            echo -n "Select one: "
1012            unset choice
1013            read choice
1014            if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then
1015                echo "Invalid choice"
1016                continue
1017            fi
1018            pathname=${lines[$(($choice-$_arrayoffset))]}
1019        done
1020    else
1021        # even though zsh arrays are 1-based, $foo[0] is an alias for $foo[1]
1022        pathname=${lines[0]}
1023    fi
1024    cd $T/$pathname
1025}
1026
1027# determine whether arrays are zero-based (bash) or one-based (zsh)
1028_xarray=(a b c)
1029if [ -z "${_xarray[${#_xarray[@]}]}" ]
1030then
1031    _arrayoffset=1
1032else
1033    _arrayoffset=0
1034fi
1035unset _xarray
1036
1037# Execute the contents of any vendorsetup.sh files we can find.
1038for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh 2> /dev/null`
1039do
1040    echo "including $f"
1041    . $f
1042done
1043unset f
1044