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