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