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