Home | History | Annotate | Download | only in tools
      1 # Common functions for all prebuilt-related scripts
      2 # This is included/sourced by other scripts
      3 #
      4 
      5 # ensure stable sort order
      6 export LC_ALL=C
      7 
      8 # NDK_BUILDTOOLS_PATH should point to the directory containing
      9 # this script. If it is not defined, assume that this is one of
     10 # the scripts in the same directory that sourced this file.
     11 #
     12 if [ -z "$NDK_BUILDTOOLS_PATH" ]; then
     13     NDK_BUILDTOOLS_PATH=$(dirname $0)
     14     if [ ! -f "$NDK_BUILDTOOLS_PATH/prebuilt-common.sh" ]; then
     15         echo "INTERNAL ERROR: Please define NDK_BUILDTOOLS_PATH to point to \$NDK/build/tools"
     16         exit 1
     17     fi
     18 fi
     19 
     20 # Warn if /bin/sh isn't bash.
     21 if [ -z "$BASH_VERSION" ] ; then
     22     echo "WARNING: The shell running this script isn't bash.  Although we try to avoid bashism in scripts, things can happen."
     23 fi
     24 
     25 NDK_BUILDTOOLS_ABSPATH=$(cd $NDK_BUILDTOOLS_PATH && pwd)
     26 
     27 . $NDK_BUILDTOOLS_PATH/ndk-common.sh
     28 . $NDK_BUILDTOOLS_PATH/dev-defaults.sh
     29 
     30 
     31 # Given an input string of the form <foo>-<bar>-<version>, where
     32 # <version> can be <major>.<minor>, extract <major>
     33 extract_version ()
     34 {
     35     echo $1 | tr '-' '\n' | tail -1
     36 }
     37 
     38 # $1: versioned name (e.g. arm-linux-androideabi-4.8)
     39 # Out: major version (e.g. 4)
     40 #
     41 # Examples:  arm-linux-androideabi-4.4.3 -> 4
     42 #            gmp-0.81 -> 0
     43 #
     44 extract_major_version ()
     45 {
     46     local RET=$(extract_version $1 | cut -d . -f 1)
     47     RET=${RET:-0}
     48     echo $RET
     49 }
     50 
     51 # Same as extract_major_version, but for the minor version number
     52 # $1: versioned named
     53 # Out: minor version
     54 #
     55 extract_minor_version ()
     56 {
     57     local RET=$(extract_version $1 | cut -d . -f 2)
     58     RET=${RET:-0}
     59     echo $RET
     60 }
     61 
     62 # Compare two version numbers and only succeeds if the first one is
     63 # greater than or equal to the second one.
     64 #
     65 # $1: first version (e.g. 4.9)
     66 # $2: second version (e.g. 4.8)
     67 #
     68 # Example: version_is_at_least 4.9 4.8 --> success
     69 #
     70 version_is_at_least ()
     71 {
     72     local A_MAJOR A_MINOR B_MAJOR B_MINOR
     73     A_MAJOR=$(extract_major_version $1)
     74     B_MAJOR=$(extract_major_version $2)
     75 
     76     if [ $A_MAJOR -lt $B_MAJOR ]; then
     77         return 1
     78     elif [ $A_MAJOR -gt $B_MAJOR ]; then
     79         return 0
     80     fi
     81 
     82     # We have A_MAJOR == B_MAJOR here
     83 
     84     A_MINOR=$(extract_minor_version $1)
     85     B_MINOR=$(extract_minor_version $2)
     86 
     87     if [ $A_MINOR -lt $B_MINOR ]; then
     88         return 1
     89     else
     90         return 0
     91     fi
     92 }
     93 
     94 #====================================================
     95 #
     96 #  UTILITY FUNCTIONS
     97 #
     98 #====================================================
     99 
    100 # Return the maximum length of a series of strings
    101 #
    102 # Usage:  len=`max_length <string1> <string2> ...`
    103 #
    104 max_length ()
    105 {
    106     echo "$@" | tr ' ' '\n' | awk 'BEGIN {max=0} {len=length($1); if (len > max) max=len} END {print max}'
    107 }
    108 
    109 # Translate dashes to underscores
    110 # Usage:  str=`dashes_to_underscores <values>`
    111 dashes_to_underscores ()
    112 {
    113     echo "$@" | tr '-' '_'
    114 }
    115 
    116 # Translate underscores to dashes
    117 # Usage: str=`underscores_to_dashes <values>`
    118 underscores_to_dashes ()
    119 {
    120     echo "$@" | tr '_' '-'
    121 }
    122 
    123 # Translate commas to spaces
    124 # Usage: str=`commas_to_spaces <list>`
    125 commas_to_spaces ()
    126 {
    127     echo "$@" | tr ',' ' '
    128 }
    129 
    130 # Translate spaces to commas
    131 # Usage: list=`spaces_to_commas <string>`
    132 spaces_to_commas ()
    133 {
    134     echo "$@" | tr ' ' ','
    135 }
    136 
    137 # Remove trailing path of a path
    138 # $1: path
    139 remove_trailing_slash () {
    140     echo ${1%%/}
    141 }
    142 
    143 # Reverse a file path directory
    144 # foo -> .
    145 # foo/bar -> ..
    146 # foo/bar/zoo -> ../..
    147 reverse_path ()
    148 {
    149     local path cur item
    150     path=${1%%/} # remove trailing slash
    151     cur="."
    152     if [ "$path" != "." ] ; then
    153         for item in $(echo "$path" | tr '/' ' '); do
    154             cur="../$cur"
    155         done
    156     fi
    157     echo ${cur%%/.}
    158 }
    159 
    160 # test_reverse_path ()
    161 # {
    162 #     rr=`reverse_path $1`
    163 #     if [ "$rr" != "$2" ] ; then
    164 #         echo "ERROR: reverse_path '$1' -> '$rr' (expected '$2')"
    165 #     fi
    166 # }
    167 #
    168 # test_reverse_path . .
    169 # test_reverse_path ./ .
    170 # test_reverse_path foo ..
    171 # test_reverse_path foo/ ..
    172 # test_reverse_path foo/bar ../..
    173 # test_reverse_path foo/bar/ ../..
    174 # test_reverse_path foo/bar/zoo ../../..
    175 # test_reverse_path foo/bar/zoo/ ../../..
    176 
    177 # Sort a space-separated list and remove duplicates
    178 # $1+: slist
    179 # Output: new slist
    180 sort_uniq ()
    181 {
    182     local RET
    183     RET=$(echo "$@" | tr ' ' '\n' | sort -u)
    184     echo $RET
    185 }
    186 
    187 # Return the list of all regular files under a given directory
    188 # $1: Directory path
    189 # Output: list of files, relative to $1
    190 list_files_under ()
    191 {
    192     if [ -d "$1" ]; then
    193         (cd $1 && find . -type f | sed -e "s!./!!" | sort -u)
    194     else
    195         echo ""
    196     fi
    197 }
    198 
    199 # Returns all words in text that do not match any of the pattern
    200 # $1: pattern
    201 # $2: text
    202 filter_out ()
    203 {
    204     local PATTERN="$1"
    205     local TEXT="$2"
    206     for pat in $PATTERN; do
    207         pat=$"${pat//\//\\/}"
    208         TEXT=$(echo $TEXT | sed -e 's/'$pat' //g' -e 's/'$pat'$//g')
    209     done
    210     echo $TEXT
    211 }
    212 
    213 # Assign a value to a variable
    214 # $1: Variable name
    215 # $2: Value
    216 var_assign ()
    217 {
    218     eval $1=\"$2\"
    219 }
    220 
    221 #====================================================
    222 #
    223 #  OPTION PROCESSING
    224 #
    225 #====================================================
    226 
    227 # We recognize the following option formats:
    228 #
    229 #  -f
    230 #  --flag
    231 #
    232 #  -s<value>
    233 #  --setting=<value>
    234 #
    235 
    236 # NOTE: We translate '-' into '_' when storing the options in global variables
    237 #
    238 
    239 OPTIONS=""
    240 OPTION_FLAGS=""
    241 OPTION_SETTINGS=""
    242 
    243 # Set a given option attribute
    244 # $1: option name
    245 # $2: option attribute
    246 # $3: attribute value
    247 #
    248 option_set_attr ()
    249 {
    250     eval OPTIONS_$1_$2=\"$3\"
    251 }
    252 
    253 # Get a given option attribute
    254 # $1: option name
    255 # $2: option attribute
    256 #
    257 option_get_attr ()
    258 {
    259     echo `var_value OPTIONS_$1_$2`
    260 }
    261 
    262 # Register a new option
    263 # $1: option
    264 # $2: small abstract for the option
    265 # $3: optional. default value
    266 #
    267 register_option_internal ()
    268 {
    269     optlabel=
    270     optname=
    271     optvalue=
    272     opttype=
    273     while [ -n "1" ] ; do
    274         # Check for something like --setting=<value>
    275         echo "$1" | grep -q -E -e '^--[^=]+=<.+>$'
    276         if [ $? = 0 ] ; then
    277             optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'`
    278             optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'`
    279             opttype="long_setting"
    280             break
    281         fi
    282 
    283         # Check for something like --flag
    284         echo "$1" | grep -q -E -e '^--[^=]+$'
    285         if [ $? = 0 ] ; then
    286             optlabel="$1"
    287             opttype="long_flag"
    288             break
    289         fi
    290 
    291         # Check for something like -f<value>
    292         echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$'
    293         if [ $? = 0 ] ; then
    294             optlabel=`expr -- "$1" : '\(-.\).*'`
    295             optvalue=`expr -- "$1" : '-.\(<.+>\)'`
    296             opttype="short_setting"
    297             break
    298         fi
    299 
    300         # Check for something like -f
    301         echo "$1" | grep -q -E -e '^-.$'
    302         if [ $? = 0 ] ; then
    303             optlabel="$1"
    304             opttype="short_flag"
    305             break
    306         fi
    307 
    308         echo "ERROR: Invalid option format: $1"
    309         echo "       Check register_option call"
    310         exit 1
    311     done
    312 
    313     log "new option: type='$opttype' name='$optlabel' value='$optvalue'"
    314 
    315     optname=`dashes_to_underscores $optlabel`
    316     OPTIONS="$OPTIONS $optname"
    317     OPTIONS_TEXT="$OPTIONS_TEXT $1"
    318     option_set_attr $optname label "$optlabel"
    319     option_set_attr $optname otype "$opttype"
    320     option_set_attr $optname value "$optvalue"
    321     option_set_attr $optname text "$1"
    322     option_set_attr $optname abstract "$2"
    323     option_set_attr $optname default "$3"
    324 }
    325 
    326 # Register a new option with a function callback.
    327 #
    328 # $1: option
    329 # $2: name of function that will be called when the option is parsed
    330 # $3: small abstract for the option
    331 # $4: optional. default value
    332 #
    333 register_option ()
    334 {
    335     local optname optvalue opttype optlabel
    336     register_option_internal "$1" "$3" "$4"
    337     option_set_attr $optname funcname "$2"
    338 }
    339 
    340 # Register a new option with a variable store
    341 #
    342 # $1: option
    343 # $2: name of variable that will be set by this option
    344 # $3: small abstract for the option
    345 #
    346 # NOTE: The current value of $2 is used as the default
    347 #
    348 register_var_option ()
    349 {
    350     local optname optvalue opttype optlabel
    351     register_option_internal "$1" "$3" "`var_value $2`"
    352     option_set_attr $optname varname "$2"
    353 }
    354 
    355 
    356 MINGW=no
    357 DARWIN=no
    358 do_mingw_option ()
    359 {
    360     if [ "$DARWIN" = "yes" ]; then
    361         echo "Can not have both --mingw and --darwin"
    362         exit 1
    363     fi
    364     MINGW=yes;
    365 }
    366 do_darwin_option ()
    367 {
    368     if [ "$MINGW" = "yes" ]; then
    369         echo "Can not have both --mingw and --darwin"
    370         exit 1
    371     fi
    372     DARWIN=yes; 
    373 }
    374 
    375 register_canadian_option ()
    376 {
    377     if [ "$HOST_OS" = "linux" ] ; then
    378         register_option "--mingw" do_mingw_option "Generate windows binaries on Linux."
    379         register_option "--darwin" do_darwin_option "Generate darwin binaries on Linux."
    380     fi
    381 }
    382 
    383 TRY64=no
    384 do_try64_option () { TRY64=yes; }
    385 
    386 register_try64_option ()
    387 {
    388     register_option "--try-64" do_try64_option "Generate 64-bit only binaries."
    389 }
    390 
    391 
    392 register_jobs_option ()
    393 {
    394     NUM_JOBS=$BUILD_NUM_CPUS
    395     register_var_option "-j<number>" NUM_JOBS "Use <number> parallel build jobs"
    396 }
    397 
    398 # Print the help, including a list of registered options for this program
    399 # Note: Assumes PROGRAM_PARAMETERS and PROGRAM_DESCRIPTION exist and
    400 #       correspond to the parameters list and the program description
    401 #
    402 print_help ()
    403 {
    404     local opt text abstract default
    405 
    406     echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS"
    407     echo ""
    408     if [ -n "$PROGRAM_DESCRIPTION" ] ; then
    409         echo "$PROGRAM_DESCRIPTION"
    410         echo ""
    411     fi
    412     echo "Valid options (defaults are in brackets):"
    413     echo ""
    414 
    415     maxw=`max_length "$OPTIONS_TEXT"`
    416     AWK_SCRIPT=`echo "{ printf \"%-${maxw}s\", \\$1 }"`
    417     for opt in $OPTIONS; do
    418         text=`option_get_attr $opt text | awk "$AWK_SCRIPT"`
    419         abstract=`option_get_attr $opt abstract`
    420         default=`option_get_attr $opt default`
    421         if [ -n "$default" ] ; then
    422             echo "  $text     $abstract [$default]"
    423         else
    424             echo "  $text     $abstract"
    425         fi
    426     done
    427     echo ""
    428 }
    429 
    430 option_panic_no_args ()
    431 {
    432     echo "ERROR: Option '$1' does not take arguments. See --help for usage."
    433     exit 1
    434 }
    435 
    436 option_panic_missing_arg ()
    437 {
    438     echo "ERROR: Option '$1' requires an argument. See --help for usage."
    439     exit 1
    440 }
    441 
    442 extract_parameters ()
    443 {
    444     local opt optname otype value name fin funcname
    445     PARAMETERS=""
    446     while [ -n "$1" ] ; do
    447         # If the parameter does not begin with a dash
    448         # it is not an option.
    449         param=`expr -- "$1" : '^\([^\-].*\)$'`
    450         if [ -n "$param" ] ; then
    451             if [ -z "$PARAMETERS" ] ; then
    452                 PARAMETERS="$1"
    453             else
    454                 PARAMETERS="$PARAMETERS $1"
    455             fi
    456             shift
    457             continue
    458         fi
    459 
    460         while [ -n "1" ] ; do
    461             # Try to match a long setting, i.e. --option=value
    462             opt=`expr -- "$1" : '^\(--[^=]*\)=.*$'`
    463             if [ -n "$opt" ] ; then
    464                 otype="long_setting"
    465                 value=`expr -- "$1" : '^--[^=]*=\(.*\)$'`
    466                 break
    467             fi
    468 
    469             # Try to match a long flag, i.e. --option
    470             opt=`expr -- "$1" : '^\(--.*\)$'`
    471             if [ -n "$opt" ] ; then
    472                 otype="long_flag"
    473                 value="yes"
    474                 break
    475             fi
    476 
    477             # Try to match a short setting, i.e. -o<value>
    478             opt=`expr -- "$1" : '^\(-[A-Za-z0-9]\)..*$'`
    479             if [ -n "$opt" ] ; then
    480                 otype="short_setting"
    481                 value=`expr -- "$1" : '^-.\(.*\)$'`
    482                 break
    483             fi
    484 
    485             # Try to match a short flag, i.e. -o
    486             opt=`expr -- "$1" : '^\(-.\)$'`
    487             if [ -n "$opt" ] ; then
    488                 otype="short_flag"
    489                 value="yes"
    490                 break
    491             fi
    492 
    493             echo "ERROR: Unknown option '$1'. Use --help for list of valid values."
    494             exit 1
    495         done
    496 
    497         #echo "Found opt='$opt' otype='$otype' value='$value'"
    498 
    499         name=`dashes_to_underscores $opt`
    500         found=0
    501         for xopt in $OPTIONS; do
    502             if [ "$name" != "$xopt" ] ; then
    503                 continue
    504             fi
    505             # Check that the type is correct here
    506             #
    507             # This also allows us to handle -o <value> as -o<value>
    508             #
    509             xotype=`option_get_attr $name otype`
    510             if [ "$otype" != "$xotype" ] ; then
    511                 case "$xotype" in
    512                 "short_flag")
    513                     option_panic_no_args $opt
    514                     ;;
    515                 "short_setting")
    516                     if [ -z "$2" ] ; then
    517                         option_panic_missing_arg $opt
    518                     fi
    519                     value="$2"
    520                     shift
    521                     ;;
    522                 "long_flag")
    523                     option_panic_no_args $opt
    524                     ;;
    525                 "long_setting")
    526                     option_panic_missing_arg $opt
    527                     ;;
    528                 esac
    529             fi
    530             found=1
    531             break
    532             break
    533         done
    534         if [ "$found" = "0" ] ; then
    535             echo "ERROR: Unknown option '$opt'. See --help for usage."
    536             exit 1
    537         fi
    538         # Set variable or launch option-specific function.
    539         varname=`option_get_attr $name varname`
    540         if [ -n "$varname" ] ; then
    541             eval ${varname}=\"$value\"
    542         else
    543             eval `option_get_attr $name funcname` \"$value\"
    544         fi
    545         shift
    546     done
    547 }
    548 
    549 do_option_help ()
    550 {
    551     print_help
    552     exit 0
    553 }
    554 
    555 VERBOSE=no
    556 do_option_verbose ()
    557 {
    558     VERBOSE=yes
    559 }
    560 
    561 DRYRUN=no
    562 do_option_dryrun ()
    563 {
    564     DRYRUN=yes
    565 }
    566 
    567 register_option "--help"          do_option_help     "Print this help."
    568 register_option "--verbose"       do_option_verbose  "Enable verbose mode."
    569 register_option "--dryrun"        do_option_dryrun   "Set to dryrun mode."
    570 
    571 #====================================================
    572 #
    573 #  TOOLCHAIN AND ABI PROCESSING
    574 #
    575 #====================================================
    576 
    577 # Determine optional variable value
    578 # $1: final variable name
    579 # $2: option variable name
    580 # $3: small description for the option
    581 fix_option ()
    582 {
    583     if [ -n "$2" ] ; then
    584         eval $1="$2"
    585         log "Using specific $3: $2"
    586     else
    587         log "Using default $3: `var_value $1`"
    588     fi
    589 }
    590 
    591 
    592 # If SYSROOT is empty, check that $1/$2 contains a sysroot
    593 # and set the variable to it.
    594 #
    595 # $1: sysroot path
    596 # $2: platform/arch suffix
    597 check_sysroot ()
    598 {
    599     if [ -z "$SYSROOT" ] ; then
    600         log "Probing directory for sysroot: $1/$2"
    601         if [ -d $1/$2 ] ; then
    602             SYSROOT=$1/$2
    603         fi
    604     fi
    605 }
    606 
    607 # Determine sysroot
    608 # $1: Option value (or empty)
    609 #
    610 fix_sysroot ()
    611 {
    612     if [ -n "$1" ] ; then
    613         eval SYSROOT="$1"
    614         log "Using specified sysroot: $1"
    615     else
    616         SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH
    617         SYSROOT=
    618         check_sysroot $ANDROID_BUILD_TOP/prebuilts/ndk/current/platforms $SYSROOT_SUFFIX
    619         check_sysroot $ANDROID_NDK_ROOT/platforms $SYSROOT_SUFFIX
    620         check_sysroot `dirname $ANDROID_NDK_ROOT`/development/ndk/platforms $SYSROOT_SUFFIX
    621 
    622         if [ -z "$SYSROOT" ] ; then
    623             echo "ERROR: Could not find NDK sysroot path for $SYSROOT_SUFFIX."
    624             echo "       Use --sysroot=<path> to specify one."
    625             exit 1
    626         fi
    627     fi
    628 
    629     if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then
    630         echo "ERROR: Invalid sysroot path: $SYSROOT"
    631         echo "       Use --sysroot=<path> to indicate a valid one."
    632         exit 1
    633     fi
    634 }
    635 
    636 # Check for the availability of a compatibility SDK in Darwin
    637 # this can be used to generate binaries compatible with either Tiger or
    638 # Leopard.
    639 #
    640 # $1: SDK root path
    641 # $2: Optional MacOS X minimum version (e.g. 10.5)
    642 DARWIN_MINVER=10.6
    643 check_darwin_sdk ()
    644 {
    645     local MACSDK="$1"
    646     local MINVER=$2
    647 
    648     if [ -z "$MINVER" ] ; then
    649         # expect SDK root path ended up with either MacOSX##.#.sdk or MacOSX##.#u.sdk
    650         MINVER=${MACSDK##*MacOSX}
    651         MINVER=${MINVER%%.sdk*}
    652         if [ "$MINVER" = "10.4u" ]; then
    653             MINVER=10.4
    654         fi
    655     fi
    656     if [ -d "$MACSDK" ] ; then
    657         HOST_CFLAGS=$HOST_CFLAGS" -isysroot $MACSDK -mmacosx-version-min=$MINVER -DMAXOSX_DEPLOYEMENT_TARGET=$MINVER"
    658         HOST_LDFLAGS=$HOST_LDFLAGS" -Wl,-syslibroot,$MACSDK -mmacosx-version-min=$MINVER"
    659         DARWIN_MINVER=$MINVER
    660         return 0  # success
    661     fi
    662     return 1
    663 }
    664 
    665 # Probe Darwin SDK in specified diectory $DARWIN_SYSROOT, or
    666 # /Developer/SDKs/MacOSX10.6.sdk
    667 #
    668 probe_darwin_sdk ()
    669 {
    670     if [ -n "$DARWIN_SYSROOT" ]; then
    671         if check_darwin_sdk "$DARWIN_SYSROOT"; then
    672             log "Use darwin sysroot $DARWIN_SYSROOT"
    673         else
    674             echo "darwin sysroot $DARWIN_SYSROOT is not valid"
    675             exit 1
    676         fi
    677     elif check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk 10.6; then
    678         log "Generating Snow Leopard-compatible binaries!"
    679     else
    680         local version=`sw_vers -productVersion`
    681         log "Generating $version-compatible binaries!"
    682     fi
    683 }
    684 
    685 handle_canadian_build ()
    686 {
    687     HOST_EXE=
    688     if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then
    689         case $HOST_TAG in
    690             linux-*)
    691                 ;;
    692             *)
    693                 echo "ERROR: Can only enable --mingw or --darwin on Linux platforms !"
    694                 exit 1
    695                 ;;
    696         esac
    697         if [ "$MINGW" = "yes" ] ; then
    698             # NOTE: Use x86_64-pc-mingw32msvc or i586-pc-mingw32msvc because wrappers are generated
    699             #       using these names
    700             if [ "$TRY64" = "yes" ]; then
    701                 ABI_CONFIGURE_HOST=x86_64-pc-mingw32msvc
    702                 HOST_TAG=windows-x86_64
    703             else
    704                 ABI_CONFIGURE_HOST=i586-pc-mingw32msvc
    705                 HOST_TAG=windows
    706             fi
    707             HOST_OS=windows
    708             HOST_EXE=.exe
    709         else
    710             if [ "$TRY64" = "yes" ]; then
    711                 ABI_CONFIGURE_HOST=x86_64-apple-darwin
    712                 HOST_TAG=darwin-x86_64
    713             else
    714                 ABI_CONFIGURE_HOST=i686-apple-darwin
    715                 HOST_TAG=darwin-x86
    716             fi
    717             HOST_OS=darwin
    718         fi
    719     fi
    720 }
    721 
    722 # Find mingw toolchain
    723 #
    724 # Set MINGW_GCC to the found mingw toolchain
    725 #
    726 find_mingw_toolchain ()
    727 {
    728     if [ "$DEBIAN_NAME" -a "$BINPREFIX" -a "$MINGW_GCC" ]; then
    729         return
    730     fi
    731     # IMPORTANT NOTE: binutils 2.21 requires a cross toolchain named
    732     # i585-pc-mingw32msvc-gcc, or it will fail its configure step late
    733     # in the toolchain build. Note that binutils 2.19 can build properly
    734     # with i585-mingw32mvsc-gcc, which is the name used by the 'mingw32'
    735     # toolchain install on Debian/Ubuntu.
    736     #
    737     # To solve this dilemma, we create a wrapper toolchain named
    738     # i586-pc-mingw32msvc-gcc that really calls i586-mingw32msvc-gcc,
    739     # this works with all versions of binutils.
    740     #
    741     # We apply the same logic to the 64-bit Windows cross-toolchain
    742     #
    743     # Fedora note: On Fedora it's x86_64-w64-mingw32- or i686-w64-mingw32-
    744     # On older Fedora it's 32-bit only and called i686-pc-mingw32-
    745     # so we just add more prefixes to the list to check.
    746     if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then
    747         BINPREFIX=x86_64-pc-mingw32msvc-
    748         BINPREFIXLST="x86_64-pc-mingw32msvc- x86_64-w64-mingw32- amd64-mingw32msvc-"
    749         DEBIAN_NAME=mingw-w64
    750     else
    751         # we are trying 32 bit anyway, so forcing it to avoid build issues
    752         force_32bit_binaries
    753         BINPREFIX=i586-pc-mingw32msvc-
    754         BINPREFIXLST="i586-pc-mingw32msvc- i686-pc-mingw32- i586-mingw32msvc- i686-w64-mingw32-"
    755         DEBIAN_NAME=mingw-w64
    756     fi
    757 
    758     # Scan $BINPREFIXLST list to find installed mingw toolchain. It will be
    759     # wrapped later with $BINPREFIX.
    760     for i in $BINPREFIXLST; do
    761         find_program MINGW_GCC ${i}gcc
    762         if [ -n "$MINGW_GCC" ]; then
    763             dump "Found mingw toolchain: $MINGW_GCC"
    764             break
    765         fi
    766     done
    767 }
    768 
    769 # Check there is a working cross-toolchain installed.
    770 #
    771 # $1: install directory for mingw/darwin wrapper toolchain
    772 #
    773 prepare_canadian_toolchain ()
    774 {
    775     if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then
    776         return
    777     fi
    778     CROSS_GCC=
    779     if [ "$MINGW" = "yes" ]; then
    780         find_mingw_toolchain
    781         if [ -z "$MINGW_GCC" ]; then
    782             echo "ERROR: Could not find in your PATH any of:"
    783             for i in $BINPREFIXLST; do echo "   ${i}gcc"; done
    784             echo "Please install the corresponding cross-toolchain and re-run this script"
    785             echo "TIP: On Debian or Ubuntu, try: sudo apt-get install $DEBIAN_NAME"
    786             exit 1
    787         fi
    788         CROSS_GCC=$MINGW_GCC
    789     else
    790         if [ -z "$DARWIN_TOOLCHAIN" ]; then
    791             echo "Please set DARWIN_TOOLCHAIN to darwin cross-toolchain"
    792             exit 1
    793         fi
    794         if [ ! -f "${DARWIN_TOOLCHAIN}-gcc" ]; then
    795             echo "darwin cross-toolchain $DARWIN_TOOLCHAIN-gcc doesn't exist"
    796             exit 1
    797         fi
    798         if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then
    799             BINPREFIX=x86_64-apple-darwin-
    800             DEBIAN_NAME=darwin64
    801             HOST_CFLAGS=$HOST_CFLAGS" -m64"
    802         else
    803             force_32bit_binaries
    804             BINPREFIX=i686-apple-darwin-
    805             DEBIAN_NAME=darwin32
    806             HOST_CFLAGS=$HOST_CFLAGS" -m32"
    807         fi
    808         CROSS_GCC=${DARWIN_TOOLCHAIN}-gcc
    809         probe_darwin_sdk
    810     fi
    811 
    812     # Create a wrapper toolchain, and prepend its dir to our PATH
    813     CROSS_WRAP_DIR="$1"/$DEBIAN_NAME-wrapper
    814     rm -rf "$CROSS_WRAP_DIR"
    815     mkdir -p "$CROSS_WRAP_DIR"
    816 
    817     if [ "$DARWIN" = "yes" ] ; then
    818         cat > "$CROSS_WRAP_DIR/sw_vers" <<EOF
    819 #!/bin/sh
    820 # Tiny utility for the real sw_vers some Makefiles need
    821 case \$1 in
    822     -productVersion)
    823         echo $DARWIN_MINVER
    824         ;;
    825     *)
    826         echo "ERROR: Unknown switch \$1"
    827         exit 1
    828 esac
    829 EOF
    830     chmod 0755 "$CROSS_WRAP_DIR/sw_vers"
    831     fi
    832 
    833     DST_PREFIX=${CROSS_GCC%gcc}
    834     if [ "$NDK_CCACHE" ]; then
    835         DST_PREFIX="$NDK_CCACHE $DST_PREFIX"
    836     fi
    837     $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=$BINPREFIX --dst-prefix="$DST_PREFIX" "$CROSS_WRAP_DIR" \
    838         --cflags="$HOST_CFLAGS" --cxxflags="$HOST_CFLAGS" --ldflags="$HOST_LDFLAGS"
    839     # generate wrappers for BUILD toolchain
    840     # this is required for mingw/darwin build to avoid tools canadian cross configuration issues
    841     # 32-bit BUILD toolchain
    842     LEGACY_TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8"
    843     $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-linux-gnu- \
    844             --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \
    845             --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
    846     $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-pc-linux-gnu- \
    847             --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \
    848             --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
    849     # 64-bit BUILD toolchain.  libbfd is still built in 32-bit.
    850     $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-linux-gnu- \
    851             --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
    852     $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-pc-linux-gnu- \
    853             --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
    854     fail_panic "Could not create $DEBIAN_NAME wrapper toolchain in $CROSS_WRAP_DIR"
    855 
    856     export PATH=$CROSS_WRAP_DIR:$PATH
    857     dump "Using $DEBIAN_NAME wrapper: $CROSS_WRAP_DIR/${BINPREFIX}gcc"
    858 }
    859 
    860 handle_host ()
    861 {
    862     if [ "$TRY64" != "yes" ]; then
    863         force_32bit_binaries  # to modify HOST_TAG and others
    864         HOST_BITS=32
    865     fi
    866     handle_canadian_build
    867 }
    868 
    869 setup_ccache ()
    870 {
    871     # Support for ccache compilation
    872     # We can't use this here when building Windows/darwin binaries on Linux with
    873     # binutils 2.21, because defining CC/CXX in the environment makes the
    874     # configure script fail later
    875     #
    876     if [ "$NDK_CCACHE" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then
    877         NDK_CCACHE_CC=$CC
    878         NDK_CCACHE_CXX=$CXX
    879         # Unfortunately, we can just do CC="$NDK_CCACHE $CC" because some
    880         # configure scripts are not capable of dealing with this properly
    881         # E.g. the ones used to rebuild the GCC toolchain from scratch.
    882         # So instead, use a wrapper script
    883         CC=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-gcc.sh
    884         CXX=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-g++.sh
    885         export NDK_CCACHE_CC NDK_CCACHE_CXX
    886         log "Using ccache compilation"
    887         log "NDK_CCACHE_CC=$NDK_CCACHE_CC"
    888         log "NDK_CCACHE_CXX=$NDK_CCACHE_CXX"
    889     fi
    890 }
    891 
    892 prepare_common_build ()
    893 {
    894     if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then
    895         if [ "$TRY64" = "yes" ]; then
    896             HOST_BITS=64
    897         else
    898             HOST_BITS=32
    899         fi
    900         if [ "$MINGW" = "yes" ]; then
    901             log "Generating $HOST_BITS-bit Windows binaries"
    902         else
    903             log "Generating $HOST_BITS-bit Darwin binaries"
    904         fi
    905         # Do *not* set CC and CXX when building the Windows/Darwin binaries in canadian build.
    906         # Otherwise, the GCC configure/build script will mess that Canadian cross
    907         # build in weird ways. Instead we rely on the toolchain detected or generated
    908         # previously in prepare_canadian_toolchain.
    909         unset CC CXX
    910         return
    911     fi
    912 
    913     # On Linux, detect our legacy-compatible toolchain when in the Android
    914     # source tree, and use it to force the generation of glibc-2.7 compatible
    915     # binaries.
    916     #
    917     # We only do this if the CC variable is not defined to a given value
    918     if [ -z "$CC" ]; then
    919         LEGACY_TOOLCHAIN_DIR=
    920         if [ "$HOST_OS" = "linux" ]; then
    921             LEGACY_TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8/bin"
    922             LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/x86_64-linux-"
    923         elif [ "$HOST_OS" = "darwin" ]; then
    924             LEGACY_TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1/bin"
    925             LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/i686-apple-darwin10-"
    926         fi
    927         if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then
    928             log "Forcing generation of $HOST_OS binaries with legacy toolchain"
    929             CC="${LEGACY_TOOLCHAIN_PREFIX}gcc"
    930             CXX="${LEGACY_TOOLCHAIN_PREFIX}g++"
    931         fi
    932     fi
    933 
    934     CC=${CC:-gcc}
    935     CXX=${CXX:-g++}
    936     STRIP=${STRIP:-strip}
    937     case $HOST_TAG in
    938         darwin-*)
    939             probe_darwin_sdk
    940             ;;
    941     esac
    942 
    943     # Force generation of 32-bit binaries on 64-bit systems.
    944     # We used to test the value of $HOST_TAG for *-x86_64, but this is
    945     # not sufficient on certain systems.
    946     #
    947     # For example, Snow Leopard can be booted with a 32-bit kernel, running
    948     # a 64-bit userland, with a compiler that generates 64-bit binaries by
    949     # default *even* though "gcc -v" will report --target=i686-apple-darwin10!
    950     #
    951     # So know, simply probe for the size of void* by performing a small runtime
    952     # compilation test.
    953     #
    954     cat > $TMPC <<EOF
    955     /* this test should fail if the compiler generates 64-bit machine code */
    956     int test_array[1-2*(sizeof(void*) != 4)];
    957 EOF
    958     log_n "Checking whether the compiler generates 32-bit binaries..."
    959     log $CC $HOST_CFLAGS -c -o $TMPO $TMPC
    960     $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1
    961     if [ $? != 0 ] ; then
    962         log "no"
    963         if [ "$TRY64" != "yes" ]; then
    964             # NOTE: We need to modify the definitions of CC and CXX directly
    965             #        here. Just changing the value of CFLAGS / HOST_CFLAGS
    966             #        will not work well with the GCC toolchain scripts.
    967             CC="$CC -m32"
    968             CXX="$CXX -m32"
    969         fi
    970     else
    971         log "yes"
    972         if [ "$TRY64" = "yes" ]; then
    973             CC="$CC -m64"
    974             CXX="$CXX -m64"
    975         fi
    976     fi
    977 
    978     if [ "$TRY64" = "yes" ]; then
    979         HOST_BITS=64
    980     else
    981         force_32bit_binaries  # to modify HOST_TAG and others
    982         HOST_BITS=32
    983     fi
    984 }
    985 
    986 prepare_host_build ()
    987 {
    988     prepare_common_build
    989 
    990     # Now deal with mingw or darwin
    991     if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then
    992         handle_canadian_build
    993         CC=$ABI_CONFIGURE_HOST-gcc
    994         CXX=$ABI_CONFIGURE_HOST-g++
    995         CPP=$ABI_CONFIGURE_HOST-cpp
    996         LD=$ABI_CONFIGURE_HOST-ld
    997         AR=$ABI_CONFIGURE_HOST-ar
    998         AS=$ABI_CONFIGURE_HOST-as
    999         RANLIB=$ABI_CONFIGURE_HOST-ranlib
   1000         STRIP=$ABI_CONFIGURE_HOST-strip
   1001         export CC CXX CPP LD AR AS RANLIB STRIP
   1002     fi
   1003 
   1004     setup_ccache
   1005 }
   1006 
   1007 prepare_abi_configure_build ()
   1008 {
   1009     # detect build tag
   1010     case $HOST_TAG in
   1011         linux-x86)
   1012             ABI_CONFIGURE_BUILD=i386-linux-gnu
   1013             ;;
   1014         linux-x86_64)
   1015             ABI_CONFIGURE_BUILD=x86_64-linux-gnu
   1016             ;;
   1017         darwin-x86)
   1018             ABI_CONFIGURE_BUILD=i686-apple-darwin
   1019             ;;
   1020         darwin-x86_64)
   1021             ABI_CONFIGURE_BUILD=x86_64-apple-darwin
   1022             ;;
   1023         windows)
   1024             ABI_CONFIGURE_BUILD=i686-pc-cygwin
   1025             ;;
   1026         *)
   1027             echo "ERROR: Unsupported HOST_TAG: $HOST_TAG"
   1028             echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh"
   1029             ;;
   1030     esac
   1031 }
   1032 
   1033 prepare_target_build ()
   1034 {
   1035     prepare_abi_configure_build
   1036 
   1037     # By default, assume host == build
   1038     ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD"
   1039 
   1040     prepare_common_build
   1041     HOST_GMP_ABI=$HOST_BITS
   1042 
   1043     # Now handle the --mingw/--darwin flag
   1044     if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then
   1045         handle_canadian_build
   1046         STRIP=$ABI_CONFIGURE_HOST-strip
   1047         if [ "$MINGW" = "yes" ] ; then
   1048             # It turns out that we need to undefine this to be able to
   1049             # perform a canadian-cross build with mingw. Otherwise, the
   1050             # GMP configure scripts will not be called with the right options
   1051             HOST_GMP_ABI=
   1052         fi
   1053     fi
   1054 
   1055     setup_ccache
   1056 }
   1057 
   1058 # $1: Toolchain name
   1059 #
   1060 parse_toolchain_name ()
   1061 {
   1062     TOOLCHAIN=$1
   1063     if [ -z "$TOOLCHAIN" ] ; then
   1064         echo "ERROR: Missing toolchain name!"
   1065         exit 1
   1066     fi
   1067 
   1068     ABI_CFLAGS_FOR_TARGET=
   1069     ABI_CXXFLAGS_FOR_TARGET=
   1070 
   1071     # Determine ABI based on toolchain name
   1072     #
   1073     case "$TOOLCHAIN" in
   1074     arm-linux-androideabi-*)
   1075         ARCH="arm"
   1076         ABI="armeabi"
   1077         ABI_CONFIGURE_TARGET="arm-linux-androideabi"
   1078         ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te"
   1079         ;;
   1080     arm-eabi-*)
   1081         ARCH="arm"
   1082         ABI="armeabi"
   1083         ABI_CONFIGURE_TARGET="arm-eabi"
   1084         ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te --disable-gold --disable-libgomp"
   1085         ;;
   1086     aarch64-linux-android-*)
   1087         ARCH="arm64"
   1088         ABI="arm64-v8a"
   1089         ABI_CONFIGURE_TARGET="aarch64-linux-android"
   1090         ;;
   1091     x86-*)
   1092         ARCH="x86"
   1093         ABI=$ARCH
   1094         ABI_INSTALL_NAME="x86"
   1095         ABI_CONFIGURE_TARGET="i686-linux-android"
   1096         # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
   1097         # You can't really build these separately at the moment.
   1098         ABI_CFLAGS_FOR_TARGET="-fPIC"
   1099         ;;
   1100     x86_64-*)
   1101         ARCH="x86_64"
   1102         ABI=$ARCH
   1103         ABI_INSTALL_NAME="x86_64"
   1104         ABI_CONFIGURE_TARGET="x86_64-linux-android"
   1105         # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
   1106         # You can't really build these separately at the moment.
   1107         ABI_CFLAGS_FOR_TARGET="-fPIC"
   1108         ;;
   1109     mipsel*)
   1110         ARCH="mips"
   1111         ABI=$ARCH
   1112         ABI_INSTALL_NAME="mips"
   1113         ABI_CONFIGURE_TARGET="mipsel-linux-android"
   1114         # Set default to mips32
   1115         ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips32"
   1116         # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
   1117         # You can't really build these separately at the moment.
   1118         # Add -fpic, because MIPS NDK will need to link .a into .so.
   1119         ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic"
   1120         ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic"
   1121         # Add --disable-fixed-point to disable fixed-point support
   1122         ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point"
   1123         ;;
   1124     mips64el*)
   1125         ARCH="mips64"
   1126         ABI=$ARCH
   1127         ABI_INSTALL_NAME="mips64"
   1128         ABI_CONFIGURE_TARGET="mips64el-linux-android"
   1129         # Set default to mips64r6
   1130         ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips64r6"
   1131         # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
   1132         # You can't really build these separately at the moment.
   1133         # Add -fpic, because MIPS NDK will need to link .a into .so.
   1134         ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic"
   1135         ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic"
   1136         # Add --disable-fixed-point to disable fixed-point support
   1137         ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point"
   1138         ;;
   1139     * )
   1140         echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|arm-eabi-*|x86-*|mipsel*|mips64el*)"
   1141         echo ""
   1142         print_help
   1143         exit 1
   1144         ;;
   1145     esac
   1146 
   1147     log "Targetting CPU: $ARCH"
   1148 
   1149     GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'`
   1150     log "Using GCC version: $GCC_VERSION"
   1151 
   1152     # Determine --host value when building gdbserver
   1153 
   1154     case "$TOOLCHAIN" in
   1155     arm-*)
   1156         GDBSERVER_HOST=arm-eabi-linux
   1157         GDBSERVER_CFLAGS="-fno-short-enums"
   1158         GDBSERVER_LDFLAGS=
   1159         ;;
   1160     aarch64-*)
   1161         GDBSERVER_HOST=aarch64-eabi-linux
   1162         GDBSERVER_CFLAGS="-fno-short-enums -DUAPI_HEADERS"
   1163         GDBSERVER_LDFLAGS=
   1164         ;;
   1165     x86-*)
   1166         GDBSERVER_HOST=i686-linux-android
   1167         GDBSERVER_CFLAGS=
   1168         GDBSERVER_LDFLAGS=
   1169         ;;
   1170     x86_64-*)
   1171         GDBSERVER_HOST=x86_64-linux-android
   1172         GDBSERVER_CFLAGS=-DUAPI_HEADERS
   1173         GDBSERVER_LDFLAGS=
   1174         ;;
   1175     mipsel-*)
   1176         GDBSERVER_HOST=mipsel-linux-android
   1177         GDBSERVER_CFLAGS=
   1178         GDBSERVER_LDFLAGS=
   1179         ;;
   1180     mips64el-*)
   1181         GDBSERVER_HOST=mips64el-linux-android
   1182         GDBSERVER_CFLAGS=-DUAPI_HEADERS
   1183         GDBSERVER_LDFLAGS=
   1184         ;;
   1185     *)
   1186         echo "Unknown TOOLCHAIN=$TOOLCHAIN"
   1187         exit
   1188     esac
   1189 }
   1190 
   1191 # Return the host "tag" used to identify prebuilt host binaries.
   1192 # NOTE: Handles the case where '$MINGW = true' or '$DARWIN = true'
   1193 # For now, valid values are: linux-x86, darwin-x86 and windows
   1194 get_prebuilt_host_tag ()
   1195 {
   1196     local RET=$HOST_TAG
   1197     if [ "$MINGW" = "yes" ]; then
   1198         if [ "$TRY64" = "no" ]; then
   1199             RET=windows
   1200         else
   1201             RET=windows-x86_64
   1202         fi
   1203     fi
   1204     if [ "$DARWIN" = "yes" ]; then
   1205         RET=darwin-x86_64  # let the following handles 32-bit case
   1206     fi
   1207     case $RET in
   1208         linux-*)
   1209             RET=linux-x86_64
   1210             ;;
   1211         darwin-*)
   1212             RET=darwin-x86_64
   1213             ;;
   1214     esac
   1215     echo $RET
   1216 }
   1217 
   1218 # Return the executable suffix corresponding to host executables
   1219 get_prebuilt_host_exe_ext ()
   1220 {
   1221     if [ "$MINGW" = "yes" ]; then
   1222         echo ".exe"
   1223     else
   1224         echo ""
   1225     fi
   1226 }
   1227 
   1228 # Get library suffix for given ABI
   1229 # $1: ABI
   1230 # Return: .so or .bc
   1231 get_lib_suffix_for_abi ()
   1232 {
   1233     local ABI=$1
   1234     echo ".so"
   1235 }
   1236 
   1237 # Convert an ABI name into an Architecture name
   1238 # $1: ABI name
   1239 # Result: Arch name
   1240 convert_abi_to_arch ()
   1241 {
   1242     local RET
   1243     local ABI=$1
   1244     case $ABI in
   1245         armeabi|armeabi-v7a|armeabi-v7a-hard)
   1246             RET=arm
   1247             ;;
   1248         x86|mips|x86_64|mips64)
   1249             RET=$ABI
   1250             ;;
   1251         mips32r6)
   1252             RET=mips
   1253             ;;
   1254         arm64-v8a)
   1255             RET=arm64
   1256             ;;
   1257         *)
   1258             >&2 echo "ERROR: Unsupported ABI name: $ABI, use one of: armeabi, armeabi-v7a, x86, mips, armeabi-v7a-hard, arm64-v8a, x86_64 or mips64"
   1259             exit 1
   1260             ;;
   1261     esac
   1262     echo "$RET"
   1263 }
   1264 
   1265 # Take architecture name as input, and output the list of corresponding ABIs
   1266 # Inverse for convert_abi_to_arch
   1267 # $1: ARCH name
   1268 # Out: ABI names list (comma-separated)
   1269 convert_arch_to_abi ()
   1270 {
   1271     local RET
   1272     local ARCH=$1
   1273     case $ARCH in
   1274         arm)
   1275             RET=armeabi,armeabi-v7a,armeabi-v7a-hard
   1276             ;;
   1277         x86|x86_64|mips|mips64)
   1278             RET=$ARCH
   1279             ;;
   1280         arm64)
   1281             RET=arm64-v8a
   1282             ;;
   1283         *)
   1284             >&2 echo "ERROR: Unsupported ARCH name: $ARCH, use one of: arm, x86, mips"
   1285             exit 1
   1286             ;;
   1287     esac
   1288     echo "$RET"
   1289 }
   1290 
   1291 # Take a list of architecture names as input, and output the list of corresponding ABIs
   1292 # $1: ARCH names list (separated by spaces or commas)
   1293 # Out: ABI names list (comma-separated)
   1294 convert_archs_to_abis ()
   1295 {
   1296     local RET
   1297     for ARCH in $(commas_to_spaces $@); do
   1298        ABI=$(convert_arch_to_abi $ARCH)
   1299        if [ -n "$ABI" ]; then
   1300           if [ -n "$RET" ]; then
   1301              RET=$RET",$ABI"
   1302           else
   1303              RET=$ABI
   1304           fi
   1305        else   # Error message is printed by convert_arch_to_abi
   1306           exit 1
   1307        fi
   1308     done
   1309     echo "$RET"
   1310 }
   1311 
   1312 # Return the default toolchain binary path prefix for given architecture and gcc version
   1313 # For example: arm 4.8 -> toolchains/<system>/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-
   1314 # $1: Architecture name
   1315 # $2: GCC version
   1316 # $3: optional, system name, defaults to $HOST_TAG
   1317 get_toolchain_binprefix_for_arch ()
   1318 {
   1319     local NAME PREFIX DIR BINPREFIX
   1320     local SYSTEM=${3:-$(get_prebuilt_host_tag)}
   1321     NAME=$(get_toolchain_name_for_arch $1 $2)
   1322     PREFIX=$(get_default_toolchain_prefix_for_arch $1)
   1323     DIR=$(get_toolchain_install . $NAME $SYSTEM)
   1324     BINPREFIX=${DIR#./}/bin/$PREFIX-
   1325     echo "$BINPREFIX"
   1326 }
   1327 
   1328 # Return llvm toolchain binary path prefix for given llvm version
   1329 # $1: llvm version
   1330 # $2: optional, system name, defaults to $HOST_TAG
   1331 get_llvm_toolchain_binprefix ()
   1332 {
   1333     local NAME DIR BINPREFIX
   1334     local SYSTEM=${2:-$(get_prebuilt_host_tag)}
   1335     SYSTEM=${SYSTEM%_64} # Trim _64 suffix. We only have one LLVM.
   1336     BINPREFIX=$ANDROID_BUILD_TOP/prebuilts/clang/$SYSTEM/host/$1/bin
   1337     echo "$BINPREFIX"
   1338 }
   1339 
   1340 # Return default API level for a given arch
   1341 # This is the level used to build the toolchains.
   1342 #
   1343 # $1: Architecture name
   1344 get_default_api_level_for_arch ()
   1345 {
   1346     # For now, always build the toolchain against API level 9 for 32-bit arch
   1347     # and API level $FIRST_API64_LEVEL for 64-bit arch
   1348     case $1 in
   1349         *64) echo $FIRST_API64_LEVEL ;;
   1350         *) echo 9 ;;
   1351     esac
   1352 }
   1353 
   1354 # Return the default platform sysroot corresponding to a given architecture
   1355 # This is the sysroot used to build the toolchain and other binaries like
   1356 # the STLport libraries.
   1357 # $1: Architecture name
   1358 get_default_platform_sysroot_for_arch ()
   1359 {
   1360     local ARCH=$1
   1361     local LEVEL=$(get_default_api_level_for_arch $ARCH)
   1362 
   1363     if [ "$ARCH" != "${ARCH%%64*}" ] ; then
   1364         LEVEL=$FIRST_API64_LEVEL
   1365     fi
   1366     echo "platforms/android-$LEVEL/arch-$ARCH"
   1367 }
   1368 
   1369 # Return the default platform sysroot corresponding to a given abi
   1370 # $1: ABI
   1371 get_default_platform_sysroot_for_abi ()
   1372 {
   1373     local ARCH=$(convert_abi_to_arch $1)
   1374     $(get_default_platform_sysroot_for_arch $ARCH)
   1375 }
   1376 
   1377 # Return the default libs dir corresponding to a given architecture
   1378 # $1: Architecture name
   1379 get_default_libdir_for_arch ()
   1380 {
   1381     case $1 in
   1382       x86_64|mips64) echo "lib64" ;;
   1383       arm64) echo "lib" ;; # return "lib" until aarch64 is built to look for sysroot/usr/lib64
   1384       *) echo "lib" ;;
   1385     esac
   1386 }
   1387 
   1388 # Return the default libs dir corresponding to a given abi
   1389 # $1: ABI
   1390 get_default_libdir_for_abi ()
   1391 {
   1392     local ARCH
   1393 
   1394     case $1 in
   1395       mips32r6) echo "libr6" ;;
   1396       *)
   1397         local ARCH=$(convert_abi_to_arch $1)
   1398         echo "$(get_default_libdir_for_arch $ARCH)"
   1399         ;;
   1400     esac
   1401 }
   1402 
   1403 # Return the host/build specific path for prebuilt toolchain binaries
   1404 # relative to $1.
   1405 #
   1406 # $1: target root NDK directory
   1407 # $2: toolchain name
   1408 # $3: optional, host system name
   1409 #
   1410 get_toolchain_install ()
   1411 {
   1412     local NDK="$1"
   1413     shift
   1414     echo "$NDK/$(get_toolchain_install_subdir "$@")"
   1415 }
   1416 
   1417 # $1: toolchain name
   1418 # $2: optional, host system name
   1419 get_toolchain_install_subdir ()
   1420 {
   1421     local SYSTEM=${2:-$(get_prebuilt_host_tag)}
   1422     echo "toolchains/$SYSTEM/$1"
   1423 }
   1424 
   1425 # Return the relative install prefix for prebuilt host
   1426 # executables (relative to the NDK top directory).
   1427 #
   1428 # Out: relative path to prebuilt install prefix
   1429 get_prebuilt_install_prefix ()
   1430 {
   1431     echo "host-tools"
   1432 }
   1433 
   1434 # Return the relative path of an installed prebuilt host
   1435 # executable.
   1436 #
   1437 # $1: executable name
   1438 # Out: path to prebuilt host executable, relative
   1439 get_prebuilt_host_exec ()
   1440 {
   1441     local PREFIX EXE
   1442     PREFIX=$(get_prebuilt_install_prefix)
   1443     EXE=$(get_prebuilt_host_exe_ext)
   1444     echo "$PREFIX/bin/$1$EXE"
   1445 }
   1446 
   1447 # Return the name of a given host executable
   1448 # $1: executable base name
   1449 # Out: executable name, with optional suffix (e.g. .exe for windows)
   1450 get_host_exec_name ()
   1451 {
   1452     local EXE=$(get_prebuilt_host_exe_ext)
   1453     echo "$1$EXE"
   1454 }
   1455 
   1456 # Return the directory where host-specific binaries are installed.
   1457 # $1: target root NDK directory
   1458 get_host_install ()
   1459 {
   1460     echo "$1/$(get_prebuilt_install_prefix)"
   1461 }
   1462 
   1463 # Set the toolchain target NDK location.
   1464 # this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX
   1465 # $1: target NDK path
   1466 # $2: toolchain name
   1467 set_toolchain_ndk ()
   1468 {
   1469     TOOLCHAIN_PATH=`get_toolchain_install "$1" $2`
   1470     log "Using toolchain path: $TOOLCHAIN_PATH"
   1471 
   1472     TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET
   1473     log "Using toolchain prefix: $TOOLCHAIN_PREFIX"
   1474 }
   1475 
   1476 # Check that a toolchain is properly installed at a target NDK location
   1477 #
   1478 # $1: target root NDK directory
   1479 # $2: toolchain name
   1480 #
   1481 check_toolchain_install ()
   1482 {
   1483     TOOLCHAIN_PATH=`get_toolchain_install "$1" $2`
   1484     if [ ! -d "$TOOLCHAIN_PATH" ] ; then
   1485         echo "ERROR: Cannot find directory '$TOOLCHAIN_PATH'!"
   1486         echo "       Toolchain '$2' not installed in '$NDK_DIR'!"
   1487         echo "       Ensure that the toolchain has been installed there before."
   1488         exit 1
   1489     fi
   1490 
   1491     set_toolchain_ndk $1 $2
   1492 }
   1493 
   1494 # $1: toolchain source directory
   1495 check_toolchain_src_dir ()
   1496 {
   1497     local SRC_DIR="$1"
   1498     if [ -z "$SRC_DIR" ]; then
   1499         echo "ERROR: Please provide the path to the toolchain source tree. See --help"
   1500         exit 1
   1501     fi
   1502 
   1503     if [ ! -d "$SRC_DIR" ]; then
   1504         echo "ERROR: Not a directory: '$SRC_DIR'"
   1505         exit 1
   1506     fi
   1507 
   1508     if [ ! -f "$SRC_DIR/build/configure" -o ! -d "$SRC_DIR/gcc" ]; then
   1509         echo "ERROR: Either the file $SRC_DIR/build/configure or"
   1510         echo "       the directory $SRC_DIR/gcc does not exist."
   1511         echo "This is not the top of a toolchain tree: $SRC_DIR"
   1512         exit 1
   1513     fi
   1514 }
   1515 
   1516 make_repo_prop () {
   1517     local OUT_PATH="$1/repo.prop"
   1518 
   1519     # The build server generates a repo.prop file that contains the current SHAs
   1520     # of each project.
   1521     if [ -f $DIST_DIR/repo.prop ]; then
   1522         cp $DIST_DIR/repo.prop $OUT_PATH
   1523     else
   1524         # Generate our own if we're building locally.
   1525         pushd $ANDROID_NDK_ROOT
   1526         repo forall \
   1527             -c 'echo $REPO_PROJECT $(git rev-parse HEAD)' > $OUT_PATH
   1528         popd
   1529     fi
   1530 }
   1531 
   1532 #
   1533 # The NDK_TMPDIR variable is used to specify a root temporary directory
   1534 # when invoking toolchain build scripts. If it is not defined, we will
   1535 # create one here, and export the value to ensure that any scripts we
   1536 # call after that use the same one.
   1537 #
   1538 if [ -z "$NDK_TMPDIR" ]; then
   1539     NDK_TMPDIR=$TMPDIR/tmp/build-$$
   1540     mkdir -p $NDK_TMPDIR
   1541     if [ $? != 0 ]; then
   1542         echo "ERROR: Could not create NDK_TMPDIR: $NDK_TMPDIR"
   1543         exit 1
   1544     fi
   1545     export NDK_TMPDIR
   1546 fi
   1547 
   1548 # Define HOST_TAG32, as the 32-bit version of HOST_TAG
   1549 # We do this by replacing an -x86_64 suffix by -x86
   1550 HOST_TAG32=$HOST_TAG
   1551 case $HOST_TAG32 in
   1552     *-x86_64)
   1553         HOST_TAG32=${HOST_TAG%%_64}
   1554         ;;
   1555 esac
   1556