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