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