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