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