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