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 ) 366 # Completion can be disabled selectively to allow users to use non-standard completion. 367 # e.g. 368 # ENVSETUP_NO_COMPLETION=adb # -> disable adb completion 369 # ENVSETUP_NO_COMPLETION=adb:bit # -> disable adb and bit completion 370 local T=$(gettop) 371 for f in ${completion_files[*]}; do 372 f="$T/$f" 373 if [ ! -f "$f" ]; then 374 echo "Warning: completion file $f not found" 375 elif should_add_completion "$f"; then 376 . $f 377 fi 378 done 379 380 if [ -z "$ZSH_VERSION" ]; then 381 # Doesn't work in zsh. 382 complete -o nospace -F _croot croot 383 # TODO(b/244559459): Support b autocompletion for zsh 384 complete -F _bazel__complete -o nospace b 385 fi 386 complete -F _lunch lunch 387 complete -F _lunch_completion lunch2 388 389 complete -F _complete_android_module_names pathmod 390 complete -F _complete_android_module_names gomod 391 complete -F _complete_android_module_names outmod 392 complete -F _complete_android_module_names installmod 393 complete -F _complete_android_module_names m 394} 395 396function add_lunch_combo() 397{ 398 if [ -n "$ZSH_VERSION" ]; then 399 echo -n "${funcfiletrace[1]}: " 400 else 401 echo -n "${BASH_SOURCE[1]}:${BASH_LINENO[0]}: " 402 fi 403 echo "add_lunch_combo is obsolete. Use COMMON_LUNCH_CHOICES in your AndroidProducts.mk instead." 404} 405 406function print_lunch_menu() 407{ 408 local uname=$(uname) 409 local choices 410 choices=$(TARGET_BUILD_APPS= TARGET_PRODUCT= TARGET_RELEASE= TARGET_BUILD_VARIANT= _get_build_var_cached COMMON_LUNCH_CHOICES 2>/dev/null) 411 local ret=$? 412 413 echo 414 echo "You're building on" $uname 415 echo 416 417 if [ $ret -ne 0 ] 418 then 419 echo "Warning: Cannot display lunch menu." 420 echo 421 echo "Note: You can invoke lunch with an explicit target:" 422 echo 423 echo " usage: lunch [target]" >&2 424 echo 425 return 426 fi 427 428 echo "Lunch menu .. Here are the common combinations:" 429 430 local i=1 431 local choice 432 for choice in $(echo $choices) 433 do 434 echo " $i. $choice" 435 i=$(($i+1)) 436 done 437 438 echo 439} 440 441function _lunch_meat() 442{ 443 local product=$1 444 local release=$2 445 local variant=$3 446 447 TARGET_PRODUCT=$product \ 448 TARGET_RELEASE=$release \ 449 TARGET_BUILD_VARIANT=$variant \ 450 build_build_var_cache 451 if [ $? -ne 0 ] 452 then 453 if [[ "$product" =~ .*_(eng|user|userdebug) ]] 454 then 455 echo "Did you mean -${product/*_/}? (dash instead of underscore)" 456 fi 457 return 1 458 fi 459 export TARGET_PRODUCT=$(_get_build_var_cached TARGET_PRODUCT) 460 export TARGET_BUILD_VARIANT=$(_get_build_var_cached TARGET_BUILD_VARIANT) 461 export TARGET_RELEASE=$release 462 # Note this is the string "release", not the value of the variable. 463 export TARGET_BUILD_TYPE=release 464 465 [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || echo 466 467 set_stuff_for_environment 468 [[ -n "${ANDROID_QUIET_BUILD:-}" ]] || printconfig 469 470 if [[ -z "${ANDROID_QUIET_BUILD}" ]]; then 471 local spam_for_lunch=$(gettop)/build/make/tools/envsetup/spam_for_lunch 472 if [[ -x $spam_for_lunch ]]; then 473 $spam_for_lunch 474 fi 475 fi 476 477 destroy_build_var_cache 478 479 if [[ -n "${CHECK_MU_CONFIG:-}" ]]; then 480 check_mu_config 481 fi 482} 483 484unset COMMON_LUNCH_CHOICES_CACHE 485# Tab completion for lunch. 486function _lunch() 487{ 488 local cur prev opts 489 COMPREPLY=() 490 cur="${COMP_WORDS[COMP_CWORD]}" 491 prev="${COMP_WORDS[COMP_CWORD-1]}" 492 493 if [ -z "$COMMON_LUNCH_CHOICES_CACHE" ]; then 494 COMMON_LUNCH_CHOICES_CACHE=$(TARGET_BUILD_APPS= _get_build_var_cached COMMON_LUNCH_CHOICES) 495 fi 496 497 COMPREPLY=( $(compgen -W "${COMMON_LUNCH_CHOICES_CACHE}" -- ${cur}) ) 498 return 0 499} 500 501function _lunch_usage() 502{ 503 ( 504 echo "The lunch command selects the configuration to use for subsequent" 505 echo "Android builds." 506 echo 507 echo "Usage: lunch TARGET_PRODUCT [TARGET_RELEASE [TARGET_BUILD_VARIANT]]" 508 echo 509 echo " Choose the product, release and variant to use. If not" 510 echo " supplied, TARGET_RELEASE will be 'trunk_staging' and" 511 echo " TARGET_BUILD_VARIANT will be 'eng'" 512 echo 513 echo 514 echo "Usage: lunch TARGET_PRODUCT-TARGET_RELEASE-TARGET_BUILD_VARIANT" 515 echo 516 echo " Chose the product, release and variant to use. This" 517 echo " legacy format is maintained for compatibility." 518 echo 519 echo 520 echo "Note that the previous interactive menu and list of hard-coded" 521 echo "list of curated targets has been removed. If you would like the" 522 echo "list of products, release configs for a particular product, or" 523 echo "variants, run list_products list_releases or list_variants" 524 echo "respectively." 525 echo 526 ) 1>&2 527} 528 529function lunch() 530{ 531 if [[ $# -eq 1 && $1 = "--help" ]]; then 532 _lunch_usage 533 return 0 534 fi 535 if [[ $# -eq 0 ]]; then 536 echo "No target specified. See lunch --help" 1>&2 537 return 1 538 fi 539 if [[ $# -gt 3 ]]; then 540 echo "Too many parameters given. See lunch --help" 1>&2 541 return 1 542 fi 543 544 local product release variant 545 546 # Handle the legacy format 547 local legacy=$(echo $1 | grep "-") 548 if [[ $# -eq 1 && -n $legacy ]]; then 549 IFS="-" read -r product release variant <<< "$1" 550 if [[ -z "$product" ]] || [[ -z "$release" ]] || [[ -z "$variant" ]]; then 551 echo "Invalid lunch combo: $1" 1>&2 552 echo "Valid combos must be of the form <product>-<release>-<variant> when using" 1>&2 553 echo "the legacy format. Run 'lunch --help' for usage." 1>&2 554 return 1 555 fi 556 fi 557 558 # Handle the new format. 559 if [[ -z $legacy ]]; then 560 product=$1 561 release=$2 562 if [[ -z $release ]]; then 563 release=trunk_staging 564 fi 565 variant=$3 566 if [[ -z $variant ]]; then 567 variant=eng 568 fi 569 fi 570 571 # Validate the selection and set all the environment stuff 572 _lunch_meat $product $release $variant 573} 574 575unset ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE 576unset ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT 577unset ANDROID_LUNCH_COMPLETION_RELEASE_CACHE 578# Tab completion for lunch. 579function _lunch_completion() 580{ 581 # Available products 582 if [[ $COMP_CWORD -eq 1 ]] ; then 583 if [[ -z $ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE ]]; then 584 ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE=$(list_products) 585 fi 586 COMPREPLY=( $(compgen -W "${ANDROID_LUNCH_COMPLETION_PRODUCT_CACHE}" -- "${COMP_WORDS[COMP_CWORD]}") ) 587 fi 588 589 # Available release configs 590 if [[ $COMP_CWORD -eq 2 ]] ; then 591 if [[ -z $ANDROID_LUNCH_COMPLETION_RELEASE_CACHE || $ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT != ${COMP_WORDS[1]} ]] ; then 592 ANDROID_LUNCH_COMPLETION_RELEASE_CACHE=$(list_releases ${COMP_WORDS[1]}) 593 ANDROID_LUNCH_COMPLETION_CHOSEN_PRODUCT=${COMP_WORDS[1]} 594 fi 595 COMPREPLY=( $(compgen -W "${ANDROID_LUNCH_COMPLETION_RELEASE_CACHE}" -- "${COMP_WORDS[COMP_CWORD]}") ) 596 fi 597 598 # Available variants 599 if [[ $COMP_CWORD -eq 3 ]] ; then 600 COMPREPLY=(user userdebug eng) 601 fi 602 603 return 0 604} 605 606 607# Configures the build to build unbundled apps. 608# Run tapas with one or more app names (from LOCAL_PACKAGE_NAME) 609function tapas() 610{ 611 local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)" 612 local arch="$(echo $* | xargs -n 1 echo | \grep -E '^(arm|x86|arm64|x86_64)$' | xargs)" 613 # TODO(b/307975293): Expand tapas to take release arguments (and update hmm() usage). 614 local release="trunk_staging" 615 local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)" 616 local density="$(echo $* | xargs -n 1 echo | \grep -E '^(ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|alldpi)$' | xargs)" 617 local keys="$(echo $* | xargs -n 1 echo | \grep -E '^(devkeys)$' | xargs)" 618 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)" 619 620 621 if [ "$showHelp" != "" ]; then 622 $(gettop)/build/make/tapasHelp.sh 623 return 624 fi 625 626 if [ $(echo $arch | wc -w) -gt 1 ]; then 627 echo "tapas: Error: Multiple build archs supplied: $arch" 628 return 629 fi 630 if [ $(echo $release | wc -w) -gt 1 ]; then 631 echo "tapas: Error: Multiple build releases supplied: $release" 632 return 633 fi 634 if [ $(echo $variant | wc -w) -gt 1 ]; then 635 echo "tapas: Error: Multiple build variants supplied: $variant" 636 return 637 fi 638 if [ $(echo $density | wc -w) -gt 1 ]; then 639 echo "tapas: Error: Multiple densities supplied: $density" 640 return 641 fi 642 if [ $(echo $keys | wc -w) -gt 1 ]; then 643 echo "tapas: Error: Multiple keys supplied: $keys" 644 return 645 fi 646 647 local product=aosp_arm 648 case $arch in 649 x86) product=aosp_x86;; 650 arm64) product=aosp_arm64;; 651 x86_64) product=aosp_x86_64;; 652 esac 653 if [ -n "$keys" ]; then 654 product=${product/aosp_/aosp_${keys}_} 655 fi; 656 657 if [ -z "$variant" ]; then 658 variant=eng 659 fi 660 if [ -z "$apps" ]; then 661 apps=all 662 fi 663 if [ -z "$density" ]; then 664 density=alldpi 665 fi 666 667 export TARGET_PRODUCT=$product 668 export TARGET_RELEASE=$release 669 export TARGET_BUILD_VARIANT=$variant 670 export TARGET_BUILD_DENSITY=$density 671 export TARGET_BUILD_TYPE=release 672 export TARGET_BUILD_APPS=$apps 673 674 build_build_var_cache 675 set_stuff_for_environment 676 printconfig 677 destroy_build_var_cache 678} 679 680# Configures the build to build unbundled Android modules (APEXes). 681# Run banchan with one or more module names (from apex{} modules). 682function banchan() 683{ 684 local showHelp="$(echo $* | xargs -n 1 echo | \grep -E '^(help)$' | xargs)" 685 local product="$(echo $* | xargs -n 1 echo | \grep -E '^(.*_)?(arm|x86|arm64|riscv64|x86_64|arm64only|x86_64only)$' | xargs)" 686 # TODO: Expand banchan to take release arguments (and update hmm() usage). 687 local release="trunk_staging" 688 local variant="$(echo $* | xargs -n 1 echo | \grep -E '^(user|userdebug|eng)$' | xargs)" 689 local apps="$(echo $* | xargs -n 1 echo | \grep -E -v '^(user|userdebug|eng|(.*_)?(arm|x86|arm64|riscv64|x86_64))$' | xargs)" 690 691 if [ "$showHelp" != "" ]; then 692 $(gettop)/build/make/banchanHelp.sh 693 return 694 fi 695 696 if [ -z "$product" ]; then 697 product=arm64 698 elif [ $(echo $product | wc -w) -gt 1 ]; then 699 echo "banchan: Error: Multiple build archs or products supplied: $products" 700 return 701 fi 702 if [ $(echo $release | wc -w) -gt 1 ]; then 703 echo "banchan: Error: Multiple build releases supplied: $release" 704 return 705 fi 706 if [ $(echo $variant | wc -w) -gt 1 ]; then 707 echo "banchan: Error: Multiple build variants supplied: $variant" 708 return 709 fi 710 if [ -z "$apps" ]; then 711 echo "banchan: Error: No modules supplied" 712 return 713 fi 714 715 case $product in 716 arm) product=module_arm;; 717 x86) product=module_x86;; 718 arm64) product=module_arm64;; 719 riscv64) product=module_riscv64;; 720 x86_64) product=module_x86_64;; 721 arm64only) product=module_arm64only;; 722 x86_64only) product=module_x86_64only;; 723 esac 724 if [ -z "$variant" ]; then 725 variant=eng 726 fi 727 728 export TARGET_PRODUCT=$product 729 export TARGET_RELEASE=$release 730 export TARGET_BUILD_VARIANT=$variant 731 export TARGET_BUILD_DENSITY=alldpi 732 export TARGET_BUILD_TYPE=release 733 734 # This setup currently uses TARGET_BUILD_APPS just like tapas, but the use 735 # case is different and it may diverge in the future. 736 export TARGET_BUILD_APPS=$apps 737 738 build_build_var_cache 739 set_stuff_for_environment 740 printconfig 741 destroy_build_var_cache 742} 743 744function croot() 745{ 746 local T=$(gettop) 747 if [ "$T" ]; then 748 if [ "$1" ]; then 749 \cd $(gettop)/$1 750 else 751 \cd $(gettop) 752 fi 753 else 754 echo "Couldn't locate the top of the tree. Try setting TOP." 755 fi 756} 757 758function _croot() 759{ 760 local T=$(gettop) 761 if [ "$T" ]; then 762 local cur="${COMP_WORDS[COMP_CWORD]}" 763 k=0 764 for c in $(compgen -d ${T}/${cur}); do 765 COMPREPLY[k++]=${c#${T}/}/ 766 done 767 fi 768} 769 770function cproj() 771{ 772 local TOPFILE=build/make/core/envsetup.mk 773 local HERE=$PWD 774 local T= 775 while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do 776 T=$PWD 777 if [ -f "$T/Android.mk" ]; then 778 \cd $T 779 return 780 fi 781 \cd .. 782 done 783 \cd $HERE 784 echo "can't find Android.mk" 785} 786 787# Ensure that we're always using the adb in the tree. This works around the fact 788# that bash caches $PATH lookups, so if you use adb before lunching/building the 789# one in your tree, you'll continue to get /usr/bin/adb or whatever even after 790# you have the one from your current tree on your path. Historically this would 791# cause confusion because glinux had adb in /usr/bin/ by default, though that 792# doesn't appear to be the case on my rodete hosts; it is however still the case 793# that my Mac has /usr/local/bin/adb installed by default and on the default 794# path. 795function adb() { 796 # We need `command which` because zsh has a built-in `which` that's more 797 # like `type`. 798 local ADB=$(command which adb) 799 if [ -z "$ADB" ]; then 800 echo "Command adb not found; try lunch (and building) first?" 801 return 1 802 fi 803 run_tool_with_logging "ADB" $ADB "${@}" 804} 805 806function fastboot() { 807 local FASTBOOT=$(command which fastboot) 808 if [ -z "$FASTBOOT" ]; then 809 echo "Command fastboot not found; try lunch (and building) first?" 810 return 1 811 fi 812 # Support tool event logging for fastboot command. 813 run_tool_with_logging "FASTBOOT" $FASTBOOT "${@}" 814} 815 816# communicate with a running device or emulator, set up necessary state, 817# and run the hat command. 818function runhat() 819{ 820 # process standard adb options 821 local adbTarget="" 822 if [ "$1" = "-d" -o "$1" = "-e" ]; then 823 adbTarget=$1 824 shift 1 825 elif [ "$1" = "-s" ]; then 826 adbTarget="$1 $2" 827 shift 2 828 fi 829 local adbOptions=${adbTarget} 830 #echo adbOptions = ${adbOptions} 831 832 # runhat options 833 local targetPid=$1 834 835 if [ "$targetPid" = "" ]; then 836 echo "Usage: runhat [ -d | -e | -s serial ] target-pid" 837 return 838 fi 839 840 # confirm hat is available 841 if [ -z $(which hat) ]; then 842 echo "hat is not available in this configuration." 843 return 844 fi 845 846 # issue "am" command to cause the hprof dump 847 local devFile=/data/local/tmp/hprof-$targetPid 848 echo "Poking $targetPid and waiting for data..." 849 echo "Storing data at $devFile" 850 adb ${adbOptions} shell am dumpheap $targetPid $devFile 851 echo "Press enter when logcat shows \"hprof: heap dump completed\"" 852 echo -n "> " 853 read 854 855 local localFile=/tmp/$$-hprof 856 857 echo "Retrieving file $devFile..." 858 adb ${adbOptions} pull $devFile $localFile 859 860 adb ${adbOptions} shell rm $devFile 861 862 echo "Running hat on $localFile" 863 echo "View the output by pointing your browser at http://localhost:7000/" 864 echo "" 865 hat -JXmx512m $localFile 866} 867 868function godir () { 869 if [[ -z "$1" ]]; then 870 echo "Usage: godir <regex>" 871 return 872 fi 873 local T=$(gettop) 874 local FILELIST 875 if [ ! "$OUT_DIR" = "" ]; then 876 mkdir -p $OUT_DIR 877 FILELIST=$OUT_DIR/filelist 878 else 879 FILELIST=$T/filelist 880 fi 881 if [[ ! -f $FILELIST ]]; then 882 echo -n "Creating index..." 883 (\cd $T; find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > $FILELIST) 884 echo " Done" 885 echo "" 886 fi 887 local lines 888 lines=($(\grep "$1" $FILELIST | sed -e 's/\/[^/]*$//' | sort | uniq)) 889 if [[ ${#lines[@]} = 0 ]]; then 890 echo "Not found" 891 return 892 fi 893 local pathname 894 local choice 895 if [[ ${#lines[@]} > 1 ]]; then 896 while [[ -z "$pathname" ]]; do 897 local index=1 898 local line 899 for line in ${lines[@]}; do 900 printf "%6s %s\n" "[$index]" $line 901 index=$(($index + 1)) 902 done 903 echo 904 echo -n "Select one: " 905 unset choice 906 read choice 907 if [[ $choice -gt ${#lines[@]} || $choice -lt 1 ]]; then 908 echo "Invalid choice" 909 continue 910 fi 911 pathname=${lines[@]:$(($choice-1)):1} 912 done 913 else 914 pathname=${lines[@]:0:1} 915 fi 916 \cd $T/$pathname 917} 918 919# Go to a specific module in the android tree, as cached in module-info.json. If any build change 920# is made, and it should be reflected in the output, you should run 'refreshmod' first. 921# Note: This function is in envsetup because changing the directory needs to happen in the current 922# shell. All other functions that use module-info.json should be in build/soong/bin. 923function gomod() { 924 if [[ $# -ne 1 ]]; then 925 echo "usage: gomod <module>" >&2 926 return 1 927 fi 928 929 local path="$(pathmod $@)" 930 if [ -z "$path" ]; then 931 return 1 932 fi 933 cd $path 934} 935 936function _complete_android_module_names() { 937 local word=${COMP_WORDS[COMP_CWORD]} 938 COMPREPLY=( $(allmod | grep -E "^$word") ) 939} 940 941function get_make_command() 942{ 943 # If we're in the top of an Android tree, use soong_ui.bash instead of make 944 if [ -f build/soong/soong_ui.bash ]; then 945 # Always use the real make if -C is passed in 946 for arg in "$@"; do 947 if [[ $arg == -C* ]]; then 948 echo command make 949 return 950 fi 951 done 952 echo build/soong/soong_ui.bash --make-mode 953 else 954 echo command make 955 fi 956} 957 958function make() 959{ 960 _wrap_build $(get_make_command "$@") "$@" 961} 962 963# Zsh needs bashcompinit called to support bash-style completion. 964function enable_zsh_completion() { 965 # Don't override user's options if bash-style completion is already enabled. 966 if ! declare -f complete >/dev/null; then 967 autoload -U compinit && compinit 968 autoload -U bashcompinit && bashcompinit 969 fi 970} 971 972function validate_current_shell() { 973 local current_sh="$(ps -o command -p $$)" 974 case "$current_sh" in 975 *bash*) 976 function check_type() { type -t "$1"; } 977 ;; 978 *zsh*) 979 function check_type() { type "$1"; } 980 enable_zsh_completion ;; 981 *) 982 echo -e "WARNING: Only bash and zsh are supported.\nUse of other shell would lead to erroneous results." 983 ;; 984 esac 985} 986 987# Execute the contents of any vendorsetup.sh files we can find. 988# Unless we find an allowed-vendorsetup_sh-files file, in which case we'll only 989# load those. 990# 991# This allows loading only approved vendorsetup.sh files 992function source_vendorsetup() { 993 unset VENDOR_PYTHONPATH 994 local T="$(gettop)" 995 allowed= 996 for f in $(cd "$T" && find -L device vendor product -maxdepth 4 -name 'allowed-vendorsetup_sh-files' 2>/dev/null | sort); do 997 if [ -n "$allowed" ]; then 998 echo "More than one 'allowed_vendorsetup_sh-files' file found, not including any vendorsetup.sh files:" 999 echo " $allowed" 1000 echo " $f" 1001 return 1002 fi 1003 allowed="$T/$f" 1004 done 1005 1006 allowed_files= 1007 [ -n "$allowed" ] && allowed_files=$(cat "$allowed") 1008 for dir in device vendor product; do 1009 for f in $(cd "$T" && test -d $dir && \ 1010 find -L $dir -maxdepth 4 -name 'vendorsetup.sh' 2>/dev/null | sort); do 1011 1012 if [[ -z "$allowed" || "$allowed_files" =~ $f ]]; then 1013 echo "including $f"; . "$T/$f" 1014 else 1015 echo "ignoring $f, not in $allowed" 1016 fi 1017 done 1018 done 1019 1020 setup_cog_env_if_needed 1021} 1022 1023function showcommands() { 1024 local T=$(gettop) 1025 if [[ -z "$TARGET_PRODUCT" ]]; then 1026 >&2 echo "TARGET_PRODUCT not set. Run lunch." 1027 return 1028 fi 1029 case $(uname -s) in 1030 Darwin) 1031 PREBUILT_NAME=darwin-x86 1032 ;; 1033 Linux) 1034 PREBUILT_NAME=linux-x86 1035 ;; 1036 *) 1037 >&2 echo Unknown host $(uname -s) 1038 return 1039 ;; 1040 esac 1041 OUT_DIR="$(_get_abs_build_var_cached OUT_DIR)" 1042 if [[ "$1" == "--regenerate" ]]; then 1043 shift 1 1044 NINJA_ARGS="-t commands $@" m 1045 else 1046 (cd $T && prebuilts/build-tools/$PREBUILT_NAME/bin/ninja \ 1047 -f $OUT_DIR/combined-${TARGET_PRODUCT}.ninja \ 1048 -t commands "$@") 1049 fi 1050} 1051 1052# These functions used to be here but are now standalone scripts 1053# in build/soong/bin. Unset these for the time being so the real 1054# script is picked up. 1055# TODO: Remove this some time after a suitable delay (maybe 2025?) 1056unset allmod 1057unset aninja 1058unset cgrep 1059unset core 1060unset coredump_enable 1061unset coredump_setup 1062unset dirmods 1063unset get_build_var 1064unset get_abs_build_var 1065unset getlastscreenshot 1066unset getprebuilt 1067unset getscreenshotpath 1068unset getsdcardpath 1069unset gettargetarch 1070unset ggrep 1071unset gogrep 1072unset hmm 1073unset installmod 1074unset is64bit 1075unset isviewserverstarted 1076unset jgrep 1077unset jsongrep 1078unset key_back 1079unset key_home 1080unset key_menu 1081unset ktgrep 1082unset m 1083unset mangrep 1084unset mgrep 1085unset mm 1086unset mma 1087unset mmm 1088unset mmma 1089unset outmod 1090unset overrideflags 1091unset owngrep 1092unset pathmod 1093unset pez 1094unset pygrep 1095unset qpid 1096unset rcgrep 1097unset refreshmod 1098unset resgrep 1099unset rsgrep 1100unset run_tool_with_logging 1101unset sepgrep 1102unset sgrep 1103unset startviewserver 1104unset stopviewserver 1105unset systemstack 1106unset syswrite 1107unset tomlgrep 1108unset treegrep 1109 1110 1111validate_current_shell 1112set_global_paths 1113source_vendorsetup 1114addcompletions 1115 1116 1117