envsetup.sh revision 9b68fb2837a2f77c73730453f9de292e6029717c
1function hmm() { 2cat <<EOF 3Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment: 4- lunch: lunch <product_name>-<build_variant> 5- tapas: tapas [<App1> <App2> ...] [arm|x86|mips|armv5] [eng|userdebug|user] 6- croot: Changes directory to the top of the tree. 7- m: Makes from the top of the tree. 8- mm: Builds all of the modules in the current directory, but not their dependencies. 9- mmm: Builds all of the modules in the supplied directories, but not their dependencies. 10- mma: Builds all of the modules in the current directory, and their dependencies. 11- mmma: Builds all of the modules in the supplied directories, and their dependencies. 12- cgrep: Greps on all local C/C++ files. 13- jgrep: Greps on all local Java files. 14- resgrep: Greps on all local res/*.xml files. 15- godir: Go to the directory containing a file. 16 17Look at the source to view more functions. The complete list is: 18EOF 19 T=$(gettop) 20 local A 21 A="" 22 for i in `cat $T/build/envsetup.sh | sed -n "/^function /s/function \([a-z_]*\).*/\1/p" | sort`; do 23 A="$A $i" 24 done 25 echo $A 26} 27 28# Get the value of a build variable as an absolute path. 29function get_abs_build_var() 30{ 31 T=$(gettop) 32 if [ ! "$T" ]; then 33 echo "Couldn't locate the top of the tree. Try setting TOP." >&2 34 return 35 fi 36 (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \ 37 make --no-print-directory -f build/core/config.mk dumpvar-abs-$1) 38} 39 40# Get the exact value of a build variable. 41function get_build_var() 42{ 43 T=$(gettop) 44 if [ ! "$T" ]; then 45 echo "Couldn't locate the top of the tree. Try setting TOP." >&2 46 return 47 fi 48 (\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \ 49 make --no-print-directory -f build/core/config.mk dumpvar-$1) 50} 51 52# check to see if the supplied product is one we can build 53function check_product() 54{ 55 T=$(gettop) 56 if [ ! "$T" ]; then 57 echo "Couldn't locate the top of the tree. Try setting TOP." >&2 58 return 59 fi 60 CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \ 61 TARGET_PRODUCT=$1 \ 62 TARGET_BUILD_VARIANT= \ 63 TARGET_BUILD_TYPE= \ 64 TARGET_BUILD_APPS= \ 65 get_build_var TARGET_DEVICE > /dev/null 66 # hide successful answers, but allow the errors to show 67} 68 69VARIANT_CHOICES=(user userdebug eng) 70 71# check to see if the supplied variant is valid 72function check_variant() 73{ 74 for v in ${VARIANT_CHOICES[@]} 75 do 76 if [ "$v" = "$1" ] 77 then 78 return 0 79 fi 80 done 81 return 1 82} 83 84function setpaths() 85{ 86 T=$(gettop) 87 if [ ! "$T" ]; then 88 echo "Couldn't locate the top of the tree. Try setting TOP." 89 return 90 fi 91 92 ################################################################## 93 # # 94 # Read me before you modify this code # 95 # # 96 # This function sets ANDROID_BUILD_PATHS to what it is adding # 97 # to PATH, and the next time it is run, it removes that from # 98 # PATH. This is required so lunch can be run more than once # 99 # and still have working paths. # 100 # # 101 ################################################################## 102 103 # Note: on windows/cygwin, ANDROID_BUILD_PATHS will contain spaces 104 # due to "C:\Program Files" being in the path. 105 106 # out with the old 107 if [ -n "$ANDROID_BUILD_PATHS" ] ; then 108 export PATH=${PATH/$ANDROID_BUILD_PATHS/} 109 fi 110 if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then 111 export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/} 112 # strip leading ':', if any 113 export PATH=${PATH/:%/} 114 fi 115 116 # and in with the new 117 CODE_REVIEWS= 118 prebuiltdir=$(getprebuilt) 119 gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS) 120 121 # defined in core/config.mk 122 targetgccversion=$(get_build_var TARGET_GCC_VERSION) 123 export TARGET_GCC_VERSION=$targetgccversion 124 125 # The gcc toolchain does not exists for windows/cygwin. In this case, do not reference it. 126 export ANDROID_EABI_TOOLCHAIN= 127 local ARCH=$(get_build_var TARGET_ARCH) 128 case $ARCH in 129 x86) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin 130 ;; 131 x86_64) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin 132 ;; 133 arm) toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin 134 ;; 135 arm64) toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin 136 ;; 137 mips) toolchaindir=mips/mipsel-linux-android-$targetgccversion/bin 138 ;; 139 mips64) toolchaindir=mips/mipsel-linux-android-$targetgccversion/bin 140 ;; 141 *) 142 echo "Can't find toolchain for unknown architecture: $ARCH" 143 toolchaindir=xxxxxxxxx 144 ;; 145 esac 146 if [ -d "$gccprebuiltdir/$toolchaindir" ]; then 147 export ANDROID_EABI_TOOLCHAIN=$gccprebuiltdir/$toolchaindir 148 fi 149 150 unset ARM_EABI_TOOLCHAIN ARM_EABI_TOOLCHAIN_PATH 151 case $ARCH in 152 arm) 153 toolchaindir=arm/arm-eabi-$targetgccversion/bin 154 if [ -d "$gccprebuiltdir/$toolchaindir" ]; then 155 export ARM_EABI_TOOLCHAIN="$gccprebuiltdir/$toolchaindir" 156 ARM_EABI_TOOLCHAIN_PATH=":$gccprebuiltdir/$toolchaindir" 157 fi 158 ;; 159 mips) toolchaindir=mips/mips-eabi-4.4.3/bin 160 ;; 161 *) 162 # No need to set ARM_EABI_TOOLCHAIN for other ARCHs 163 ;; 164 esac 165 166 export ANDROID_TOOLCHAIN=$ANDROID_EABI_TOOLCHAIN 167 export ANDROID_QTOOLS=$T/development/emulator/qtools 168 export ANDROID_DEV_SCRIPTS=$T/development/scripts:$T/prebuilts/devtools/tools 169 export ANDROID_BUILD_PATHS=$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_QTOOLS:$ANDROID_TOOLCHAIN$ARM_EABI_TOOLCHAIN_PATH$CODE_REVIEWS:$ANDROID_DEV_SCRIPTS: 170 export PATH=$ANDROID_BUILD_PATHS$PATH 171 172 unset ANDROID_JAVA_TOOLCHAIN 173 unset ANDROID_PRE_BUILD_PATHS 174 if [ -n "$JAVA_HOME" ]; then 175 export ANDROID_JAVA_TOOLCHAIN=$JAVA_HOME/bin 176 export ANDROID_PRE_BUILD_PATHS=$ANDROID_JAVA_TOOLCHAIN: 177 export PATH=$ANDROID_PRE_BUILD_PATHS$PATH 178 fi 179 180 unset ANDROID_PRODUCT_OUT 181 export ANDROID_PRODUCT_OUT=$(get_abs_build_var PRODUCT_OUT) 182 export OUT=$ANDROID_PRODUCT_OUT 183 184 unset ANDROID_HOST_OUT 185 export ANDROID_HOST_OUT=$(get_abs_build_var HOST_OUT) 186 187 # needed for processing samples collected by perf counters 188 unset OPROFILE_EVENTS_DIR 189 export OPROFILE_EVENTS_DIR=$T/external/oprofile/events 190 191 # needed for building linux on MacOS 192 # TODO: fix the path 193 #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include 194} 195 196function printconfig() 197{ 198 T=$(gettop) 199 if [ ! "$T" ]; then 200 echo "Couldn't locate the top of the tree. Try setting TOP." >&2 201 return 202 fi 203 get_build_var report_config 204} 205 206function set_stuff_for_environment() 207{ 208 settitle 209 set_java_home 210 setpaths 211 set_sequence_number 212 213 export ANDROID_BUILD_TOP=$(gettop) 214 # With this environment variable new GCC can apply colors to warnings/errors 215 export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' 216} 217 218function set_sequence_number() 219{ 220 export BUILD_ENV_SEQUENCE_NUMBER=10 221} 222 223function settitle() 224{ 225 if [ "$STAY_OFF_MY_LAWN" = "" ]; then 226 local arch=$(gettargetarch) 227 local product=$TARGET_PRODUCT 228 local variant=$TARGET_BUILD_VARIANT 229 local apps=$TARGET_BUILD_APPS 230 if [ -z "$apps" ]; then 231 export PROMPT_COMMAND="echo -ne \"\033]0;[${arch}-${product}-${variant}] ${USER}@${HOSTNAME}: ${PWD}\007\"" 232 else 233 export PROMPT_COMMAND="echo -ne \"\033]0;[$arch $apps $variant] ${USER}@${HOSTNAME}: ${PWD}\007\"" 234 fi 235 fi 236} 237 238function addcompletions() 239{ 240 local T dir f 241 242 # Keep us from trying to run in something that isn't bash. 243 if [ -z "${BASH_VERSION}" ]; then 244 return 245 fi 246 247 # Keep us from trying to run in bash that's too old. 248 if [ ${BASH_VERSINFO[0]} -lt 3 ]; then 249 return 250 fi 251 252 dir="sdk/bash_completion" 253 if [ -d ${dir} ]; then 254 for f in `/bin/ls ${dir}/[a-z]*.bash 2> /dev/null`; do 255 echo "including $f" 256 . $f 257 done 258 fi 259} 260 261function choosetype() 262{ 263 echo "Build type choices are:" 264 echo " 1. release" 265 echo " 2. debug" 266 echo 267 268 local DEFAULT_NUM DEFAULT_VALUE 269 DEFAULT_NUM=1 270 DEFAULT_VALUE=release 271 272 export TARGET_BUILD_TYPE= 273 local ANSWER 274 while [ -z $TARGET_BUILD_TYPE ] 275 do 276 echo -n "Which would you like? ["$DEFAULT_NUM"] " 277 if [ -z "$1" ] ; then 278 read ANSWER 279 else 280 echo $1 281 ANSWER=$1 282 fi 283 case $ANSWER in 284 "") 285 export TARGET_BUILD_TYPE=$DEFAULT_VALUE 286 ;; 287 1) 288 export TARGET_BUILD_TYPE=release 289 ;; 290 release) 291 export TARGET_BUILD_TYPE=release 292 ;; 293 2) 294 export TARGET_BUILD_TYPE=debug 295 ;; 296 debug) 297 export TARGET_BUILD_TYPE=debug 298 ;; 299 *) 300 echo 301 echo "I didn't understand your response. Please try again." 302 echo 303 ;; 304 esac 305 if [ -n "$1" ] ; then 306 break 307 fi 308 done 309 310 set_stuff_for_environment 311} 312 313# 314# This function isn't really right: It chooses a TARGET_PRODUCT 315# based on the list of boards. Usually, that gets you something 316# that kinda works with a generic product, but really, you should 317# pick a product by name. 318# 319function chooseproduct() 320{ 321 if [ "x$TARGET_PRODUCT" != x ] ; then 322 default_value=$TARGET_PRODUCT 323 else 324 default_value=full 325 fi 326 327 export TARGET_PRODUCT= 328 local ANSWER 329 while [ -z "$TARGET_PRODUCT" ] 330 do 331 echo -n "Which product would you like? [$default_value] " 332 if [ -z "$1" ] ; then 333 read ANSWER 334 else 335 echo $1 336 ANSWER=$1 337 fi 338 339 if [ -z "$ANSWER" ] ; then 340 export TARGET_PRODUCT=$default_value 341 else 342 if check_product $ANSWER 343 then 344 export TARGET_PRODUCT=$ANSWER 345 else 346 echo "** Not a valid product: $ANSWER" 347 fi 348 fi 349 if [ -n "$1" ] ; then 350 break 351 fi 352 done 353 354 set_stuff_for_environment 355} 356 357function choosevariant() 358{ 359 echo "Variant choices are:" 360 local index=1 361 local v 362 for v in ${VARIANT_CHOICES[@]} 363 do 364 # The product name is the name of the directory containing 365 # the makefile we found, above. 366 echo " $index. $v" 367 index=$(($index+1)) 368 done 369 370 local default_value=eng 371 local ANSWER 372 373 export TARGET_BUILD_VARIANT= 374 while [ -z "$TARGET_BUILD_VARIANT" ] 375 do 376 echo -n "Which would you like? [$default_value] " 377 if [ -z "$1" ] ; then 378 read ANSWER 379 else 380 echo $1 381 ANSWER=$1 382 fi 383 384 if [ -z "$ANSWER" ] ; then 385 export TARGET_BUILD_VARIANT=$default_value 386 elif (echo -n $ANSWER | grep -q -e "^[0-9][0-9]*$") ; then 387 if [ "$ANSWER" -le "${#VARIANT_CHOICES[@]}" ] ; then 388 export TARGET_BUILD_VARIANT=${VARIANT_CHOICES[$(($ANSWER-1))]} 389 fi 390 else 391 if check_variant $ANSWER 392 then 393 export TARGET_BUILD_VARIANT=$ANSWER 394 else 395 echo "** Not a valid variant: $ANSWER" 396 fi 397 fi 398 if [ -n "$1" ] ; then 399 break 400 fi 401 done 402} 403 404function choosecombo() 405{ 406 choosetype $1 407 408 echo 409 echo 410 chooseproduct $2 411 412 echo 413 echo 414 choosevariant $3 415 416 echo 417 set_stuff_for_environment 418 printconfig 419} 420 421# Clear this variable. It will be built up again when the vendorsetup.sh 422# files are included at the end of this file. 423unset LUNCH_MENU_CHOICES 424function add_lunch_combo() 425{ 426 local new_combo=$1 427 local c 428 for c in ${LUNCH_MENU_CHOICES[@]} ; do 429 if [ "$new_combo" = "$c" ] ; then 430 return 431 fi 432 done 433 LUNCH_MENU_CHOICES=(${LUNCH_MENU_CHOICES[@]} $new_combo) 434} 435 436# add the default one here 437add_lunch_combo aosp_arm-eng 438add_lunch_combo aosp_arm64-eng 439add_lunch_combo aosp_mips-eng 440add_lunch_combo aosp_x86-eng 441add_lunch_combo aosp_x86_64-eng 442add_lunch_combo vbox_x86-eng 443 444function print_lunch_menu() 445{ 446 local uname=$(uname) 447 echo 448 echo "You're building on" $uname 449 echo 450 echo "Lunch menu... pick a combo:" 451 452 local i=1 453 local choice 454 for choice in ${LUNCH_MENU_CHOICES[@]} 455 do 456 echo " $i. $choice" 457 i=$(($i+1)) 458 done 459 460 echo 461} 462 463function lunch() 464{ 465 local answer 466 467 if [ "$1" ] ; then 468 answer=$1 469 else 470 print_lunch_menu 471 echo -n "Which would you like? [aosp_arm-eng] " 472 read answer 473 fi 474 475 local selection= 476 477 if [ -z "$answer" ] 478 then 479 selection=aosp_arm-eng 480 elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") 481 then 482 if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ] 483 then 484 selection=${LUNCH_MENU_CHOICES[$(($answer-1))]} 485 fi 486 elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$") 487 then 488 selection=$answer 489 fi 490 491 if [ -z "$selection" ] 492 then 493 echo 494 echo "Invalid lunch combo: $answer" 495 return 1 496 fi 497 498 export TARGET_BUILD_APPS= 499 500 local product=$(echo -n $selection | sed -e "s/-.*$//") 501 check_product $product 502 if [ $? -ne 0 ] 503 then 504 echo 505 echo "** Don't have a product spec for: '$product'" 506 echo "** Do you have the right repo manifest?" 507 product= 508 fi 509 510 local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//") 511 check_variant $variant 512 if [ $? -ne 0 ] 513 then 514 echo 515 echo "** Invalid variant: '$variant'" 516 echo "** Must be one of ${VARIANT_CHOICES[@]}" 517 variant= 518 fi 519 520 if [ -z "$product" -o -z "$variant" ] 521 then 522 echo 523 return 1 524 fi 525 526 export TARGET_PRODUCT=$product 527 export TARGET_BUILD_VARIANT=$variant 528 export TARGET_BUILD_TYPE=release 529 530 echo 531 532 set_stuff_for_environment 533 printconfig 534} 535 536# Tab completion for lunch. 537function _lunch() 538{ 539 local cur prev opts 540 COMPREPLY=() 541 cur="${COMP_WORDS[COMP_CWORD]}" 542 prev="${COMP_WORDS[COMP_CWORD-1]}" 543 544 COMPREPLY=( $(compgen -W "${LUNCH_MENU_CHOICES[*]}" -- ${cur}) ) 545 return 0 546} 547complete -F _lunch lunch 548 549# Configures the build to build unbundled apps. 550# Run tapas with one ore more app names (from LOCAL_PACKAGE_NAME) 551function tapas() 552{ 553 local arch=$(echo -n $(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|mips|armv5)$')) 554 local variant=$(echo -n $(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$')) 555 local apps=$(echo -n $(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|mips|armv5)$')) 556 557 if [ $(echo $arch | wc -w) -gt 1 ]; then 558 echo "tapas: Error: Multiple build archs supplied: $arch" 559 return 560 fi 561 if [ $(echo $variant | wc -w) -gt 1 ]; then 562 echo "tapas: Error: Multiple build variants supplied: $variant" 563 return 564 fi 565 566 local product=full 567 case $arch in 568 x86) product=full_x86;; 569 mips) product=full_mips;; 570 armv5) product=generic_armv5;; 571 esac 572 if [ -z "$variant" ]; then 573 variant=eng 574 fi 575 if [ -z "$apps" ]; then 576 apps=all 577 fi 578 579 export TARGET_PRODUCT=$product 580 export TARGET_BUILD_VARIANT=$variant 581 export TARGET_BUILD_TYPE=release 582 export TARGET_BUILD_APPS=$apps 583 584 set_stuff_for_environment 585 printconfig 586} 587 588function gettop 589{ 590 local TOPFILE=build/core/envsetup.mk 591 if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then 592 echo $TOP 593 else 594 if [ -f $TOPFILE ] ; then 595 # The following circumlocution (repeated below as well) ensures 596 # that we record the true directory name and not one that is 597 # faked up with symlink names. 598 PWD= /bin/pwd 599 else 600 local HERE=$PWD 601 T= 602 while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do 603 \cd .. 604 T=`PWD= /bin/pwd` 605 done 606 \cd $HERE 607 if [ -f "$T/$TOPFILE" ]; then 608 echo $T 609 fi 610 fi 611 fi 612} 613 614# Return driver for "make", if any (eg. static analyzer) 615function getdriver() 616{ 617 local T="$1" 618 test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER 619 if [ -n "$WITH_STATIC_ANALYZER" ]; then 620 echo "\ 621$T/prebuilts/clang/linux-x86/host/3.3/tools/scan-build/scan-build \ 622--use-analyzer $T/prebuilts/clang/linux-x86/host/3.3/bin/analyzer \ 623--status-bugs \ 624--top=$T" 625 fi 626} 627 628function m() 629{ 630 local T=$(gettop) 631 local DRV=$(getdriver $T) 632 if [ "$T" ]; then 633 $DRV make -C $T -f build/core/main.mk $@ 634 else 635 echo "Couldn't locate the top of the tree. Try setting TOP." 636 fi 637} 638 639function findmakefile() 640{ 641 TOPFILE=build/core/envsetup.mk 642 local HERE=$PWD 643 T= 644 while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do 645 T=`PWD= /bin/pwd` 646 if [ -f "$T/Android.mk" ]; then 647 echo $T/Android.mk 648 \cd $HERE 649 return 650 fi 651 \cd .. 652 done 653 \cd $HERE 654} 655 656function mm() 657{ 658 local T=$(gettop) 659 local DRV=$(getdriver $T) 660 # If we're sitting in the root of the build tree, just do a 661 # normal make. 662 if [ -f build/core/envsetup.mk -a -f Makefile ]; then 663 $DRV make $@ 664 else 665 # Find the closest Android.mk file. 666 local M=$(findmakefile) 667 local MODULES= 668 local GET_INSTALL_PATH= 669 local ARGS= 670 # Remove the path to top as the makefilepath needs to be relative 671 local M=`echo $M|sed 's:'$T'/::'` 672 if [ ! "$T" ]; then 673 echo "Couldn't locate the top of the tree. Try setting TOP." 674 elif [ ! "$M" ]; then 675 echo "Couldn't locate a makefile from the current directory." 676 else 677 for ARG in $@; do 678 case $ARG in 679 GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;; 680 esac 681 done 682 if [ -n "$GET_INSTALL_PATH" ]; then 683 MODULES= 684 ARGS=GET-INSTALL-PATH 685 else 686 MODULES=all_modules 687 ARGS=$@ 688 fi 689 ONE_SHOT_MAKEFILE=$M $DRV make -C $T -f build/core/main.mk $MODULES $ARGS 690 fi 691 fi 692} 693 694function mmm() 695{ 696 local T=$(gettop) 697 local DRV=$(getdriver $T) 698 if [ "$T" ]; then 699 local MAKEFILE= 700 local MODULES= 701 local ARGS= 702 local DIR TO_CHOP 703 local GET_INSTALL_PATH= 704 local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/') 705 local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/') 706 for DIR in $DIRS ; do 707 MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'` 708 if [ "$MODULES" = "" ]; then 709 MODULES=all_modules 710 fi 711 DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'` 712 if [ -f $DIR/Android.mk ]; then 713 local TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '` 714 local TO_CHOP=`expr $TO_CHOP + 1` 715 local START=`PWD= /bin/pwd` 716 local MFILE=`echo $START | cut -c${TO_CHOP}-` 717 if [ "$MFILE" = "" ] ; then 718 MFILE=$DIR/Android.mk 719 else 720 MFILE=$MFILE/$DIR/Android.mk 721 fi 722 MAKEFILE="$MAKEFILE $MFILE" 723 else 724 case $DIR in 725 showcommands | snod | dist | incrementaljavac) ARGS="$ARGS $DIR";; 726 GET-INSTALL-PATH) GET_INSTALL_PATH=$DIR;; 727 *) echo "No Android.mk in $DIR."; return 1;; 728 esac 729 fi 730 done 731 if [ -n "$GET_INSTALL_PATH" ]; then 732 ARGS=$GET_INSTALL_PATH 733 MODULES= 734 fi 735 ONE_SHOT_MAKEFILE="$MAKEFILE" $DRV make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $ARGS 736 else 737 echo "Couldn't locate the top of the tree. Try setting TOP." 738 fi 739} 740 741function mma() 742{ 743 local T=$(gettop) 744 local DRV=$(getdriver $T) 745 if [ -f build/core/envsetup.mk -a -f Makefile ]; then 746 $DRV make $@ 747 else 748 if [ ! "$T" ]; then 749 echo "Couldn't locate the top of the tree. Try setting TOP." 750 fi 751 local MY_PWD=`PWD= /bin/pwd|sed 's:'$T'/::'` 752 $DRV make -C $T -f build/core/main.mk $@ all_modules BUILD_MODULES_IN_PATHS="$MY_PWD" 753 fi 754} 755 756function mmma() 757{ 758 local T=$(gettop) 759 local DRV=$(getdriver $T) 760 if [ "$T" ]; then 761 local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/') 762 local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/') 763 local MY_PWD=`PWD= /bin/pwd` 764 if [ "$MY_PWD" = "$T" ]; then 765 MY_PWD= 766 else 767 MY_PWD=`echo $MY_PWD|sed 's:'$T'/::'` 768 fi 769 local DIR= 770 local MODULE_PATHS= 771 local ARGS= 772 for DIR in $DIRS ; do 773 if [ -d $DIR ]; then 774 if [ "$MY_PWD" = "" ]; then 775 MODULE_PATHS="$MODULE_PATHS $DIR" 776 else 777 MODULE_PATHS="$MODULE_PATHS $MY_PWD/$DIR" 778 fi 779 else 780 case $DIR in 781 showcommands | snod | dist | incrementaljavac) ARGS="$ARGS $DIR";; 782 *) echo "Couldn't find directory $DIR"; return 1;; 783 esac 784 fi 785 done 786 $DRV make -C $T -f build/core/main.mk $DASH_ARGS $ARGS all_modules BUILD_MODULES_IN_PATHS="$MODULE_PATHS" 787 else 788 echo "Couldn't locate the top of the tree. Try setting TOP." 789 fi 790} 791 792function croot() 793{ 794 T=$(gettop) 795 if [ "$T" ]; then 796 \cd $(gettop) 797 else 798 echo "Couldn't locate the top of the tree. Try setting TOP." 799 fi 800} 801 802function cproj() 803{ 804 TOPFILE=build/core/envsetup.mk 805 local HERE=$PWD 806 T= 807 while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do 808 T=$PWD 809 if [ -f "$T/Android.mk" ]; then 810 \cd $T 811 return 812 fi 813 \cd .. 814 done 815 \cd $HERE 816 echo "can't find Android.mk" 817} 818 819# simplified version of ps; output in the form 820# <pid> <procname> 821function qpid() { 822 local prepend='' 823 local append='' 824 if [ "$1" = "--exact" ]; then 825 prepend=' ' 826 append='$' 827 shift 828 elif [ "$1" = "--help" -o "$1" = "-h" ]; then 829 echo "usage: qpid [[--exact] <process name|pid>" 830 return 255 831 fi 832 833 local EXE="$1" 834 if [ "$EXE" ] ; then 835 qpid | \grep "$prepend$EXE$append" 836 else 837 adb shell ps \ 838 | tr -d '\r' \ 839 | sed -e 1d -e 's/^[^ ]* *\([0-9]*\).* \([^ ]*\)$/\1 \2/' 840 fi 841} 842 843function pid() 844{ 845 local prepend='' 846 local append='' 847 if [ "$1" = "--exact" ]; then 848 prepend=' ' 849 append='$' 850 shift 851 fi 852 local EXE="$1" 853 if [ "$EXE" ] ; then 854 local PID=`adb shell ps \ 855 | tr -d '\r' \ 856 | \grep "$prepend$EXE$append" \ 857 | sed -e 's/^[^ ]* *\([0-9]*\).*$/\1/'` 858 echo "$PID" 859 else 860 echo "usage: pid [--exact] <process name>" 861 return 255 862 fi 863} 864 865# systemstack - dump the current stack trace of all threads in the system process 866# to the usual ANR traces file 867function systemstack() 868{ 869 stacks system_server 870} 871 872function stacks() 873{ 874 if [[ $1 =~ ^[0-9]+$ ]] ; then 875 local PID="$1" 876 elif [ "$1" ] ; then 877 local PIDLIST="$(pid $1)" 878 if [[ $PIDLIST =~ ^[0-9]+$ ]] ; then 879 local PID="$PIDLIST" 880 elif [ "$PIDLIST" ] ; then 881 echo "more than one process: $1" 882 else 883 echo "no such process: $1" 884 fi 885 else 886 echo "usage: stacks [pid|process name]" 887 fi 888 889 if [ "$PID" ] ; then 890 # Determine whether the process is native 891 if adb shell ls -l /proc/$PID/exe | grep -q /system/bin/app_process ; then 892 # Dump stacks of Dalvik process 893 local TRACES=/data/anr/traces.txt 894 local ORIG=/data/anr/traces.orig 895 local TMP=/data/anr/traces.tmp 896 897 # Keep original traces to avoid clobbering 898 adb shell mv $TRACES $ORIG 899 900 # Make sure we have a usable file 901 adb shell touch $TRACES 902 adb shell chmod 666 $TRACES 903 904 # Dump stacks and wait for dump to finish 905 adb shell kill -3 $PID 906 adb shell notify $TRACES >/dev/null 907 908 # Restore original stacks, and show current output 909 adb shell mv $TRACES $TMP 910 adb shell mv $ORIG $TRACES 911 adb shell cat $TMP 912 else 913 # Dump stacks of native process 914 adb shell debuggerd -b $PID 915 fi 916 fi 917} 918 919function gdbwrapper() 920{ 921 $ANDROID_TOOLCHAIN/$GDB -x "$@" 922} 923 924function gdbclient() 925{ 926 local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT) 927 local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED) 928 local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED) 929 local OUT_EXE_SYMBOLS=$(get_abs_build_var TARGET_OUT_EXECUTABLES_UNSTRIPPED) 930 local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS) 931 local ARCH=$(get_build_var TARGET_ARCH) 932 local GDB 933 case "$ARCH" in 934 arm) GDB=arm-linux-androideabi-gdb;; 935 arm64) GDB=aarch64-linux-android-gdb;; 936 mips) GDB=mipsel-linux-android-gdb;; 937 mips64) GDB=mipsel-linux-android-gdb;; 938 x86) GDB=x86_64-linux-android-gdb;; 939 x86_64) GDB=x86_64-linux-android-gdb;; 940 *) echo "Unknown arch $ARCH"; return 1;; 941 esac 942 943 if [ "$OUT_ROOT" -a "$PREBUILTS" ]; then 944 local EXE="$1" 945 if [ "$EXE" ] ; then 946 EXE=$1 947 else 948 EXE="app_process" 949 fi 950 951 local PORT="$2" 952 if [ "$PORT" ] ; then 953 PORT=$2 954 else 955 PORT=":5039" 956 fi 957 958 local PID="$3" 959 if [ "$PID" ] ; then 960 if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then 961 PID=`pid $3` 962 if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then 963 # that likely didn't work because of returning multiple processes 964 # try again, filtering by root processes (don't contain colon) 965 PID=`adb shell ps | \grep $3 | \grep -v ":" | awk '{print $2}'` 966 if [[ ! "$PID" =~ ^[0-9]+$ ]] 967 then 968 echo "Couldn't resolve '$3' to single PID" 969 return 1 970 else 971 echo "" 972 echo "WARNING: multiple processes matching '$3' observed, using root process" 973 echo "" 974 fi 975 fi 976 fi 977 adb forward "tcp$PORT" "tcp$PORT" 978 adb shell gdbserver $PORT --attach $PID & 979 sleep 2 980 else 981 echo "" 982 echo "If you haven't done so already, do this first on the device:" 983 echo " gdbserver $PORT /system/bin/$EXE" 984 echo " or" 985 echo " gdbserver $PORT --attach <PID>" 986 echo "" 987 fi 988 989 echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS" 990 echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS:$OUT_SO_SYMBOLS/hw:$OUT_SO_SYMBOLS/ssl/engines:$OUT_SO_SYMBOLS/drm:$OUT_SO_SYMBOLS/egl:$OUT_SO_SYMBOLS/soundfx" 991 echo >>"$OUT_ROOT/gdbclient.cmds" "source $ANDROID_BUILD_TOP/development/scripts/gdb/dalvik.gdb" 992 echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT" 993 echo >>"$OUT_ROOT/gdbclient.cmds" "" 994 995 gdbwrapper "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE" 996 else 997 echo "Unable to determine build system output dir." 998 fi 999 1000} 1001 1002case `uname -s` in 1003 Darwin) 1004 function sgrep() 1005 { 1006 find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|S|java|xml|sh|mk)' -print0 | xargs -0 grep --color -n "$@" 1007 } 1008 1009 ;; 1010 *) 1011 function sgrep() 1012 { 1013 find . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.\(c\|h\|cpp\|S\|java\|xml\|sh\|mk\)' -print0 | xargs -0 grep --color -n "$@" 1014 } 1015 ;; 1016esac 1017 1018function gettargetarch 1019{ 1020 get_build_var TARGET_ARCH 1021} 1022 1023function jgrep() 1024{ 1025 find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" -print0 | xargs -0 grep --color -n "$@" 1026} 1027 1028function cgrep() 1029{ 1030 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' \) -print0 | xargs -0 grep --color -n "$@" 1031} 1032 1033function resgrep() 1034{ 1035 for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do find $dir -type f -name '*\.xml' -print0 | xargs -0 grep --color -n "$@"; done; 1036} 1037 1038function mangrep() 1039{ 1040 find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'AndroidManifest.xml' -print0 | xargs -0 grep --color -n "$@" 1041} 1042 1043function sepgrep() 1044{ 1045 find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d -print0 | xargs -0 grep --color -n -r --exclude-dir=\.git "$@" 1046} 1047 1048case `uname -s` in 1049 Darwin) 1050 function mgrep() 1051 { 1052 find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -print0 | xargs -0 grep --color -n "$@" 1053 } 1054 1055 function treegrep() 1056 { 1057 find -E . -name .repo -prune -o -name .git -prune -o -type f -iregex '.*\.(c|h|cpp|S|java|xml)' -print0 | xargs -0 grep --color -n -i "$@" 1058 } 1059 1060 ;; 1061 *) 1062 function mgrep() 1063 { 1064 find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f -print0 | xargs -0 grep --color -n "$@" 1065 } 1066 1067 function treegrep() 1068 { 1069 find . -name .repo -prune -o -name .git -prune -o -regextype posix-egrep -iregex '.*\.(c|h|cpp|S|java|xml)' -type f -print0 | xargs -0 grep --color -n -i "$@" 1070 } 1071 1072 ;; 1073esac 1074 1075function getprebuilt 1076{ 1077 get_abs_build_var ANDROID_PREBUILTS 1078} 1079 1080function tracedmdump() 1081{ 1082 T=$(gettop) 1083 if [ ! "$T" ]; then 1084 echo "Couldn't locate the top of the tree. Try setting TOP." 1085 return 1086 fi 1087 local prebuiltdir=$(getprebuilt) 1088 local arch=$(gettargetarch) 1089 local KERNEL=$T/prebuilts/qemu-kernel/$arch/vmlinux-qemu 1090 1091 local TRACE=$1 1092 if [ ! "$TRACE" ] ; then 1093 echo "usage: tracedmdump tracename" 1094 return 1095 fi 1096 1097 if [ ! -r "$KERNEL" ] ; then 1098 echo "Error: cannot find kernel: '$KERNEL'" 1099 return 1100 fi 1101 1102 local BASETRACE=$(basename $TRACE) 1103 if [ "$BASETRACE" = "$TRACE" ] ; then 1104 TRACE=$ANDROID_PRODUCT_OUT/traces/$TRACE 1105 fi 1106 1107 echo "post-processing traces..." 1108 rm -f $TRACE/qtrace.dexlist 1109 post_trace $TRACE 1110 if [ $? -ne 0 ]; then 1111 echo "***" 1112 echo "*** Error: malformed trace. Did you remember to exit the emulator?" 1113 echo "***" 1114 return 1115 fi 1116 echo "generating dexlist output..." 1117 /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 1118 echo "generating dmtrace data..." 1119 q2dm -r $ANDROID_PRODUCT_OUT/symbols $TRACE $KERNEL $TRACE/dmtrace || return 1120 echo "generating html file..." 1121 dmtracedump -h $TRACE/dmtrace >| $TRACE/dmtrace.html || return 1122 echo "done, see $TRACE/dmtrace.html for details" 1123 echo "or run:" 1124 echo " traceview $TRACE/dmtrace" 1125} 1126 1127# communicate with a running device or emulator, set up necessary state, 1128# and run the hat command. 1129function runhat() 1130{ 1131 # process standard adb options 1132 local adbTarget="" 1133 if [ "$1" = "-d" -o "$1" = "-e" ]; then 1134 adbTarget=$1 1135 shift 1 1136 elif [ "$1" = "-s" ]; then 1137 adbTarget="$1 $2" 1138 shift 2 1139 fi 1140 local adbOptions=${adbTarget} 1141 #echo adbOptions = ${adbOptions} 1142 1143 # runhat options 1144 local targetPid=$1 1145 1146 if [ "$targetPid" = "" ]; then 1147 echo "Usage: runhat [ -d | -e | -s serial ] target-pid" 1148 return 1149 fi 1150 1151 # confirm hat is available 1152 if [ -z $(which hat) ]; then 1153 echo "hat is not available in this configuration." 1154 return 1155 fi 1156 1157 # issue "am" command to cause the hprof dump 1158 local sdcard=$(adb ${adbOptions} shell echo -n '$EXTERNAL_STORAGE') 1159 local devFile=$sdcard/hprof-$targetPid 1160 #local devFile=/data/local/hprof-$targetPid 1161 echo "Poking $targetPid and waiting for data..." 1162 echo "Storing data at $devFile" 1163 adb ${adbOptions} shell am dumpheap $targetPid $devFile 1164 echo "Press enter when logcat shows \"hprof: heap dump completed\"" 1165 echo -n "> " 1166 read 1167 1168 local localFile=/tmp/$$-hprof 1169 1170 echo "Retrieving file $devFile..." 1171 adb ${adbOptions} pull $devFile $localFile 1172 1173 adb ${adbOptions} shell rm $devFile 1174 1175 echo "Running hat on $localFile" 1176 echo "View the output by pointing your browser at http://localhost:7000/" 1177 echo "" 1178 hat -JXmx512m $localFile 1179} 1180 1181function getbugreports() 1182{ 1183 local reports=(`adb shell ls /sdcard/bugreports | tr -d '\r'`) 1184 1185 if [ ! "$reports" ]; then 1186 echo "Could not locate any bugreports." 1187 return 1188 fi 1189 1190 local report 1191 for report in ${reports[@]} 1192 do 1193 echo "/sdcard/bugreports/${report}" 1194 adb pull /sdcard/bugreports/${report} ${report} 1195 gunzip ${report} 1196 done 1197} 1198 1199function getsdcardpath() 1200{ 1201 adb ${adbOptions} shell echo -n \$\{EXTERNAL_STORAGE\} 1202} 1203 1204function getscreenshotpath() 1205{ 1206 echo "$(getsdcardpath)/Pictures/Screenshots" 1207} 1208 1209function getlastscreenshot() 1210{ 1211 local screenshot_path=$(getscreenshotpath) 1212 local screenshot=`adb ${adbOptions} ls ${screenshot_path} | grep Screenshot_[0-9-]*.*\.png | sort -rk 3 | cut -d " " -f 4 | head -n 1` 1213 if [ "$screenshot" = "" ]; then 1214 echo "No screenshots found." 1215 return 1216 fi 1217 echo "${screenshot}" 1218 adb ${adbOptions} pull ${screenshot_path}/${screenshot} 1219} 1220 1221function startviewserver() 1222{ 1223 local port=4939 1224 if [ $# -gt 0 ]; then 1225 port=$1 1226 fi 1227 adb shell service call window 1 i32 $port 1228} 1229 1230function stopviewserver() 1231{ 1232 adb shell service call window 2 1233} 1234 1235function isviewserverstarted() 1236{ 1237 adb shell service call window 3 1238} 1239 1240function key_home() 1241{ 1242 adb shell input keyevent 3 1243} 1244 1245function key_back() 1246{ 1247 adb shell input keyevent 4 1248} 1249 1250function key_menu() 1251{ 1252 adb shell input keyevent 82 1253} 1254 1255function smoketest() 1256{ 1257 if [ ! "$ANDROID_PRODUCT_OUT" ]; then 1258 echo "Couldn't locate output files. Try running 'lunch' first." >&2 1259 return 1260 fi 1261 T=$(gettop) 1262 if [ ! "$T" ]; then 1263 echo "Couldn't locate the top of the tree. Try setting TOP." >&2 1264 return 1265 fi 1266 1267 (\cd "$T" && mmm tests/SmokeTest) && 1268 adb uninstall com.android.smoketest > /dev/null && 1269 adb uninstall com.android.smoketest.tests > /dev/null && 1270 adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTestApp.apk && 1271 adb install $ANDROID_PRODUCT_OUT/data/app/SmokeTest.apk && 1272 adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner 1273} 1274 1275# simple shortcut to the runtest command 1276function runtest() 1277{ 1278 T=$(gettop) 1279 if [ ! "$T" ]; then 1280 echo "Couldn't locate the top of the tree. Try setting TOP." >&2 1281 return 1282 fi 1283 ("$T"/development/testrunner/runtest.py $@) 1284} 1285 1286function godir () { 1287 if [[ -z "$1" ]]; then 1288 echo "Usage: godir <regex>" 1289 return 1290 fi 1291 T=$(gettop) 1292 if [[ ! -f $T/filelist ]]; then 1293 echo -n "Creating index..." 1294 (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > filelist) 1295 echo " Done" 1296 echo "" 1297 fi 1298 local lines 1299 lines=($(\grep "$1" $T/filelist | sed -e 's/\/[^/]*$//' | sort | uniq)) 1300 if [[ ${#lines[@]} = 0 ]]; then 1301 echo "Not found" 1302 return 1303 fi 1304 local pathname 1305 local choice 1306 if [[ ${#lines[@]} > 1 ]]; then 1307 while [[ -z "$pathname" ]]; do 1308 local index=1 1309 local line 1310 for line in ${lines[@]}; do 1311 printf "%6s %s\n" "[$index]" $line 1312 index=$(($index + 1)) 1313 done 1314 echo 1315 echo -n "Select one: " 1316 unset choice 1317 read choice 1318 if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then 1319 echo "Invalid choice" 1320 continue 1321 fi 1322 pathname=${lines[$(($choice-1))]} 1323 done 1324 else 1325 pathname=${lines[0]} 1326 fi 1327 \cd $T/$pathname 1328} 1329 1330# Force JAVA_HOME to point to java 1.7 or java 1.6 if it isn't already set. 1331# 1332# Note that the MacOS path for java 1.7 includes a minor revision number (sigh). 1333# For some reason, installing the JDK doesn't make it show up in the 1334# JavaVM.framework/Versions/1.7/ folder. 1335function set_java_home() { 1336 # Clear the existing JAVA_HOME value if we set it ourselves, so that 1337 # we can reset it later, depending on the value of EXPERIMENTAL_USE_JAVA7. 1338 # 1339 # If we don't do this, the JAVA_HOME value set by the first call to 1340 # build/envsetup.sh will persist forever. 1341 if [ -n "$ANDROID_SET_JAVA_HOME" ]; then 1342 export JAVA_HOME="" 1343 fi 1344 1345 if [ ! "$JAVA_HOME" ]; then 1346 if [ ! "$EXPERIMENTAL_USE_JAVA7" ]; then 1347 case `uname -s` in 1348 Darwin) 1349 export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home 1350 ;; 1351 *) 1352 export JAVA_HOME=/usr/lib/jvm/java-6-sun 1353 ;; 1354 esac 1355 else 1356 case `uname -s` in 1357 Darwin) 1358 export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home 1359 ;; 1360 *) 1361 export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 1362 ;; 1363 esac 1364 fi 1365 1366 # Keep track of the fact that we set JAVA_HOME ourselves, so that 1367 # we can change it on the next envsetup.sh, if required. 1368 export ANDROID_SET_JAVA_HOME=true 1369 fi 1370} 1371 1372# Print colored exit condition 1373function pez { 1374 "$@" 1375 local retval=$? 1376 if [ $retval -ne 0 ] 1377 then 1378 echo -e "\e[0;31mFAILURE\e[00m" 1379 else 1380 echo -e "\e[0;32mSUCCESS\e[00m" 1381 fi 1382 return $retval 1383} 1384 1385if [ "x$SHELL" != "x/bin/bash" ]; then 1386 case `ps -o command -p $$` in 1387 *bash*) 1388 ;; 1389 *) 1390 echo "WARNING: Only bash is supported, use of other shell would lead to erroneous results" 1391 ;; 1392 esac 1393fi 1394 1395# Execute the contents of any vendorsetup.sh files we can find. 1396for f in `test -d device && find device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` \ 1397 `test -d vendor && find vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null` 1398do 1399 echo "including $f" 1400 . $f 1401done 1402unset f 1403 1404addcompletions 1405