1# Copyright (C) 2022 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# gettop is duplicated here and in shell_utils.mk, because it's difficult 16# to find shell_utils.make without it for all the novel ways this file can be 17# sourced. Other common functions should only be in one place or the other. 18function _gettop_once 19{ 20 local TOPFILE=build/make/core/envsetup.mk 21 if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then 22 # The following circumlocution ensures we remove symlinks from TOP. 23 (cd "$TOP"; PWD= /bin/pwd) 24 else 25 if [ -f $TOPFILE ] ; then 26 # The following circumlocution (repeated below as well) ensures 27 # that we record the true directory name and not one that is 28 # faked up with symlink names. 29 PWD= /bin/pwd 30 else 31 local HERE=$PWD 32 local T= 33 while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do 34 \cd .. 35 T=`PWD= /bin/pwd -P` 36 done 37 \cd "$HERE" 38 if [ -f "$T/$TOPFILE" ]; then 39 echo "$T" 40 fi 41 fi 42 fi 43} 44T=$(_gettop_once) 45if [ ! "$T" ]; then 46 echo "Couldn't locate the top of the tree. Always source build/envsetup.sh from the root of the tree." >&2 47 return 1 48fi 49IMPORTING_ENVSETUP=true source $T/build/make/shell_utils.sh 50 51# Get all the build variables needed by this script in a single call to the build system. 52function 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_cached/) 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_cached/) 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. 83function 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. 98function _get_abs_build_var_cached() 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. 115function _get_build_var_cached() 116{ 117 if [ "$BUILD_VAR_CACHE_READY" = "true" ] 118 then 119 eval "echo \"\${var_cache_$1}\"" 120 return 0 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 1 127 fi 128 (\cd $T; build/soong/soong_ui.bash --dumpvar-mode $1) 129} 130 131# This logic matches envsetup.mk 132function get_host_prebuilt_prefix 133{ 134 local un=$(uname) 135 if [[ $un == "Linux" ]] ; then 136 echo linux-x86 137 elif [[ $un == "Darwin" ]] ; then 138 echo darwin-x86 139 else 140 echo "Error: Invalid host operating system: $un" 1>&2 141 fi 142} 143 144# Add directories to PATH that are dependent on the lunch target. 145# For directories that are not lunch-specific, add them in set_global_paths 146function set_lunch_paths() 147{ 148 local T=$(gettop) 149 if [ ! "$T" ]; then 150 echo "Couldn't locate the top of the tree. Try setting TOP." 151 return 152 fi 153 154 ################################################################## 155 # # 156 # Read me before you modify this code # 157 # # 158 # This function sets ANDROID_LUNCH_BUILD_PATHS to what it is # 159 # adding to PATH, and the next time it is run, it removes that # 160 # from PATH. This is required so lunch can be run more than # 161 # once and still have working paths. # 162 # # 163 ################################################################## 164 165 # Note: on windows/cygwin, ANDROID_LUNCH_BUILD_PATHS will contain spaces 166 # due to "C:\Program Files" being in the path. 167 168 # Handle compat with the old ANDROID_BUILD_PATHS variable. 169 # TODO: Remove this after we think everyone has lunched again. 170 if [ -z "$ANDROID_LUNCH_BUILD_PATHS" -a -n "$ANDROID_BUILD_PATHS" ] ; then 171 ANDROID_LUNCH_BUILD_PATHS="$ANDROID_BUILD_PATHS" 172 ANDROID_BUILD_PATHS= 173 fi 174 if [ -n "$ANDROID_PRE_BUILD_PATHS" ] ; then 175 export PATH=${PATH/$ANDROID_PRE_BUILD_PATHS/} 176 # strip leading ':', if any 177 export PATH=${PATH/:%/} 178 ANDROID_PRE_BUILD_PATHS= 179 fi 180 181 # Out with the old... 182 if [ -n "$ANDROID_LUNCH_BUILD_PATHS" ] ; then 183 export PATH=${PATH/$ANDROID_LUNCH_BUILD_PATHS/} 184 fi 185 186 # And in with the new... 187 ANDROID_LUNCH_BUILD_PATHS=$(_get_abs_build_var_cached SOONG_HOST_OUT_EXECUTABLES) 188 ANDROID_LUNCH_BUILD_PATHS+=:$(_get_abs_build_var_cached HOST_OUT_EXECUTABLES) 189 190 # Append llvm binutils prebuilts path to ANDROID_LUNCH_BUILD_PATHS. 191 local ANDROID_LLVM_BINUTILS=$(_get_abs_build_var_cached ANDROID_CLANG_PREBUILTS)/llvm-binutils-stable 192 ANDROID_LUNCH_BUILD_PATHS+=:$ANDROID_LLVM_BINUTILS 193 194 # Set up ASAN_SYMBOLIZER_PATH for SANITIZE_HOST=address builds. 195 export ASAN_SYMBOLIZER_PATH=$ANDROID_LLVM_BINUTILS/llvm-symbolizer 196 197 # Append asuite prebuilts path to ANDROID_LUNCH_BUILD_PATHS. 198 local os_arch=$(_get_build_var_cached HOST_PREBUILT_TAG) 199 ANDROID_LUNCH_BUILD_PATHS+=:$T/prebuilts/asuite/acloud/$os_arch 200 ANDROID_LUNCH_BUILD_PATHS+=:$T/prebuilts/asuite/aidegen/$os_arch 201 ANDROID_LUNCH_BUILD_PATHS+=:$T/prebuilts/asuite/atest/$os_arch 202 203 export ANDROID_JAVA_HOME=$(_get_abs_build_var_cached ANDROID_JAVA_HOME) 204 export JAVA_HOME=$ANDROID_JAVA_HOME 205 export ANDROID_JAVA_TOOLCHAIN=$(_get_abs_build_var_cached ANDROID_JAVA_TOOLCHAIN) 206 ANDROID_LUNCH_BUILD_PATHS+=:$ANDROID_JAVA_TOOLCHAIN 207 208 # Fix up PYTHONPATH 209 if [ -n $ANDROID_PYTHONPATH ]; then 210 export PYTHONPATH=${PYTHONPATH//$ANDROID_PYTHONPATH/} 211 fi 212 # //development/python-packages contains both a pseudo-PYTHONPATH which 213 # mimics an already assembled venv, but also contains real Python packages 214 # that are not in that layout until they are installed. We can fake it for 215 # the latter type by adding the package source directories to the PYTHONPATH 216 # directly. For the former group, we only need to add the python-packages 217 # directory itself. 218 # 219 # This could be cleaned up by converting the remaining packages that are in 220 # the first category into a typical python source layout (that is, another 221 # layer of directory nesting) and automatically adding all subdirectories of 222 # python-packages to the PYTHONPATH instead of manually curating this. We 223 # can't convert the packages like adb to the other style because doing so 224 # would prevent exporting type info from those packages. 225 # 226 # http://b/266688086 227 export ANDROID_PYTHONPATH=$T/development/python-packages/adb:$T/development/python-packages/gdbrunner:$T/development/python-packages: 228 if [ -n $VENDOR_PYTHONPATH ]; then 229 ANDROID_PYTHONPATH=$ANDROID_PYTHONPATH$VENDOR_PYTHONPATH 230 fi 231 export PYTHONPATH=$ANDROID_PYTHONPATH$PYTHONPATH 232 233 unset ANDROID_PRODUCT_OUT 234 export ANDROID_PRODUCT_OUT=$(_get_abs_build_var_cached PRODUCT_OUT) 235 export OUT=$ANDROID_PRODUCT_OUT 236 237 unset ANDROID_HOST_OUT 238 export ANDROID_HOST_OUT=$(_get_abs_build_var_cached HOST_OUT) 239 240 unset ANDROID_SOONG_HOST_OUT 241 export ANDROID_SOONG_HOST_OUT=$(_get_abs_build_var_cached SOONG_HOST_OUT) 242 243 unset ANDROID_HOST_OUT_TESTCASES 244 export ANDROID_HOST_OUT_TESTCASES=$(_get_abs_build_var_cached HOST_OUT_TESTCASES) 245 246 unset ANDROID_TARGET_OUT_TESTCASES 247 export ANDROID_TARGET_OUT_TESTCASES=$(_get_abs_build_var_cached TARGET_OUT_TESTCASES) 248 249 # Finally, set PATH 250 export PATH=$ANDROID_LUNCH_BUILD_PATHS:$PATH 251} 252 253# Add directories to PATH that are NOT dependent on the lunch target. 254# For directories that are lunch-specific, add them in set_lunch_paths 255function set_global_paths() 256{ 257 local T=$(gettop) 258 if [ ! "$T" ]; then 259 echo "Couldn't locate the top of the tree. Try setting TOP." 260 return 261 fi 262 263 ################################################################## 264 # # 265 # Read me before you modify this code # 266 # # 267 # This function sets ANDROID_GLOBAL_BUILD_PATHS to what it is # 268 # adding to PATH, and the next time it is run, it removes that # 269 # from PATH. This is required so envsetup.sh can be sourced # 270 # more than once and still have working paths. # 271 # # 272 ################################################################## 273 274 # Out with the old... 275 if [ -n "$ANDROID_GLOBAL_BUILD_PATHS" ] ; then 276 export PATH=${PATH/$ANDROID_GLOBAL_BUILD_PATHS/} 277 fi 278 279 # And in with the new... 280 ANDROID_GLOBAL_BUILD_PATHS=$T/build/soong/bin 281 ANDROID_GLOBAL_BUILD_PATHS+=:$T/build/bazel/bin 282 ANDROID_GLOBAL_BUILD_PATHS+=:$T/development/scripts 283 ANDROID_GLOBAL_BUILD_PATHS+=:$T/prebuilts/devtools/tools 284 285 # add kernel specific binaries 286 if [ $(uname -s) = Linux ] ; then 287 ANDROID_GLOBAL_BUILD_PATHS+=:$T/prebuilts/misc/linux-x86/dtc 288 ANDROID_GLOBAL_BUILD_PATHS+=:$T/prebuilts/misc/linux-x86/libufdt 289 fi 290 291 # If prebuilts/android-emulator/<system>/ exists, prepend it to our PATH 292 # to ensure that the corresponding 'emulator' binaries are used. 293 case $(uname -s) in 294 Darwin) 295 ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/darwin-x86_64 296 ;; 297 Linux) 298 ANDROID_EMULATOR_PREBUILTS=$T/prebuilts/android-emulator/linux-x86_64 299 ;; 300 *) 301 ANDROID_EMULATOR_PREBUILTS= 302 ;; 303 esac 304 if [ -n "$ANDROID_EMULATOR_PREBUILTS" -a -d "$ANDROID_EMULATOR_PREBUILTS" ]; then 305 ANDROID_GLOBAL_BUILD_PATHS+=:$ANDROID_EMULATOR_PREBUILTS 306 export ANDROID_EMULATOR_PREBUILTS 307 fi 308 309 # Finally, set PATH 310 export PATH=$ANDROID_GLOBAL_BUILD_PATHS:$PATH 311} 312 313function printconfig() 314{ 315 local T=$(gettop) 316 if [ ! "$T" ]; then 317 echo "Couldn't locate the top of the tree. Try setting TOP." >&2 318 return 319 fi 320 _get_build_var_cached report_config 321} 322 323function set_stuff_for_environment() 324{ 325 set_lunch_paths 326 set_sequence_number 327 328 export ANDROID_BUILD_TOP=$(gettop) 329} 330 331function set_sequence_number() 332{ 333 export BUILD_ENV_SEQUENCE_NUMBER=13 334} 335 336# Takes a command name, and check if it's in ENVSETUP_NO_COMPLETION or not. 337function should_add_completion() { 338 local cmd="$(basename $1| sed 's/_completion//' |sed 's/\.\(.*\)*sh$//')" 339 case :"$ENVSETUP_NO_COMPLETION": in 340 *:"$cmd":*) 341 return 1 342 ;; 343 esac 344 return 0 345} 346 347function addcompletions() 348{ 349 local f= 350 351 # Keep us from trying to run in something that's neither bash nor zsh. 352 if [ -z "$BASH_VERSION" -a -z "$ZSH_VERSION" ]; then 353 return 354 fi 355 356 # Keep us from trying to run in bash that's too old. 357 if [ -n "$BASH_VERSION" -a ${BASH_VERSINFO[0]} -lt 3 ]; then 358 return 359 fi 360 361 local completion_files=( 362 packages/modules/adb/adb.bash 363 system/core/fastboot/fastboot.bash 364 tools/asuite/asuite.sh 365 prebuilts/bazel/common/bazel-complete.bash 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 local T=$(gettop) 372 for f in ${completion_files[*]}; do 373 f="$T/$f" 374 if [ ! -f "$f" ]; then 375 echo "Warning: completion file $f not found" 376 elif should_add_completion "$f"; then 377 . $f 378 fi 379 done 380 381 if [ -z "$ZSH_VERSION" ]; then 382 # Doesn't work in zsh. 383 complete -o nospace -F _croot croot 384 # TODO(b/244559459): Support b autocompletion for zsh 385 complete -F _bazel__complete -o nospace b 386 fi 387 complete -F _lunch lunch 388 complete -F _lunch_completion lunch2 389 390 complete -F _complete_android_module_names pathmod 391 complete -F _complete_android_module_names gomod 392 complete -F _complete_android_module_names outmod 393 complete -F _complete_android_module_names installmod 394 complete -F _complete_android_module_names m 395} 396 397function add_lunch_combo() 398{ 399 if [ -n "$ZSH_VERSION" ]; then 400 echo -n "${funcfiletrace[1]}: " 401 else 402 echo -n "${BASH_SOURCE[1]}:${BASH_LINENO[0]}: " 403 fi 404 echo "add_lunch_combo is obsolete. Use COMMON_LUNCH_CHOICES in your AndroidProducts.mk instead." 405} 406 407function print_lunch_menu() 408{ 409 local uname=$(uname) 410 local choices 411 choices=$(TARGET_BUILD_APPS= TARGET_PRODUCT= TARGET_RELEASE= TARGET_BUILD_VARIANT= _get_build_var_cached COMMON_LUNCH_CHOICES 2>/dev/null) 412 local ret=$? 413 414 echo 415 echo "You're building on" $uname 416 echo 417 418 if [ $ret -ne 0 ] 419 then 420 echo "Warning: Cannot display lunch menu." 421 echo 422 echo "Note: You can invoke lunch with an explicit target:" 423 echo 424 echo " usage: lunch [target]" >&2 425 echo 426 return 427 fi 428 429 echo "Lunch menu .. Here are the common combinations:" 430 431 local i=1 432 local choice 433 for choice in $(echo $choices) 434 do 435 echo " $i. $choice" 436 i=$(($i+1)) 437 done 438 439 echo 440} 441 442function lunch() 443{ 444 local answer 445 446 if [[ $# -gt 1 ]]; then 447 echo "usage: lunch [target]" >&2 448 return 1 449 fi 450 451 local used_lunch_menu=0 452 453 if [ "$1" ]; then 454 answer=$1 455 else 456 print_lunch_menu 457 echo "Which would you like? [aosp_cf_x86_64_phone-trunk_staging-eng]" 458 echo -n "Pick from common choices above (e.g. 13) or specify your own (e.g. aosp_barbet-trunk_staging-eng): " 459 read answer 460 used_lunch_menu=1 461 fi 462 463 local selection= 464 465 if [ -z "$answer" ] 466 then 467 selection=aosp_cf_x86_64_phone-trunk_staging-eng 468 elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") 469 then 470 local choices=($(TARGET_BUILD_APPS= TARGET_PRODUCT= TARGET_RELEASE= TARGET_BUILD_VARIANT= _get_build_var_cached COMMON_LUNCH_CHOICES 2>/dev/null)) 471 if [ $answer -le ${#choices[@]} ] 472 then 473 # array in zsh starts from 1 instead of 0. 474 if [ -n "$ZSH_VERSION" ] 475 then 476 selection=${choices[$(($answer))]} 477 else 478 selection=${choices[$(($answer-1))]} 479 fi 480 fi 481 else 482 selection=$answer 483 fi 484 485 export TARGET_BUILD_APPS= 486 487 # This must be <product>-<release>-<variant> 488 local product release variant 489 # Split string on the '-' character. 490 IFS="-" read -r product release variant <<< "$selection" 491 492 if [[ -z "$product" ]] || [[ -z "$release" ]] || [[ -z "$variant" ]] 493 then 494 echo 495 echo "Invalid lunch combo: $selection" 496 echo "Valid combos must be of the form <product>-<release>-<variant>" 497 return 1 498 fi 499 500 _lunch_meat $product $release $variant 501} 502 503function _lunch_meat() 504{ 505 local product=$1 506 local release=$2 507 local variant=$3 508 509 TARGET_PRODUCT=$product \ 510 TARGET_RELEASE=$release \ 511 TARGET_BUILD_VARIANT=$variant \ 512 build_build_var_cache 513 if [ $? -ne 0 ] 514 then 515 if [[ "$product" =~ .*_(eng|user|userdebug) ]] 516 then 517 echo "Did you mean -${product/*_/}? (dash instead of underscore)" 518 fi 519 return 1 520 fi 521 export TARGET_PRODUCT=$(_get_build_var_cached TARGET_PRODUCT) 522 export TARGET_BUILD_VARIANT=$(_get_build_var_cached TARGET_BUILD_VARIANT) 523 export TARGET_RELEASE=$release 524 # Note this is the string "release", not the value of the variable. 525 export TARGET_BUILD_TYPE=release 526 527 [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || echo 528 529 set_stuff_for_environment 530 [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || printconfig 531 532 if [[ -z "${ANDROID_QUIET_BUILD}" ]]; then 533 local spam_for_lunch=$(gettop)/build/make/tools/envsetup/spam_for_lunch 534 if [[ -x $spam_for_lunch ]]; then 535 $spam_for_lunch 536 fi 537 fi 538 539 destroy_build_var_cache 540 541 if [[ -n "${CHECK_MU_CONFIG:-}" ]]; then 542 check_mu_config 543 fi 544} 545 546unset COMMON_LUNCH_CHOICES_CACHE 547# Tab completion for lunch. 548function _lunch() 549{ 550 local cur prev opts 551 COMPREPLY=() 552 cur="${COMP_WORDS[COMP_CWORD]}" 553 prev="${COMP_WORDS[COMP_CWORD-1]}" 554 555 if [ -z "$COMMON_LUNCH_CHOICES_CACHE" ]; then 556 COMMON_LUNCH_CHOICES_CACHE=$(TARGET_BUILD_APPS= _get_build_var_cached COMMON_LUNCH_CHOICES) 557 fi 558 559 COMPREPLY=( $(compgen -W "${COMMON_LUNCH_CHOICES_CACHE}" -- ${cur}) ) 560 return 0 561} 562 563function _lunch_usage() 564{ 565 ( 566 echo "The lunch command selects the configuration to use for subsequent" 567 echo "Android builds." 568 echo 569 echo "Usage: lunch TARGET_PRODUCT [TARGET_RELEASE [TARGET_BUILD_VARIANT]]" 570 echo 571 echo " Choose the product, release and variant to use. If not" 572 echo " supplied, TARGET_RELEASE will be 'trunk_staging' and" 573 echo " TARGET_BUILD_VARIANT will be 'eng'" 574 echo 575 echo 576 echo "Usage: lunch TARGET_PRODUCT-TARGET_RELEASE-TARGET_BUILD_VARIANT" 577 echo 578 echo " Chose the product, release and variant to use. This" 579 echo " legacy format is maintained for compatibility." 580 echo 581 echo 582 echo "Note that the previous interactive menu and list of hard-coded" 583 echo "list of curated targets has been removed. If you would like the" 584 echo "list of products, release configs for a particular product, or" 585 echo "variants, run list_products, list_release_configs, list_variants" 586 echo "respectively." 587 echo 588 ) 1>&2 589} 590 591function lunch2() 592{ 593 if [[ $# -eq 1 && $1 = "--help" ]]; then 594 _lunch_usage 595 return 0 596 fi 597 if [[ $# -eq 0 ]]; then 598 echo "No target specified. See lunch --help" 1>&2 599 return 1 600 fi 601 if [[ $# -gt 3 ]]; then 602 echo "Too many parameters given. See lunch --help" 1>&2 603 return 1 604 fi 605 606 local product release variant 607 608 # Handle the legacy format 609 local legacy=$(echo $1 | grep "-") 610 if [[ $# -eq 1 && -n $legacy ]]; then 611 IFS="-" read -r product release variant <<< "$1" 612 if [[ -z "$product" ]] || [[ -z "$release" ]] || [[ -z "$variant" ]]; then 613 echo "Invalid lunch combo: $1" 1>&2 614 echo "Valid combos must be of the form <product>-<release>-<variant> when using" 1>&2 615 echo "the legacy format. Run 'lunch --help' for usage." 1>&2 616 return 1 617 fi 618 fi 619 620 # Handle the new format. 621 if [[ -z $legacy ]]; then 622 product=$1 623 release=$2 624 if [[ -z $release ]]; then 625 release=trunk_staging 626 fi 627 variant=$3 628 if [[ -z $variant ]]; then 629 variant=eng 630 fi 631 fi 632 633 # Validate the selection and set all the environment stuff 634 _lunch_meat $product $release $variant 635} 636 637unset ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE 638unset ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT 639unset ANDROID_LUNCH_COMPLETION_RELEASE_CACHE 640# Tab completion for lunch. 641function _lunch_completion() 642{ 643 # Available products 644 if [[ $COMP_CWORD -eq 1 ]] ; then 645 if [[ -z $ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE ]]; then 646 ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE=$(list_products) 647 fi 648 COMPREPLY=( $(compgen -W "${ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE}" -- "${COMP_WORDS[COMP_CWORD]}") ) 649 fi 650 651 # Available release configs 652 if [[ $COMP_CWORD -eq 2 ]] ; then 653 if [[ -z $ANDROID_LUNCH_COMPLETION_RELEASE_CACHE || $ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT != ${COMP_WORDS[1]} ]] ; then 654 ANDROID_LUNCH_COMPLETION_RELEASE_CACHE=$(list_releases ${COMP_WORDS[1]}) 655 ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT=${COMP_WORDS[1]} 656 fi 657 COMPREPLY=( $(compgen -W "${ANDROID_LUNCH_COMPLETION_RELEASE_CACHE}" -- "${COMP_WORDS[COMP_CWORD]}") ) 658 fi 659 660 # Available variants 661 if [[ $COMP_CWORD -eq 3 ]] ; then 662 COMPREPLY=(user userdebug eng) 663 fi 664 665 return 0 666} 667 668 669# Configures the build to build unbundled apps. 670# Run tapas with one or more app names (from LOCAL_PACKAGE_NAME) 671function tapas() 672{ 673 local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)" 674 local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|arm64|x86_64)$' | xargs)" 675 # TODO(b/307975293): Expand tapas to take release arguments (and update hmm() usage). 676 local release="trunk_staging" 677 local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)" 678 local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)" 679 local keys="$(echo $* | xargs -n 1 echo | \grep -E '^(devkeys)$' | xargs)" 680 local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|arm|x86|arm64|x86_64|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi|devkeys)$' | xargs)" 681 682 683 if [ "$showHelp" != "" ]; then 684 $(gettop)/build/make/tapasHelp.sh 685 return 686 fi 687 688 if [ $(echo $arch | wc -w) -gt 1 ]; then 689 echo "tapas: Error: Multiple build archs supplied: $arch" 690 return 691 fi 692 if [ $(echo $release | wc -w) -gt 1 ]; then 693 echo "tapas: Error: Multiple build releases supplied: $release" 694 return 695 fi 696 if [ $(echo $variant | wc -w) -gt 1 ]; then 697 echo "tapas: Error: Multiple build variants supplied: $variant" 698 return 699 fi 700 if [ $(echo $density | wc -w) -gt 1 ]; then 701 echo "tapas: Error: Multiple densities supplied: $density" 702 return 703 fi 704 if [ $(echo $keys | wc -w) -gt 1 ]; then 705 echo "tapas: Error: Multiple keys supplied: $keys" 706 return 707 fi 708 709 local product=aosp_arm 710 case $arch in 711 x86) product=aosp_x86;; 712 arm64) product=aosp_arm64;; 713 x86_64) product=aosp_x86_64;; 714 esac 715 if [ -n "$keys" ]; then 716 product=${product/aosp_/aosp_${keys}_} 717 fi; 718 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_RELEASE=$release 731 export TARGET_BUILD_VARIANT=$variant 732 export TARGET_BUILD_DENSITY=$density 733 export TARGET_BUILD_TYPE=release 734 export TARGET_BUILD_APPS=$apps 735 736 build_build_var_cache 737 set_stuff_for_environment 738 printconfig 739 destroy_build_var_cache 740} 741 742# Configures the build to build unbundled Android modules (APEXes). 743# Run banchan with one or more module names (from apex{} modules). 744function banchan() 745{ 746 local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)" 747 local product="$(echo $* | xargs -n 1 echo | \grep -E '^(.*_)?(arm|x86|arm64|riscv64|x86_64|arm64only|x86_64only)$' | xargs)" 748 # TODO: Expand banchan to take release arguments (and update hmm() usage). 749 local release="trunk_staging" 750 local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)" 751 local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|(.*_)?(arm|x86|arm64|riscv64|x86_64))$' | xargs)" 752 753 if [ "$showHelp" != "" ]; then 754 $(gettop)/build/make/banchanHelp.sh 755 return 756 fi 757 758 if [ -z "$product" ]; then 759 product=arm64 760 elif [ $(echo $product | wc -w) -gt 1 ]; then 761 echo "banchan: Error: Multiple build archs or products supplied: $products" 762 return 763 fi 764 if [ $(echo $release | wc -w) -gt 1 ]; then 765 echo "banchan: Error: Multiple build releases supplied: $release" 766 return 767 fi 768 if [ $(echo $variant | wc -w) -gt 1 ]; then 769 echo "banchan: Error: Multiple build variants supplied: $variant" 770 return 771 fi 772 if [ -z "$apps" ]; then 773 echo "banchan: Error: No modules supplied" 774 return 775 fi 776 777 case $product in 778 arm) product=module_arm;; 779 x86) product=module_x86;; 780 arm64) product=module_arm64;; 781 riscv64) product=module_riscv64;; 782 x86_64) product=module_x86_64;; 783 arm64only) product=module_arm64only;; 784 x86_64only) product=module_x86_64only;; 785 esac 786 if [ -z "$variant" ]; then 787 variant=eng 788 fi 789 790 export TARGET_PRODUCT=$product 791 export TARGET_RELEASE=$release 792 export TARGET_BUILD_VARIANT=$variant 793 export TARGET_BUILD_DENSITY=alldpi 794 export TARGET_BUILD_TYPE=release 795 796 # This setup currently uses TARGET_BUILD_APPS just like tapas, but the use 797 # case is different and it may diverge in the future. 798 export TARGET_BUILD_APPS=$apps 799 800 build_build_var_cache 801 set_stuff_for_environment 802 printconfig 803 destroy_build_var_cache 804} 805 806function croot() 807{ 808 local T=$(gettop) 809 if [ "$T" ]; then 810 if [ "$1" ]; then 811 \cd $(gettop)/$1 812 else 813 \cd $(gettop) 814 fi 815 else 816 echo "Couldn't locate the top of the tree. Try setting TOP." 817 fi 818} 819 820function _croot() 821{ 822 local T=$(gettop) 823 if [ "$T" ]; then 824 local cur="${COMP_WORDS[COMP_CWORD]}" 825 k=0 826 for c in $(compgen -d ${T}/${cur}); do 827 COMPREPLY[k++]=${c#${T}/}/ 828 done 829 fi 830} 831 832function cproj() 833{ 834 local TOPFILE=build/make/core/envsetup.mk 835 local HERE=$PWD 836 local T= 837 while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do 838 T=$PWD 839 if [ -f "$T/Android.mk" ]; then 840 \cd $T 841 return 842 fi 843 \cd .. 844 done 845 \cd $HERE 846 echo "can't find Android.mk" 847} 848 849# Ensure that we're always using the adb in the tree. This works around the fact 850# that bash caches $PATH lookups, so if you use adb before lunching/building the 851# one in your tree, you'll continue to get /usr/bin/adb or whatever even after 852# you have the one from your current tree on your path. Historically this would 853# cause confusion because glinux had adb in /usr/bin/ by default, though that 854# doesn't appear to be the case on my rodete hosts; it is however still the case 855# that my Mac has /usr/local/bin/adb installed by default and on the default 856# path. 857function adb() { 858 # We need `command which` because zsh has a built-in `which` that's more 859 # like `type`. 860 local ADB=$(command which adb) 861 if [ -z "$ADB" ]; then 862 echo "Command adb not found; try lunch (and building) first?" 863 return 1 864 fi 865 run_tool_with_logging "ADB" $ADB "${@}" 866} 867 868function fastboot() { 869 local FASTBOOT=$(command which fastboot) 870 if [ -z "$FASTBOOT" ]; then 871 echo "Command fastboot not found; try lunch (and building) first?" 872 return 1 873 fi 874 # Support tool event logging for fastboot command. 875 run_tool_with_logging "FASTBOOT" $FASTBOOT "${@}" 876} 877 878# communicate with a running device or emulator, set up necessary state, 879# and run the hat command. 880function runhat() 881{ 882 # process standard adb options 883 local adbTarget="" 884 if [ "$1" = "-d" -o "$1" = "-e" ]; then 885 adbTarget=$1 886 shift 1 887 elif [ "$1" = "-s" ]; then 888 adbTarget="$1 $2" 889 shift 2 890 fi 891 local adbOptions=${adbTarget} 892 #echo adbOptions = ${adbOptions} 893 894 # runhat options 895 local targetPid=$1 896 897 if [ "$targetPid" = "" ]; then 898 echo "Usage: runhat [ -d | -e | -s serial ] target-pid" 899 return 900 fi 901 902 # confirm hat is available 903 if [ -z $(which hat) ]; then 904 echo "hat is not available in this configuration." 905 return 906 fi 907 908 # issue "am" command to cause the hprof dump 909 local devFile=/data/local/tmp/hprof-$targetPid 910 echo "Poking $targetPid and waiting for data..." 911 echo "Storing data at $devFile" 912 adb ${adbOptions} shell am dumpheap $targetPid $devFile 913 echo "Press enter when logcat shows \"hprof: heap dump completed\"" 914 echo -n "> " 915 read 916 917 local localFile=/tmp/$$-hprof 918 919 echo "Retrieving file $devFile..." 920 adb ${adbOptions} pull $devFile $localFile 921 922 adb ${adbOptions} shell rm $devFile 923 924 echo "Running hat on $localFile" 925 echo "View the output by pointing your browser at http://localhost:7000/" 926 echo "" 927 hat -JXmx512m $localFile 928} 929 930function godir () { 931 if [[ -z "$1" ]]; then 932 echo "Usage: godir <regex>" 933 return 934 fi 935 local T=$(gettop) 936 local FILELIST 937 if [ ! "$OUT_DIR" = "" ]; then 938 mkdir -p $OUT_DIR 939 FILELIST=$OUT_DIR/filelist 940 else 941 FILELIST=$T/filelist 942 fi 943 if [[ ! -f $FILELIST ]]; then 944 echo -n "Creating index..." 945 (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > $FILELIST) 946 echo " Done" 947 echo "" 948 fi 949 local lines 950 lines=($(\grep "$1" $FILELIST | sed -e 's/\/[^/]*$//' | sort | uniq)) 951 if [[ ${#lines[@]} = 0 ]]; then 952 echo "Not found" 953 return 954 fi 955 local pathname 956 local choice 957 if [[ ${#lines[@]} > 1 ]]; then 958 while [[ -z "$pathname" ]]; do 959 local index=1 960 local line 961 for line in ${lines[@]}; do 962 printf "%6s %s\n" "[$index]" $line 963 index=$(($index + 1)) 964 done 965 echo 966 echo -n "Select one: " 967 unset choice 968 read choice 969 if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then 970 echo "Invalid choice" 971 continue 972 fi 973 pathname=${lines[@]:$(($choice-1)):1} 974 done 975 else 976 pathname=${lines[@]:0:1} 977 fi 978 \cd $T/$pathname 979} 980 981# Go to a specific module in the android tree, as cached in module-info.json. If any build change 982# is made, and it should be reflected in the output, you should run 'refreshmod' first. 983# Note: This function is in envsetup because changing the directory needs to happen in the current 984# shell. All other functions that use module-info.json should be in build/soong/bin. 985function gomod() { 986 if [[ $# -ne 1 ]]; then 987 echo "usage: gomod <module>" >&2 988 return 1 989 fi 990 991 local path="$(pathmod $@)" 992 if [ -z "$path" ]; then 993 return 1 994 fi 995 cd $path 996} 997 998function _complete_android_module_names() { 999 local word=${COMP_WORDS[COMP_CWORD]} 1000 COMPREPLY=( $(allmod | grep -E "^$word") ) 1001} 1002 1003function get_make_command() 1004{ 1005 # If we're in the top of an Android tree, use soong_ui.bash instead of make 1006 if [ -f build/soong/soong_ui.bash ]; then 1007 # Always use the real make if -C is passed in 1008 for arg in "$@"; do 1009 if [[ $arg == -C* ]]; then 1010 echo command make 1011 return 1012 fi 1013 done 1014 echo build/soong/soong_ui.bash --make-mode 1015 else 1016 echo command make 1017 fi 1018} 1019 1020function make() 1021{ 1022 _wrap_build $(get_make_command "$@") "$@" 1023} 1024 1025# Zsh needs bashcompinit called to support bash-style completion. 1026function enable_zsh_completion() { 1027 # Don't override user's options if bash-style completion is already enabled. 1028 if ! declare -f complete >/dev/null; then 1029 autoload -U compinit && compinit 1030 autoload -U bashcompinit && bashcompinit 1031 fi 1032} 1033 1034function validate_current_shell() { 1035 local current_sh="$(ps -o command -p $$)" 1036 case "$current_sh" in 1037 *bash*) 1038 function check_type() { type -t "$1"; } 1039 ;; 1040 *zsh*) 1041 function check_type() { type "$1"; } 1042 enable_zsh_completion ;; 1043 *) 1044 echo -e "WARNING: Only bash and zsh are supported.\nUse of other shell would lead to erroneous results." 1045 ;; 1046 esac 1047} 1048 1049# Execute the contents of any vendorsetup.sh files we can find. 1050# Unless we find an allowed-vendorsetup_sh-files file, in which case we'll only 1051# load those. 1052# 1053# This allows loading only approved vendorsetup.sh files 1054function source_vendorsetup() { 1055 unset VENDOR_PYTHONPATH 1056 local T="$(gettop)" 1057 allowed= 1058 for f in $(cd "$T" && find -L device vendor product -maxdepth 4 -name 'allowed-vendorsetup_sh-files' 2>/dev/null | sort); do 1059 if [ -n "$allowed" ]; then 1060 echo "More than one 'allowed_vendorsetup_sh-files' file found, not including any vendorsetup.sh files:" 1061 echo " $allowed" 1062 echo " $f" 1063 return 1064 fi 1065 allowed="$T/$f" 1066 done 1067 1068 allowed_files= 1069 [ -n "$allowed" ] && allowed_files=$(cat "$allowed") 1070 for dir in device vendor product; do 1071 for f in $(cd "$T" && test -d $dir && \ 1072 find -L $dir -maxdepth 4 -name 'vendorsetup.sh' 2>/dev/null | sort); do 1073 1074 if [[ -z "$allowed" || "$allowed_files" =~ $f ]]; then 1075 echo "including $f"; . "$T/$f" 1076 else 1077 echo "ignoring $f, not in $allowed" 1078 fi 1079 done 1080 done 1081 1082 if [[ "${PWD}" == /google/cog/* ]]; then 1083 f="build/make/cogsetup.sh" 1084 echo "including $f"; . "$T/$f" 1085 fi 1086} 1087 1088function showcommands() { 1089 local T=$(gettop) 1090 if [[ -z "$TARGET_PRODUCT" ]]; then 1091 >&2 echo "TARGET_PRODUCT not set. Run lunch." 1092 return 1093 fi 1094 case $(uname -s) in 1095 Darwin) 1096 PREBUILT_NAME=darwin-x86 1097 ;; 1098 Linux) 1099 PREBUILT_NAME=linux-x86 1100 ;; 1101 *) 1102 >&2 echo Unknown host $(uname -s) 1103 return 1104 ;; 1105 esac 1106 OUT_DIR="$(_get_abs_build_var_cached OUT_DIR)" 1107 if [[ "$1" == "--regenerate" ]]; then 1108 shift 1 1109 NINJA_ARGS="-t commands $@" m 1110 else 1111 (cd $T && prebuilts/build-tools/$PREBUILT_NAME/bin/ninja \ 1112 -f $OUT_DIR/combined-${TARGET_PRODUCT}.ninja \ 1113 -t commands "$@") 1114 fi 1115} 1116 1117# These functions used to be here but are now standalone scripts 1118# in build/soong/bin. Unset these for the time being so the real 1119# script is picked up. 1120# TODO: Remove this some time after a suitable delay (maybe 2025?) 1121unset allmod 1122unset aninja 1123unset cgrep 1124unset core 1125unset coredump_enable 1126unset coredump_setup 1127unset dirmods 1128unset get_build_var 1129unset get_abs_build_var 1130unset getlastscreenshot 1131unset getprebuilt 1132unset getscreenshotpath 1133unset getsdcardpath 1134unset gettargetarch 1135unset ggrep 1136unset gogrep 1137unset hmm 1138unset installmod 1139unset is64bit 1140unset isviewserverstarted 1141unset jgrep 1142unset jsongrep 1143unset key_back 1144unset key_home 1145unset key_menu 1146unset ktgrep 1147unset m 1148unset mangrep 1149unset mgrep 1150unset mm 1151unset mma 1152unset mmm 1153unset mmma 1154unset outmod 1155unset overrideflags 1156unset owngrep 1157unset pathmod 1158unset pez 1159unset pygrep 1160unset qpid 1161unset rcgrep 1162unset refreshmod 1163unset resgrep 1164unset rsgrep 1165unset run_tool_with_logging 1166unset sepgrep 1167unset sgrep 1168unset startviewserver 1169unset stopviewserver 1170unset systemstack 1171unset syswrite 1172unset tomlgrep 1173unset treegrep 1174 1175 1176validate_current_shell 1177set_global_paths 1178source_vendorsetup 1179addcompletions 1180 1181 1182