Home | History | Annotate | Download | only in tools
      1 #!/bin/sh
      2 #
      3 # Copyright (C) 2012 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 # Rebuild the host GCC toolchain binaries from sources.
     18 #
     19 # NOTE: this script does not rebuild gdb, see build-host-gdb.sh for this.
     20 #
     21 
     22 # include common function and variable definitions
     23 . `dirname $0`/prebuilt-common.sh
     24 
     25 PROGRAM_PARAMETERS="[<toolchain-name>+]"
     26 PROGRAM_DESCRIPTION="\
     27 This program is used to rebuild one or more NDK cross-toolchains from scratch.
     28 To use it, you will first need to call download-toolchain-sources.sh to download
     29 the toolchain sources, then pass the corresponding directory with the
     30 --toolchain-src-dir=<path> option.
     31 
     32 If you don't pass any parameter, the script will rebuild all NDK toolchains
     33 for the current host system [$HOST_TAG]. You can otherwise give a list of
     34 toolchains among the following names:
     35 
     36   arm-linux-androideabi-4.4.3
     37   arm-linux-androideabi-4.6
     38   x64-4.4.3
     39   x86-4.6
     40   mipsel-linux-android-4.4.3
     41   mipsel-linux-android-4.6
     42 
     43 By default, the script rebuilds the toolchain(s) for you host system [$HOST_TAG],
     44 but you can use --systems=<tag1>,<tag2>,.. to ask binaries that can run on
     45 several distinct systems. Each <tag> value in the list can be one of the
     46 following:
     47 
     48    linux-x86
     49    linux-x86_64
     50    windows
     51    windows-x86  (equivalent to 'windows')
     52    windows-x86_64
     53    darwin-x86
     54    darwin-x86_64
     55 
     56 For example, here's how to rebuild the ARM toolchains on Linux
     57 for four different systems:
     58 
     59   $PROGNAME --toolchain-src-dir=/path/to/toolchain/src \
     60     --systems=linux-x86,linux-x86_64,windows,windows-x86_64 \
     61     arm-linux-androideabi-4.4.3 \
     62     arm-linux-androideabi-4.6
     63 
     64 You can build Windows binaries on Linux if you have a Windows-targetting
     65 cross-toolchain installed and in your path. Note that the script named
     66 'build-mingw64-toolchain.sh' can be used to rebuild such a toolchain
     67 (x86_64-w64-mingw32) from sources if you don't have one available.
     68 
     69 Building the toolchains directly under Cygwin/MSys has not be tested and
     70 is not recommended (it will be *extremely* slow, if it ever works).
     71 
     72 On Darwin, the script will try to probe any compatibility SDK installed
     73 on your development machine and will use the first it finds among a list
     74 of well-known names. You can however force a specific usage with the
     75 --darwin-sdk-version=<version> name, where <version> can be one of 10.4, 10.5,
     76 10.6, 10.7, etc.
     77 
     78 The generated binaries should run on 10.5 or higher. You can force a
     79 different compatibility minimum with --darwin-min-version.
     80 
     81 If you want to build Darwin binaries on a non-Darwin machine, you will
     82 have to define DARWIN_TOOLCHAIN / DARWIN_SYSROOT in your environment first
     83 (note: this feature is highly experimental).
     84 
     85 The script is sufficiently clever to minimize all build steps, especially
     86 if you try to build several toolchains for several distinct host systems. Note
     87 however that generating a canadian-cross toolchain (e.g. building on Linux a
     88 Windows toolchain that targets Android ARM binaries) will force the generation
     89 of a host toolchain as well, in case it is not listed in your --systems list.
     90 This is required to generate proper target GCC libraries.
     91 
     92 The toolchain binaries are installed under \$NDK_DIR/toolchains by default,
     93 but you can use --ndk-dir=<path> to specify a different NDK installation path.
     94 The script will try to build the Gold linker for host/target combination that
     95 are well supported (Gold doesn't build / is buggy for some of them). However,
     96 the BFD linker is still the default used by the generated toolchain. You can
     97 change this behaviour with two options:
     98 
     99    --default-ld=<name>  Changes the default toolchain linker.
    100                         <name> can be one of 'default', 'bfd' and 'gold'.
    101 
    102                         For now, 'default' is an alias for 'bfd', but we plan
    103                         to map it to 'gold' for some combos in the future, once
    104                         we're confident it works reliably
    105 
    106    --force-gold-build   Force the build of the Gold linker, even if it is known
    107                         to fail or generate a buggy linker. Only use this for
    108                         experimentation (e.g. with your own patched toolchain
    109                         sources).
    110 "
    111 
    112 BINUTILS_VERSION=$DEFAULT_BINUTILS_VERSION
    113 register_var_option "--binutils-version=<version>" BINUTILS_VERSION "Select binutils version"
    114 
    115 GMP_VERSION=$DEFAULT_GMP_VERSION
    116 register_var_option "--gmp-version=<version>" GMP_VERSION "Select gmp version"
    117 
    118 MPFR_VERSION=$DEFAULT_MPFR_VERSION
    119 register_var_option "--mpfr-version=<version>" MPFR_VERSION "Select mpfr version"
    120 
    121 MPC_VERSION=$DEFAULT_MPC_VERSION
    122 register_var_option "--mpc-version=<version>" MPC_VERSION "Select mpc version"
    123 
    124 TOOLCHAIN_SRC_DIR=
    125 register_var_option "--toolchain-src-dir=<path>" TOOLCHAIN_SRC_DIR "Select toolchain source directory"
    126 
    127 NDK_DIR=$ANDROID_NDK_ROOT
    128 register_var_option "--ndk-dir=<path>" NDK_DIR "Select NDK install directory"
    129 
    130 BUILD_DIR=
    131 register_var_option "--build-dir=<path>" BUILD_DIR "Build GCC into directory"
    132 
    133 PACKAGE_DIR=
    134 register_var_option "--package-dir=<path>" PACKAGE_DIR "Package prebuilt tarballs into directory"
    135 
    136 HOST_SYSTEMS="$HOST_TAG"
    137 register_var_option "--systems=<list>" HOST_SYSTEMS "Build binaries for these host systems"
    138 
    139 FORCE=
    140 register_var_option "--force" FORCE "Force full rebuild"
    141 
    142 NO_TARGET_LIBS=
    143 register_var_option "--no-target-libs" NO_TARGET_LIBS "Don't build gcc target libs."
    144 
    145 NO_STRIP=
    146 register_var_option "--no-strip" NO_STRIP "Don't strip generated binaries."
    147 
    148 NO_COLOR=
    149 register_var_option "--no-color" NO_COLOR "Don't output colored text."
    150 
    151 if [ "$HOST_OS" = darwin ]; then
    152     DARWIN_SDK_VERSION=
    153     register_var_option "--darwin-sdk-version=<version>" DARWIN_SDK "Select Darwin SDK version."
    154 
    155     DARWIN_MIN_VERSION=
    156     register_var_option "--darwin-min-version=<version>" DARWIN_MIN_VERSION "Select minimum OS X version of generated host toolchains."
    157 fi
    158 
    159 DEFAULT_LD=
    160 register_var_option "--default-ld=<name>" DEFAULT_LD "Select default linker ('bfd' or 'gold')."
    161 
    162 FORCE_GOLD_BUILD=
    163 register_var_option "--force-gold-build" FORCE_GOLD_BUILD "Always try to build Gold (experimental)."
    164 
    165 register_jobs_option
    166 
    167 
    168 extract_parameters "$@"
    169 
    170 TOOLCHAINS=$PARAMETERS
    171 if [ -z "$TOOLCHAINS" ]; then
    172     TOOLCHAINS="arm-linux-androideabi-4.4.3,arm-linux-androideabi-4.6,x86-4.4.3,x86-4.6,mipsel-linux-android-4.4.3,mipsel-linux-android-4.6"
    173     dump "Auto-config: $TOOLCHAINS"
    174 fi
    175 
    176 if [ -z "$TOOLCHAIN_SRC_DIR" ]; then
    177     panic "Please use --toolchain-src-dir=<path> to select toolchain source directory."
    178 fi
    179 
    180 if [ -z "$BUILD_DIR" ]; then
    181     BUILD_DIR=/tmp/ndk-$USER/build/host-gcc
    182 fi
    183 
    184 case $DEFAULT_LD in
    185     gold|bfd)
    186       ;;
    187     "")
    188       # For now, we always use the default BFD linker.
    189       # We should be able to switch to Gold later when all bugs are fixed.
    190       DEFAULT_LD=bfd
    191       ;;
    192     *)
    193       panic "Invalid --default-ld name '$DEFAULT_LD', valid values are: bfd gold"
    194       ;;
    195 esac
    196 
    197 HOST_SYSTEMS=$(commas_to_spaces $HOST_SYSTEMS)
    198 TOOLCHAINS=$(commas_to_spaces $TOOLCHAINS)
    199 
    200 # The values of HOST_OS/ARCH/TAG will be redefined during the build to
    201 # match those of the system the generated compiler binaries will run on.
    202 #
    203 # Save the original ones into BUILD_XXX variants, corresponding to the
    204 # machine where the build happens.
    205 #
    206 BUILD_OS=$HOST_OS
    207 BUILD_ARCH=$HOST_ARCH
    208 BUILD_TAG=$HOST_TAG
    209 
    210 # Important note: When identifying a build or host system, there is
    211 # a difference between 'NDK system tags' and "GNU configuration triplet'.
    212 #
    213 # A "system tag" is specific to the NDK and identifies a given host
    214 # system for the toolchain binaries, valid values:
    215 #
    216 #  linux-x86
    217 #  linux-x86_64
    218 #  windows        (historical alias to windows-x86)
    219 #  windows-x86
    220 #  windows-x86_64
    221 #  darwin-x86
    222 #  darwin-x86_64
    223 #
    224 # A GNU configuration triplet identifies a system too, but it used by
    225 # configure scripts, not the NDK. They vary a lot too and some of the
    226 # scripts are *very* picky about the exact values being used.
    227 #
    228 # Typical values that are known to work properly:
    229 #
    230 #    i686-linux-gnu       (Linux x86 system, with GNU libc)
    231 #    x86_64-linux-gnu     (Same, with x86_64 CPU)
    232 #    i586-mingw32msvc     (Windows 32-bits, MSVCRT.DLL)
    233 #    i586-pc-mingw32msvc  (same)
    234 #    i686-w64-mingw32     (same, slightly different sources)
    235 #    x86_64-w64-mingw32   (Windows 64-bits, MSVCRT.DLL)
    236 #    i686-apple-darwin    (OS X / Darwin, x86 CPU)
    237 #    x86_64-apple-darwin  (OS X / Darwin, x86_64 CPU)
    238 #
    239 # A cross-toolchain will typically use the GNU configuration triplet as
    240 # a prefix for all its binaries, but not always. For example, the 'mingw32'
    241 # package on Ubuntu provides a Windows cross-toolchain that uses the
    242 # i586-mingw32msvc prefix, but if you try to use it as a configuration
    243 # triplet when configuring binutils-2.21, the build will fail. You need to
    244 # pass i586-pc-mingw32msvc instead (binutils-2.19 accepts both).
    245 #
    246 # Another issue is that some toolchains need to use additional compiler
    247 # flags to deal with backwards-compatibility SDKs (Darwin) or 32/64 bit
    248 # code generation. Note all build scripts accept the same mix of
    249 # '--with-cflags=...' or 'export CFLAGS' configuration, which makes
    250 # things pretty difficult to manage.
    251 #
    252 # To work-around these issues, the script will generate "wrapper toolchains"
    253 # with the prefix that the configure scripts expects. I.e. small scripts that
    254 # redirect to the correct toolchain, eventually adding hidden extra compiler
    255 # flags. This seems to completely get rid of the problems described above.
    256 #
    257 
    258 
    259 # $1: system tag (e.g. linux-x86)
    260 tag_to_os ()
    261 {
    262     local RET
    263     case $1 in
    264         linux-*) RET="linux";;
    265         darwin-*) RET="darwin";;
    266         windows|windows-*) RET="windows";;
    267     esac
    268     echo $RET
    269 }
    270 
    271 # $1: system tag (e.g. linux-x86)
    272 tag_to_arch ()
    273 {
    274     local RET
    275     case $1 in
    276         windows|*-x86) RET=x86;;
    277         *-x86_64) RET=x86_64;;
    278     esac
    279     echo $RET
    280 }
    281 
    282 # $1: system tag (e.g. linux-x86)
    283 tag_to_bits ()
    284 {
    285     local RET
    286     case $1 in
    287         windows|*-x86) RET=32;;
    288         *-x86_64) RET=64;;
    289     esac
    290     echo $RET
    291 }
    292 
    293 if [ "$NO_COLOR" ]; then
    294     COLOR_GREEN=
    295     COLOR_PURPLE=
    296     COLOR_CYAN=
    297     COLOR_END=
    298 else
    299     COLOR_GREEN="\e[32m"
    300     COLOR_PURPLE="\e[35m"
    301     COLOR_CYAN="\e[36m"
    302     COLOR_END="\e[0m"
    303 fi
    304 
    305 # Pretty printing with colors!
    306 host_text ()
    307 {
    308     printf "[${COLOR_GREEN}${HOST}${COLOR_END}]"
    309 }
    310 
    311 toolchain_text ()
    312 {
    313     printf "[${COLOR_PURPLE}${TOOLCHAIN}${COLOR_END}]"
    314 }
    315 
    316 target_text ()
    317 {
    318     printf "[${COLOR_CYAN}${TARGET}${COLOR_END}]"
    319 }
    320 
    321 arch_text ()
    322 {
    323     # Print arch name in cyan
    324     printf "[${COLOR_CYAN}${ARCH}${COLOR_END}]"
    325 }
    326 
    327 # We're going to cheat a little here. If we're only building a linux-x86
    328 # on a linux-x86_64 machine, we want to change the value of BUILD_TAG
    329 # to linux-x86 instead to speed-up the build.
    330 #
    331 # More generally speaking, we need to verify that if:
    332 #   - we build a $BUILD_OS-x86 toolchain on a $BUILD_OS-x86_64 machine
    333 #   - we don't want to build $BUILD_OS-x86_64 either.
    334 #
    335 # Then we can change our BUILD values to $BUILD_OS-x86
    336 # This assumes that the build machine's toolchain can generate both
    337 # 32-bit and 64-bit binaries with either -m32 or -m64
    338 #
    339 BUILD_BUILD_32=
    340 BUILD_BUILD_64=
    341 for SYSTEM in $HOST_SYSTEMS; do
    342     if [ "$(tag_to_os $SYSTEM)" = "$BUILD_OS" ]; then
    343         BUILD_BUILD_OS=true
    344         case $(tag_to_bits $SYSTEM) in
    345             32) BUILD_BUILD_32=true;;
    346             64) BUILD_BUILD_64=true;;
    347         esac
    348     fi
    349 done
    350 
    351 case $(tag_to_bits $BUILD_TAG) in
    352     64)
    353         # Building on a 64-bit machine
    354         if [ "$BUILD_BUILD_32" -a -z "$BUILD_BUILD_64" ]; then
    355             # Ok, we want to build a 32-bit toolchain on a 64-bit machine
    356             # So cheat a little now :-)
    357             BUILD_ARCH=x86
    358             BUILD_TAG=$BUILD_OS-$BUILD_ARCH
    359             dump "Forcing build config: $BUILD_TAG"
    360         fi
    361         ;;
    362 esac
    363 
    364 BUILD_BITS=$(tag_to_bits $BUILD_TAG)
    365 
    366 # On Darwin, parallel installs of certain libraries do not work on
    367 # some multi-core machines. So define NUM_BUILD_JOBS as 1 on this
    368 # platform.
    369 case $BUILD_OS in
    370     darwin) NUM_INSTALL_JOBS=1;;
    371     *) NUM_INSTALL_JOBS=$NUM_JOBS;;
    372 esac
    373 
    374 extract_version ()
    375 {
    376     echo $1 | tr '-' '\n' | tail -1
    377 }
    378 
    379 # Given an input string of the form <foo>-<bar>-<version>, where
    380 # <version> can be <major>.<minor>, extract <major>
    381 #
    382 # $1: versioned name (e.g. arm-linux-androideabi-4.4.3)
    383 # Out: major version (e.g. 4)
    384 #
    385 # Examples:  arm-linux-androideabi-4.4.3 -> 4
    386 #            gmp-0.81 -> 0
    387 #
    388 extract_major_version ()
    389 {
    390     local RET=$(extract_version $1 | cut -d . -f 1)
    391     RET=${RET:-0}
    392     echo $RET
    393 }
    394 
    395 # Same as extract_major_version, but for the minor version number
    396 # $1: versioned named
    397 # Out: minor version
    398 #
    399 extract_minor_version ()
    400 {
    401     local RET=$(extract_version $1 | cut -d . -f 2)
    402     RET=${RET:-0}
    403     echo $RET
    404 }
    405 
    406 # Compare two version numbers and only succeeds if the first one is
    407 # greather or equal than the second one.
    408 #
    409 # $1: first version (e.g. 4.4.3)
    410 # $2: second version (e.g. 4.6)
    411 #
    412 # Example: version_is_greater_than 4.6 4.4.3 --> success
    413 #
    414 version_is_greater_than ()
    415 {
    416     local A_MAJOR A_MINOR B_MAJOR B_MINOR
    417     A_MAJOR=$(extract_major_version $1)
    418     B_MAJOR=$(extract_major_version $2)
    419 
    420     if [ $A_MAJOR -lt $B_MAJOR ]; then
    421         return 1
    422     elif [ $A_MAJOR -gt $B_MAJOR ]; then
    423         return 0
    424     fi
    425 
    426     # We have A_MAJOR == B_MAJOR here
    427 
    428     A_MINOR=$(extract_minor_version $1)
    429     B_MINOR=$(extract_minor_version $2)
    430 
    431     if [ $A_MINOR -lt $B_MINOR ]; then
    432         return 1
    433     else
    434         return 0
    435     fi
    436 }
    437 
    438 tag_to_config_triplet ()
    439 {
    440     local RET
    441     case $1 in
    442         linux-x86) RET=i686-linux-gnu;;
    443         linux-x86_64) RET=x86_64-linux-gnu;;
    444         darwin-x86) RET=i686-apple-darwin;;
    445         darwin-x86_64) RET=x86_64-apple-darwin;;
    446         windows|windows-x86) RET=i586-pc-mingw32msvc;;
    447         windows-x86_64) RET=x86_64-w64-mingw32;;
    448     esac
    449     echo "$RET"
    450 }
    451 
    452 run_on_setup ()
    453 {
    454     if [ "$PHASE" = setup ]; then
    455         run "$@"
    456     fi
    457 }
    458 
    459 setup_build ()
    460 {
    461     run_on_setup mkdir -p "$BUILD_DIR"
    462     if [ -n "$FORCE" ]; then
    463         rm -rf "$BUILD_DIR"/*
    464     fi
    465 
    466     TOP_BUILD_DIR=$BUILD_DIR
    467 
    468     setup_default_log_file $BUILD_DIR/build.log
    469 
    470     WRAPPERS_DIR="$BUILD_DIR/toolchain-wrappers"
    471     run_on_setup mkdir -p "$WRAPPERS_DIR" && run_on_setup rm -rf "$WRAPPERS_DIR/*"
    472 
    473     STAMPS_DIR="$BUILD_DIR/timestamps"
    474     run_on_setup mkdir -p "$STAMPS_DIR"
    475     if [ -n "$FORCE" ]; then
    476         run_on_setup rm -f "$STAMPS_DIR"/*
    477     fi
    478 
    479     if [ "$PACKAGE_DIR" ]; then
    480         mkdir -p "$PACKAGE_DIR"
    481         fail_panic "Can't create packaging directory: $PACKAGE_DIR"
    482     fi
    483 
    484     BUILD=$(tag_to_config_triplet $BUILD_TAG)
    485 }
    486 
    487 stamps_do ()
    488 {
    489     local NAME=$1
    490     shift
    491     if [ ! -f "$STAMPS_DIR/$NAME" ]; then
    492         "$@"
    493         fail_panic
    494         mkdir -p "$STAMPS_DIR" && touch "$STAMPS_DIR/$NAME"
    495     fi
    496 }
    497 
    498 # Check that a given compiler generates code correctly
    499 #
    500 # This is to detect bad/broken toolchains, e.g. amd64-mingw32msvc
    501 # is totally broken on Ubuntu 10.10 and 11.04
    502 #
    503 # $1: compiler
    504 # $2: optional extra flags
    505 #
    506 check_compiler ()
    507 {
    508     local CC="$1"
    509     local TMPC=/tmp/build-host-gcc-$USER-$$.c
    510     local TMPE=${TMPC%%.c}
    511     local TMPL=$TMPC.log
    512     local RET
    513     shift
    514     cat > $TMPC <<EOF
    515 int main(void) { return 0; }
    516 EOF
    517     log_n "Checking compiler code generation ($CC)... "
    518     $CC -o $TMPE $TMPC "$@" >$TMPL 2>&1
    519     RET=$?
    520     rm -f $TMPC $TMPE $TMPL
    521     if [ "$RET" = 0 ]; then
    522         log "yes"
    523     else
    524         log "no"
    525     fi
    526     return $RET
    527 }
    528 
    529 
    530 # $1: toolchain install dir
    531 # $2: toolchain prefix, no trailing dash (e.g. arm-linux-androideabi)
    532 # $3: optional -m32 or -m64.
    533 try_host_fullprefix ()
    534 {
    535     local PREFIX="$1/bin/$2"
    536     shift; shift;
    537     if [ -z "$HOST_FULLPREFIX" ]; then
    538         local GCC="$PREFIX-gcc"
    539         if [ -f "$GCC" ]; then
    540             if check_compiler "$GCC" "$@"; then
    541                 HOST_FULLPREFIX="${GCC%%gcc}"
    542                 dump "$(host_text) Using host gcc: $GCC $@"
    543             else
    544                 dump "$(host_text) Ignoring broken host gcc: $GCC $@"
    545             fi
    546         fi
    547     fi
    548 }
    549 
    550 # $1: host prefix, no trailing slash (e.g. i686-linux-android)
    551 # $2: optional compiler args (should be empty, -m32 or -m64)
    552 try_host_prefix ()
    553 {
    554     local PREFIX="$1"
    555     shift
    556     if [ -z "$HOST_FULLPREFIX" ]; then
    557         local GCC="$(which $PREFIX-gcc 2>/dev/null)"
    558         if [ "$GCC" -a -e "$GCC" ]; then
    559             if check_compiler "$GCC" "$@"; then
    560                 HOST_FULLPREFIX=${GCC%%gcc}
    561                 dump "$(host_text) Using host gcc: ${HOST_FULLPREFIX}gcc $@"
    562             else
    563                 dump "$(host_text) Ignoring broken host gcc: $GCC $@"
    564             fi
    565         fi
    566     fi
    567 }
    568 
    569 # Used to determine the minimum possible Darwin version that a Darwin SDK
    570 # can target. This actually depends from the host architecture.
    571 # $1: Host architecture name
    572 # out: SDK version number (e.g. 10.4 or 10.5)
    573 darwin_arch_to_min_version ()
    574 {
    575   if [ "$DARWIN_MIN_VERSION" ]; then
    576     echo "$DARWIN_MIN_VERSION"
    577   elif [ "$1" = "x86" ]; then
    578     echo "10.4"
    579   else
    580     echo "10.5"
    581   fi
    582 }
    583 
    584 # Use the check for the availability of a compatibility SDK in Darwin
    585 # this can be used to generate binaries compatible with either Tiger or
    586 # Leopard.
    587 #
    588 # $1: SDK root path
    589 # $2: Darwin architecture
    590 check_darwin_sdk ()
    591 {
    592     if [ -d "$1" -a -z "$HOST_CFLAGS" ] ; then
    593         local MINVER=$(darwin_arch_to_min_version $2)
    594         HOST_CFLAGS="-isysroot $1 -mmacosx-version-min=$MINVER -DMAXOSX_DEPLOYEMENT_TARGET=$MINVER"
    595         HOST_CXXFLAGS=$HOST_CFLAGS
    596         HOST_LDFLAGS="-syslibroot $1 -mmacosx-version-min=$MINVER"
    597         dump "Generating $MINVER-compatible binaries."
    598         return 0  # success
    599     fi
    600     return 1
    601 }
    602 
    603 # Check that a given compiler generates 32 or 64 bit code.
    604 # $1: compiler full path (.e.g  /path/to/fullprefix-gcc)
    605 # $2: 32 or 64
    606 # $3: extract compiler flags
    607 # Return: success iff the compiler generates $2-bits code
    608 check_compiler_bitness ()
    609 {
    610     local CC="$1"
    611     local BITS="$2"
    612     local TMPC=/tmp/build-host-gcc-bits-$USER-$$.c
    613     local TMPL=$TMPC.log
    614     local RET
    615     shift; shift;
    616     cat > $TMPC <<EOF
    617 /* this program will fail to compile if the compiler doesn't generate BITS-bits code */
    618 int tab[1-2*(sizeof(void*)*8 != BITS)];
    619 EOF
    620     dump_n "$(host_text) Checking that the compiler generates $BITS-bits code ($@)... "
    621     $CC -c -DBITS=$BITS -o /dev/null $TMPC $HOST_CFLAGS "$@" > $TMPL 2>&1
    622     RET=$?
    623     rm -f $TMPC $TMPL
    624     if [ "$RET" = 0 ]; then
    625         dump "yes"
    626     else
    627         dump "no"
    628     fi
    629     return $RET
    630 }
    631 
    632 # This function probes the system to find the best toolchain or cross-toolchain
    633 # to build binaries that run on a given host system. After that, it generates
    634 # a wrapper toolchain under $WRAPPERS_DIR with a prefix of ${HOST}-
    635 # where $HOST is a GNU configuration name.
    636 #
    637 # Important: this script might redefine $HOST to a different value!
    638 # Important: must be called after setup_build.
    639 #
    640 # $1: NDK system tag (e.g. linux-x86)
    641 #
    642 select_toolchain_for_host ()
    643 {
    644     local HOST_CFLAGS HOST_CXXFLAGS HOST_LDFLAGS HOST_FULLPREFIX DARWIN_ARCH
    645 
    646     # We do all the complex auto-detection magic in the setup phase,
    647     # then save the result in host-specific global variables.
    648     #
    649     # In the build phase, we will simply restore the values into the
    650     # global HOST_FULLPREFIX / HOST_BUILD_DIR
    651     # variables.
    652     #
    653 
    654     # Try to find the best toolchain to do that job, assuming we are in
    655     # a full Android platform source checkout, we can look at the prebuilts/
    656     # directory.
    657     case $1 in
    658         linux-x86)
    659             # If possible, automatically use our custom toolchain to generate
    660             # 32-bit executables that work on Ubuntu 8.04 and higher.
    661             try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" i686-linux
    662             try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.4.3" i686-linux
    663             try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3" i686-linux
    664             try_host_prefix i686-linux-gnu
    665             try_host_prefix i686-linux
    666             try_host_prefix x86_64-linux-gnu -m32
    667             try_host_prefix x86_64-linux -m32
    668             ;;
    669 
    670         linux-x86_64)
    671             # If possible, automaticaly use our custom toolchain to generate
    672             # 64-bit executables that work on Ubuntu 8.04 and higher.
    673             try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" x86_64-linux
    674             try_host_prefix x86_64-linux-gnu
    675             try_host_prefix x84_64-linux
    676             try_host_prefix i686-linux-gnu -m64
    677             try_host_prefix i686-linux -m64
    678             ;;
    679 
    680         darwin-*)
    681             DARWIN_ARCH=$(tag_to_arch $1)
    682             case $BUILD_OS in
    683                 darwin)
    684                     if [ "$DARWIN_SDK_VERSION" ]; then
    685                         # Compute SDK subdirectory name
    686                         case $DARWIN_SDK_VERSION in
    687                             10.4) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdku;;
    688                             *) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdk;;
    689                         esac
    690                         # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder.
    691                         check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_ARCH
    692                         check_darwin_sdk /Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_ARCH
    693                     else
    694                         # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder.
    695                         check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk $DARWIN_ARCH
    696                         check_darwin_sdk /Developer/SDKs/MacOSX10.7.sdk  $DARWIN_ARCH
    697                         check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk  $DARWIN_ARCH
    698                         # NOTE: The 10.5.sdk on Lion is buggy and cannot build basic C++ programs
    699                         #check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk  $DARWIN_ARCH
    700                         # NOTE: The 10.4.sdku is not available anymore and could not be tested.
    701                         #check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku $DARWIN_ARCH
    702                     fi
    703                     if [ -z "$HOST_CFLAGS" ]; then
    704                         local version="$(sw_vers -productVersion)"
    705                         log "Generating $version-compatible binaries!"
    706                     fi
    707                     ;;
    708                 *)
    709                     if [ -z "$DARWIN_TOOLCHAIN" -o -z "$DARWIN_SYSROOT" ]; then
    710                         dump "If you want to build Darwin binaries on a non-Darwin machine,"
    711                         dump "Please define DARWIN_TOOLCHAIN to name it, and DARWIN_SYSROOT to point"
    712                         dump "to the SDK. For example:"
    713                         dump ""
    714                         dump "   DARWIN_TOOLCHAIN=\"i686-apple-darwin11\""
    715                         dump "   DARWIN_SYSROOT=\"~/darwin-cross/MacOSX10.7.sdk\""
    716                         dump "   export DARWIN_TOOLCHAIN DARWIN_SYSROOT"
    717                         dump ""
    718                         exit 1
    719                     fi
    720                     local DARWINMINVER=$(darwin_arch_to_min_version $2)
    721                     check_darwin_sdk $DARWIN_SYSROOT $DARWINARCH
    722                     try_host_prefix "$DARWIN_TOOLCHAIN" -m$(tag_to_bits $1) --sysroot "$DARWIN_SYSROOT"
    723                     if [ -z "$HOST_FULLPREFIX" ]; then
    724                         dump "It looks like $DARWIN_TOOLCHAIN-gcc is not in your path, or does not work correctly!"
    725                         exit 1
    726                     fi
    727                     dump "Using darwin cross-toolchain: ${HOST_FULLPREFIX}gcc"
    728                     ;;
    729             esac
    730             ;;
    731 
    732         windows|windows-x86)
    733             case $BUILD_OS in
    734                 linux)
    735                     # We favor these because they are more recent, and because
    736                     # we have a script to rebuild them from scratch. See
    737                     # build-mingw64-toolchain.sh.
    738                     try_host_prefix x86_64-w64-mingw32 -m32
    739                     try_host_prefix i686-w64-mingw32
    740                     # Typically provided by the 'mingw32' package on Debian
    741                     # and Ubuntu systems.
    742                     try_host_prefix i586-mingw32msvc
    743                     # Special note for Fedora: this distribution used
    744                     # to have a mingw32-gcc package that provided a 32-bit
    745                     # only cross-toolchain named i686-pc-mingw32.
    746                     # Later versions of the distro now provide a new package
    747                     # named mingw-gcc which provides i686-w64-mingw32 and
    748                     # x86_64-w64-mingw32 instead.
    749                     try_host_prefix i686-pc-mingw32
    750                     if [ -z "$HOST_FULLPREFIX" ]; then
    751                         dump "There is no Windows cross-compiler. Ensure that you"
    752                         dump "have one of these installed and in your path:"
    753                         dump "   x86_64-w64-mingw32-gcc  (see build-mingw64-toolchain.sh)"
    754                         dump "   i686-w64-mingw32-gcc    (see build-mingw64-toolchain.sh)"
    755                         dump "   i586-mingw32msvc-gcc    ('mingw32' Debian/Ubuntu package)"
    756                         dump "   i686-pc-mingw32         (on Fedora)"
    757                         dump ""
    758                         exit 1
    759                     fi
    760                     # Adjust $HOST to match the toolchain to ensure proper builds.
    761                     # I.e. chose configuration triplets that are known to work
    762                     # with the gmp/mpfr/mpc/binutils/gcc configure scripts.
    763                     case $HOST_FULLPREFIX in
    764                         *-mingw32msvc-*|i686-pc-mingw32)
    765                             HOST=i586-pc-mingw32msvc
    766                             ;;
    767                         *)
    768                             HOST=i686-w64-mingw32msvc
    769                             ;;
    770                     esac
    771                     ;;
    772                 *) panic "Sorry, this script only supports building windows binaries on Linux."
    773                 ;;
    774             esac
    775             ;;
    776 
    777         windows-x86_64)
    778             # Sanity check for GMP which doesn't build with x86_64-w64-mingw32-gcc
    779             # before 5.0. We already have 5.0.5 in AOSP toolchain source tree, so
    780             # suggest it here.
    781             if ! version_is_greater_than $GMP_VERSION 5.0; then
    782                 dump "You cannot build a 64-bit Windows toolchain with this version of libgmp."
    783                 dump "Please use --gmp-version=5.0.5 to fix this."
    784                 exit 1
    785             fi
    786             case $BUILD_OS in
    787                 linux)
    788                     # See comments above for windows-x86
    789                     try_host_prefix x86_64-w64-mingw32
    790                     try_host_prefix i686-w64-mingw32 -m64
    791                     # Beware that this package is completely broken on many
    792                     # versions of no vinegar Ubuntu (i.e. it fails at building trivial
    793                     # programs).
    794                     try_host_prefix amd64-mingw32msvc
    795                     # There is no x86_64-pc-mingw32 toolchain on Fedora.
    796                     if [ -z "$HOST_FULLPREFIX" ]; then
    797                         dump "There is no Windows cross-compiler in your path. Ensure you"
    798                         dump "have one of these installed and in your path:"
    799                         dump "   x86_64-w64-mingw32-gcc  (see build-mingw64-toolchain.sh)"
    800                         dump "   i686-w64-mingw32-gcc    (see build-mingw64-toolchain.sh)"
    801                         dump "   amd64-mingw32msvc-gcc   (Debian/Ubuntu - broken until Ubuntu 11.10)"
    802                         dump ""
    803                         exit 1
    804                     fi
    805                     # See comment above for windows-x86
    806                     case $HOST_FULLPREFIX in
    807                         *-mingw32msvc*)
    808                             # Actually, this has never been tested.
    809                             HOST=amd64-pc-mingw32msvc
    810                             ;;
    811                         *)
    812                             HOST=x86_64-w64-mingw32
    813                             ;;
    814                     esac
    815                     ;;
    816 
    817                 *) panic "Sorry, this script only supports building windows binaries on Linux."
    818                 ;;
    819             esac
    820             ;;
    821     esac
    822 
    823     mkdir -p "$(host_build_dir)"
    824     if [ "$FORCE" ]; then
    825         rm -rf "$(host_build_dir)"/*
    826     fi
    827 
    828     # Determine the default bitness of our compiler. It it doesn't match
    829     # HOST_BITS, tries to see if it supports -m32 or -m64 to change it.
    830     if ! check_compiler_bitness ${HOST_FULLPREFIX}gcc $HOST_BITS; then
    831         TRY_CFLAGS=
    832         case $HOST_BITS in
    833             32) TRY_CFLAGS=-m32;;
    834             64) TRY_CFLAGS=-m64;;
    835         esac
    836         if ! check_compiler_bitness ${HOST_FULLPREFIX}gcc $HOST_BITS $TRY_CFLAGS; then
    837             panic "Can't find a way to generate $HOST_BITS binaries with this compiler: ${HOST_FULLPREFIX}gcc"
    838         fi
    839         HOST_CFLAGS=$HOST_CFLAGS" "$TRY_CFLAGS
    840         HOST_CXXFLAGS=$HOST_CXXFLAGS" "$TRY_CFLAGS
    841     fi
    842 
    843     # Support for ccache, to speed up rebuilds.
    844     DST_PREFIX=$HOST_FULLPREFIX
    845     if [ "$NDK_CCACHE" ]; then
    846         DST_PREFIX="$NDK_CCACHE $HOST_FULLPREFIX"
    847     fi
    848 
    849     # We're going to generate a wrapper toolchain with the $HOST prefix
    850     # i.e. if $HOST is 'i686-linux-gnu', then we're going to generate a
    851     # wrapper toolchain named 'i686-linux-gnu-gcc' that will redirect
    852     # to whatever HOST_FULLPREFIX points to, with appropriate modifier
    853     # compiler/linker flags.
    854     #
    855     # This helps tremendously getting stuff to compile with the GCC
    856     # configure scripts.
    857     #
    858     run $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh "$WRAPPERS_DIR" \
    859         --src-prefix="$HOST-" \
    860         --dst-prefix="$DST_PREFIX" \
    861         --cflags="$HOST_CFLAGS" \
    862         --cxxflags="$HOST_CXXFLAGS" \
    863         --ldflags="$HOST_LDFLAGS"
    864 }
    865 
    866 # Call this before anything else to setup a few important variables that are
    867 # used consistently to build any host-specific binaries.
    868 #
    869 # $1: Host system name (e.g. linux-x86), this is the name of the host system
    870 #     where the generated GCC binaries will run, not the current machine's
    871 #     type (this one is in $ORIGINAL_HOST_TAG instead).
    872 #
    873 setup_build_for_host ()
    874 {
    875     local HOST_VARNAME=$(dashes_to_underscores $1)
    876     local HOST_VAR=_HOST_${HOST_VARNAME}
    877 
    878     # Determine the host configuration triplet in $HOST
    879     HOST=$(tag_to_config_triplet $1)
    880     HOST_OS=$(tag_to_os $1)
    881     HOST_ARCH=$(tag_to_arch $1)
    882     HOST_BITS=$(tag_to_bits $1)
    883     HOST_TAG=$1
    884 
    885     # Note: since select_toolchain_for_host can change the value of $HOST
    886     # we need to save it in a variable to later get the correct one when
    887     # this function is called again.
    888     if [ -z "$(var_value ${HOST_VAR}_SETUP)" ]; then
    889         select_toolchain_for_host $1
    890         var_assign ${HOST_VAR}_CONFIG $HOST
    891         var_assign ${HOST_VAR}_SETUP true
    892     else
    893         HOST=$(var_value ${HOST_VAR}_CONFIG)
    894     fi
    895 }
    896 
    897 # Returns the location of all $HOST specific files (build and install)
    898 host_build_dir ()
    899 {
    900     echo "$TOP_BUILD_DIR/$HOST"
    901 }
    902 
    903 # Return the location of the build directory for a specific component
    904 # $1: component name (e.g. gmp-4.2.4)
    905 host_build_dir_for ()
    906 {
    907     echo "$(host_build_dir)/build-$1"
    908 }
    909 
    910 # Returns the install location of the $HOST pre-reqs libraries
    911 host_prereqs_install_dir ()
    912 {
    913     echo "$(host_build_dir)/temp-prereqs"
    914 }
    915 
    916 # Returns the install location of the $HOST binutils cross-toolchain
    917 host_binutils_install_dir ()
    918 {
    919     echo "$(host_build_dir)/temp-binutils-$BINUTILS_VERSION-$TARGET"
    920 }
    921 
    922 # Returns the install location of the $HOST binutils cross-toolchain
    923 build_binutils_install_dir ()
    924 {
    925     echo "$TOP_BUILD_DIR/$BUILD/temp-binutils-$BINUTILS_VERSION-$TARGET"
    926 }
    927 
    928 # Returns the install location of the $HOST gcc cross-toolchain
    929 host_gcc_install_dir ()
    930 {
    931     echo "$(host_build_dir)/temp-$TOOLCHAIN"
    932 }
    933 
    934 # Returns the install location of the $BUILD gcc cross-toolchain
    935 build_gcc_install_dir ()
    936 {
    937     echo "$TOP_BUILD_DIR/$BUILD/temp-$TOOLCHAIN"
    938 }
    939 
    940 
    941 # Location of the host sysroot used during the build
    942 host_sysroot ()
    943 {
    944     # This must be a sub-directory of $(host_gcc_install_dir)
    945     # to generate relocatable binaries that are used by
    946     # standalone versions of the toolchain.
    947     #
    948     # If you change this, you will need to modify make-standalone-toolchain.sh
    949     # as well.
    950     #
    951     echo "$(host_gcc_install_dir)/sysroot"
    952 }
    953 
    954 # Returns the final install location of the $HOST toolchain
    955 # This ones contains the binutils binaries, the gcc ones,
    956 # the target libraries, but does *not* include the sysroot
    957 # and other stuff (e.g. documentation like info or man files).
    958 #
    959 host_gcc_final_dir ()
    960 {
    961     echo "$(host_build_dir)/final-$TOOLCHAIN"
    962 }
    963 
    964 setup_build_for_toolchain ()
    965 {
    966     GCC_VERSION=$(extract_version $1)
    967     BINUTILS_VERSION=$(get_default_binutils_version_for_gcc $1)
    968 
    969     TARGET_ARCH=$(echo $1 | cut -d - -f 1)
    970 
    971     # NOTE: The 'mipsel' toolchain architecture name maps to the 'mips'
    972     # NDK architecture name.
    973     case $TARGET_ARCH in
    974         arm) TARGET=arm-linux-androideabi;;
    975         x86) TARGET=i686-linux-android;;
    976         mips|mipsel) TARGET=mipsel-linux-android; TARGET_ARCH=mips;;
    977         *) panic "Unknown target toolchain architecture: $TARGET_ARCH"
    978     esac
    979 
    980     # MPC is only needed starting with GCC 4.5
    981     HOST_NEED_MPC=
    982     if version_is_greater_than $GCC_VERSION 4.5; then
    983         HOST_NEED_MPC=true
    984     fi
    985 
    986     # TODO: We will need to place these under
    987     #      $NDK_DIR/prebuilts/$HOST/android-$TARGET_ARCH-gcc-$GCC_VERSION/
    988     #      in a future patch.
    989     TOOLCHAIN_SUB_DIR=toolchains/$TOOLCHAIN/prebuilt/$HOST_TAG
    990     TOOLCHAIN_INSTALL_DIR=$NDK_DIR/$TOOLCHAIN_SUB_DIR
    991 
    992     # These will go into CFLAGS_FOR_TARGET and others during the build
    993     # of GCC target libraries.
    994     if [ -z "$NO_STRIP" ]; then
    995         TARGET_CFLAGS="-O2 -Os -fomit-frame-pointer -s"
    996     else
    997         TARGET_CFLAGS="-O2 -Os -g"
    998     fi
    999 
   1000     TARGET_CXXFLAGS=$TARGET_CFLAGS
   1001     TARGET_LDFLAGS=""
   1002 
   1003     case $TARGET_ARCH in
   1004         x86)
   1005         TARGET_CFLAGS=$TARGET_CFLAGS" \
   1006         -DANDROID -D__ANDROID__ -Ulinux \
   1007         -fPIC -Wa,--noexecstack -m32 -fstack-protector \
   1008         -W -Wall -Werror=address -Werror=format-security -Werror=non-virtual-dtor -Werror=return-type \
   1009         -Werror=sequence-point -Winit-self -Wno-multichar -Wno-unused -Wpointer-arith -Wstrict-aliasing=2 \
   1010         -fexceptions -ffunction-sections -finline-functions \
   1011         -finline-limit=300 -fmessage-length=0 -fno-inline-functions-called-once \
   1012         -fno-strict-aliasing -frtti \
   1013         -fstrict-aliasing -funswitch-loops -funwind-tables \
   1014         -march=i686 -mtune=atom -mbionic -mfpmath=sse -mstackrealign -DUSE_SSE2"
   1015 
   1016         TARGET_LDFLAGS=$TARGET_LDFLAGS" \
   1017         -m32 -O2 -g -fPIC \
   1018         -nostartfiles \
   1019         -Wl,-z,noexecstack -Wl,--gc-sections -nostdlib \
   1020         -fexceptions -frtti -fstrict-aliasing -ffunction-sections -finline-functions  \
   1021         -finline-limit=300 -fno-inline-functions-called-once \
   1022         -funswitch-loops -funwind-tables -mstackrealign \
   1023         -ffunction-sections -funwind-tables -fmessage-length=0 \
   1024         -march=i686 -mstackrealign -mfpmath=sse -mbionic \
   1025         -Wno-multichar -Wl,-z,noexecstack -Werror=format-security -Wstrict-aliasing=2 \
   1026         -W -Wall -Wno-unused -Winit-self -Wpointer-arith -Werror=return-type -Werror=non-virtual-dtor \
   1027         -Werror=address -Werror=sequence-point \
   1028         -Werror=format-security -Wl,--no-undefined"
   1029 
   1030         # The following was removed from the assignment above because we can't build these object files
   1031         # unless we already have a working binutils / assembler for them. I believe these are now handled
   1032         # by the right gcc config files now. Also TARGET_SYSROOT isn't defined yet.
   1033         #
   1034         #-nostartfiles $TARGET_SYSROOT/usr/lib/crtbegin_dynamic.o $TARGET_SYSROOT/usr/lib/crtend_android.o"
   1035         ;;
   1036 
   1037         mips)
   1038         # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
   1039         # You can't really build these separately at the moment.
   1040         # Add -fpic, because MIPS NDK will need to link .a into .so.
   1041         TARGET_CFLAGS=$TARGET_CFLAGS" -fexceptions -fpic"
   1042         TARGET_CXXFLAGS=$TARGET_CXXFLAGS" -frtti -fpic"
   1043         ;;
   1044     esac
   1045 }
   1046 
   1047 # This function is used to setup the build environment whenever we
   1048 # generate host-specific binaries.
   1049 #
   1050 setup_host_env ()
   1051 {
   1052     CC=$HOST-gcc
   1053     CXX=$HOST-g++
   1054     LD=$HOST-ld
   1055     AR=$HOST-ar
   1056     AS=$HOST-as
   1057     RANLIB=$HOST-ranlib
   1058     NM=$HOST-nm
   1059     STRIP=$HOST-strip
   1060     STRINGS=$HOST-strings
   1061     export CC CXX AS LD AR RANLIB STRIP STRINGS NM
   1062 
   1063     CFLAGS=
   1064     CXXFLAGS=
   1065     LDFLAGS=
   1066     if [ -z "$NO_STRIP" ]; then
   1067         CFLAGS="-O2 -Os -fomit-frame-pointer -s"
   1068         CXXFLAGS=$CFLAGS
   1069     fi
   1070 
   1071     # This should only used when building the target GCC libraries
   1072     CFLAGS_FOR_TARGET=$TARGET_CFLAGS
   1073     CXXFLAGS_FOR_TARGET=$TARGET_CXXFLAGS
   1074     LDFLAGS_FOR_TARGET=$TARGET_LDFLAGS
   1075 
   1076     export CFLAGS CXXFLAGS LDFLAGS CFLAGS_FOR_TARGET CXXFLAGS_FOR_TARGET LDFLAGS_FOR_TARGET
   1077 
   1078     PATH=$WRAPPERS_DIR:$PATH
   1079 }
   1080 
   1081 # $1: NDK architecture name (e.g. 'arm')
   1082 arch_sysroot_install_dir ()
   1083 {
   1084     echo "$BUILD_DIR/arch-$1/sysroot"
   1085 }
   1086 
   1087 # $1: NDK architecture name (e.g. 'arm')
   1088 arch_sysroot_dir ()
   1089 {
   1090     echo "$(arch_sysroot_install_dir $1)/$(get_default_platform_sysroot_for_arch $1)"
   1091 }
   1092 
   1093 # $1: architecture name
   1094 gen_minimal_sysroot ()
   1095 {
   1096     local ARCH=$1
   1097     local INSTALL_DIR=$(arch_sysroot_install_dir $ARCH)
   1098 
   1099     dump "$(arch_text) Generating minimal sysroot."
   1100     run2 $NDK_BUILDTOOLS_PATH/gen-platforms.sh --minimal --arch=$ARCH --dst-dir="$INSTALL_DIR"
   1101 }
   1102 
   1103 
   1104 # $1: gmp version
   1105 extract_gmp_sources ()
   1106 {
   1107     local SRC_DIR="$TOP_BUILD_DIR/temp-src"
   1108 
   1109     dump "Extracting gmp-$1"
   1110     run2 mkdir -p "$SRC_DIR" &&
   1111     run2 tar xjf "$TOOLCHAIN_SRC_DIR/gmp/gmp-$1.tar.bz2" -C "$SRC_DIR"
   1112 }
   1113 
   1114 # $1: gmp version
   1115 build_gmp ()
   1116 {
   1117     local SRC_DIR="$TOP_BUILD_DIR/temp-src/gmp-$1"
   1118     local INSTALL_DIR="$(host_prereqs_install_dir)"
   1119     local BUILD_DIR
   1120 
   1121     stamps_do extract-gmp-$1 extract_gmp_sources $1
   1122 
   1123     dump "$(host_text) Building gmp-$1"
   1124     (
   1125         setup_host_env &&
   1126         BUILD_DIR="$(host_build_dir_for gmp-$GMP_VERSION)" &&
   1127         run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* &&
   1128         cd "$BUILD_DIR" &&
   1129         run2 "$SRC_DIR"/configure \
   1130             --prefix=$INSTALL_DIR \
   1131             --build=$BUILD \
   1132             --host=$HOST \
   1133             --disable-shared &&
   1134         run2 make -j$NUM_JOBS &&
   1135         run2 make install -j$NUM_INSTALL_JOBS
   1136     )
   1137     return $?
   1138 }
   1139 
   1140 extract_mpfr_sources ()
   1141 {
   1142     local SRC_DIR="$TOP_BUILD_DIR/temp-src"
   1143 
   1144     dump "Extracting mpfr-$1"
   1145     run2 mkdir -p "$SRC_DIR" &&
   1146     run2 tar xjf "$TOOLCHAIN_SRC_DIR/mpfr/mpfr-$1.tar.bz2" -C "$SRC_DIR"
   1147 }
   1148 
   1149 # $1: mpfr-version
   1150 build_mpfr ()
   1151 {
   1152     local SRC_DIR="$TOP_BUILD_DIR/temp-src/mpfr-$1"
   1153     local INSTALL_DIR="$(host_prereqs_install_dir)"
   1154     local BUILD_DIR
   1155 
   1156     stamps_do extract-mpfr-$MPFR_VERSION extract_mpfr_sources $1
   1157 
   1158     stamps_do build-gmp-$GMP_VERSION-$HOST build_gmp $GMP_VERSION
   1159 
   1160     dump "$(host_text) Building mpfr-$1"
   1161     (
   1162         setup_host_env &&
   1163         BUILD_DIR="$(host_build_dir_for mpfr-$MPFR_VERSION)" &&
   1164         run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* &&
   1165         cd $BUILD_DIR &&
   1166         run2 "$SRC_DIR"/configure \
   1167             --prefix=$INSTALL_DIR \
   1168             --build=$BUILD \
   1169             --host=$HOST \
   1170             --disable-shared \
   1171             --with-gmp=$INSTALL_DIR &&
   1172         run2 make -j$NUM_JOBS &&
   1173         run2 make -j$NUM_INSTALL_JOBS install
   1174     )
   1175     return $?
   1176 }
   1177 
   1178 # $1: mpc-version
   1179 extract_mpc_sources ()
   1180 {
   1181     local SRC_DIR="$TOP_BUILD_DIR/temp-src"
   1182 
   1183     dump "Extracting mpc-$1"
   1184     run2 mkdir -p "$SRC_DIR" &&
   1185     run2 tar xzf "$TOOLCHAIN_SRC_DIR/mpc/mpc-$1.tar.gz" -C "$SRC_DIR"
   1186 }
   1187 
   1188 
   1189 # $1: mpc-version
   1190 build_mpc ()
   1191 {
   1192     local SRC_DIR="$TOP_BUILD_DIR/temp-src/mpc-$1"
   1193     local INSTALL_DIR="$(host_prereqs_install_dir)"
   1194     local BUILD_DIR
   1195 
   1196     stamps_do extract-mpc-$1 extract_mpc_sources $1
   1197 
   1198     stamps_do build-mpfr-$MPFR_VERSION-$HOST build_mpfr $MPFR_VERSION
   1199 
   1200     dump "$(host_text) Building mpc-$1"
   1201     (
   1202         setup_host_env &&
   1203         BUILD_DIR="$(host_build_dir_for mpc-$MPC_VERSION)" &&
   1204         run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* &&
   1205         cd $BUILD_DIR &&
   1206         run2 "$SRC_DIR"/configure \
   1207             --prefix=$INSTALL_DIR \
   1208             --build=$BUILD \
   1209             --host=$HOST \
   1210             --disable-shared \
   1211             --with-gmp=$INSTALL_DIR \
   1212             --with-mpfr=$INSTALL_DIR &&
   1213         run2 make -j$NUM_JOBS &&
   1214         run2 make -j$NUM_INSTALL_JOBS install
   1215     )
   1216     return $?
   1217 }
   1218 
   1219 # Build all pre-required host libraries (gmp, mpfr, etc...) that are needed
   1220 # by binutils and gcc, as static libraries that will be placed under
   1221 # $HOST_BUILD_DIR/temp-install
   1222 #
   1223 # $1: toolchain source directory
   1224 #
   1225 build_host_prereqs ()
   1226 {
   1227     local INSTALL_DIR="$(host_prereqs_install_dir)"
   1228     local ARGS
   1229 
   1230     ARGS=" --with-gmp=$INSTALL_DIR --with-mpfr=$INSTALL_DIR"
   1231 
   1232     # Only build MPC when we need it.
   1233     if [ "$HOST_NEED_MPC" ]; then
   1234         ARGS=$ARGS" --with-mpc=$INSTALL_DIR"
   1235         stamps_do build-mpc-$MPC_VERSION-$HOST build_mpc $MPC_VERSION
   1236     else
   1237         stamps_do build-mpfr-$MPFR_VERSION-$HOST build_mpfr $MPFR_VERSION
   1238     fi
   1239 
   1240     # This gets used by build_host_binutils and others.
   1241     HOST_PREREQS_ARGS=$ARGS
   1242 }
   1243 
   1244 build_host_binutils ()
   1245 {
   1246     local SRC_DIR="$TOOLCHAIN_SRC_DIR/binutils/binutils-$BINUTILS_VERSION"
   1247     local INSTALL_DIR="$(host_binutils_install_dir)"
   1248     local PREREQS_INSTALL_DIR="$(host_prereqs_install_dir)"
   1249     local ARGS
   1250 
   1251     build_host_prereqs
   1252 
   1253     ARGS=" --with-gmp=$PREREQS_INSTALL_DIR --with-mpfr=$PREREQS_INSTALL_DIR"
   1254     if [ "$HOST_NEED_MPC" ]; then
   1255         ARGS=$ARGS" --with-mpc=$PREREQS_INSTALL_DIR"
   1256     fi
   1257 
   1258     LD_NAME=$DEFAULT_LD
   1259 
   1260     # Enable Gold globally. It can be built for all hosts.
   1261     BUILD_GOLD=true
   1262 
   1263     # Special case, gold is not ready for mips yet.
   1264     if [ "$TARGET" = "mipsel-linux-android" ]; then
   1265         BUILD_GOLD=
   1266     fi
   1267 
   1268     # Another special case, gold in binutils-2.21 for arch-x86 is buggy
   1269     # (i.e. when building the platform with it, the system doesn't boot)
   1270     #
   1271     if [ "$BINUTILS_VERSION" = "2.21" -a "$TARGET" = "i686-linux-android" ]; then
   1272         USE_LD_DEFAULT=true
   1273         BUILD_GOLD=
   1274     fi
   1275 
   1276     # Another special case. Not or 2.19, it wasn't ready
   1277     if [ "$BINUTILS_VERSION" = "2.19" ]; then
   1278         BUILD_GOLD=
   1279     fi
   1280 
   1281     if [ "$DEFAULT_LD" = "gold" -a -z "$BUILD_GOLD" ]; then
   1282         dump "$(host_text)$(target_text): Cannot build Gold for this toolchain!"
   1283         BUILD_GOLD=
   1284     fi
   1285 
   1286     # Ok, if the user *really* wants it, we're going to build Gold anyway.
   1287     # There are no guarantees about the correctness of the resulting binary.
   1288     # --default-ld still determines the default linker to use by the toolchain.
   1289     #
   1290     if [ "$FORCE_GOLD_BUILD" -a -z "$BUILD_GOLD" ]; then
   1291         dump "$(host_text)$(target_text): Warning: forcing build of potentially buggy Gold linker!"
   1292         BUILD_GOLD=true
   1293     fi
   1294 
   1295     # The BFD linker is always built, but to build Gold, we need a specific
   1296     # option for the binutils configure script. Note that its format has
   1297     # changed during development.
   1298     export host_configargs=
   1299     if [ "$BUILD_GOLD" ]; then
   1300         # The syntax of the --enable-gold option has changed.
   1301         if version_is_greater_than $BINUTILS_VERSION 2.20; then
   1302             if [ "$DEFAULT_LD" = "bfd" ]; then
   1303                 ARGS=$ARGS" --enable-gold --enable-ld=default"
   1304             else
   1305                 ARGS=$ARGS" --enable-gold=default --enable-ld"
   1306             fi
   1307         else
   1308             if [ "$DEFAULT_LD" = "bfd" ]; then
   1309                 ARGS=$ARGS" --enable-gold=both"
   1310             else
   1311                 ARGS=$ARGS" --enable-gold=both/gold"
   1312             fi
   1313         fi
   1314 	# This ARG needs quoting when passed to run2.
   1315 	GOLD_LDFLAGS_ARG=
   1316         if [ "$HOST_OS" = 'windows' ]; then
   1317             # gold may have runtime dependency on libgcc_sjlj_1.dll and
   1318             # libstdc++-6.dll when built by newer versions of mingw.
   1319             # Link them statically to avoid that.
   1320             if version_is_greater_than $BINUTILS_VERSION 2.22; then
   1321                 export host_configargs="--with-gold-ldflags='-static-libgcc -static-libstdc++'"
   1322             elif version_is_greater_than $BINUTILS_VERSION 2.21; then
   1323                 GOLD_LDFLAGS_ARG="--with-gold-ldflags=-static-libgcc -static-libstdc++"
   1324             else
   1325                 export LDFLAGS=$LDFLAGS" -static-libgcc -static-libstdc++"
   1326             fi
   1327         fi
   1328     fi
   1329 
   1330     # This is used to install libbfd which is later used to compile
   1331     # oprofile for the platform. This is not technically required for
   1332     # the NDK, but allows us to use the same toolchain for the platform
   1333     # build. TODO: Probably want to move this step to its own script
   1334     # like build-host-libbfd.sh in the future.
   1335     ARGS=$ARGS" --enable-install-libbfd"
   1336 
   1337     # Enable plugins support for > binutils-2.19
   1338     # This is common feature for binutils and gcc
   1339     case "$BINUTILS_VERSION" in
   1340       2.19)
   1341         # Add nothing
   1342         ;;
   1343       *)
   1344         ARGS=$ARGS" --enable-plugins"
   1345         ;;
   1346     esac
   1347 
   1348     dump "$(host_text)$(target_text) Building binutils-$BINUTILS_VERSION"
   1349     (
   1350         setup_host_env &&
   1351         BUILD_DIR="$(host_build_dir_for binutils-$BINUTILS_VERSION-$TARGET)" &&
   1352         run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* &&
   1353         cd "$BUILD_DIR" &&
   1354         run2 "$SRC_DIR"/configure \
   1355             --prefix="$INSTALL_DIR" \
   1356             --disable-shared \
   1357             --disable-werror \
   1358             --disable-nls \
   1359             --build=$BUILD \
   1360             --host=$HOST \
   1361             --target=$TARGET \
   1362             --with-sysroot="$INSTALL_DIR/sysroot" \
   1363             $ARGS &&
   1364         run2 make -j$NUM_JOBS &&
   1365         run2 make -j$NUM_INSTALL_JOBS install &&
   1366         # We need to take care of something weird, binutils-2.21 on mips
   1367         # doesn't seem to build gold, and the Makefile script forgets to
   1368         # copy it to $INSTALL/bin/mipsel-linux-android-ld. Take care of this
   1369         # here with a symlink, which will be enough for now.
   1370         if [ ! -f "$INSTALL_DIR/bin/$TARGET-ld" ]; then
   1371             run2 ln -s "$TARGET-ld.bfd" "$INSTALL_DIR/bin/$TARGET-ld"
   1372         fi
   1373     )
   1374     return $?
   1375 }
   1376 
   1377 copy_target_sysroot ()
   1378 {
   1379     local SRC_SYSROOT=$(arch_sysroot_dir $TARGET_ARCH)
   1380     local SYSROOT=$(host_sysroot)
   1381 
   1382     # We need the arch-specific minimal sysroot
   1383     stamps_do sysroot-arch-$TARGET_ARCH gen_minimal_sysroot $TARGET_ARCH
   1384 
   1385     dump "$(host_text)$(toolchain_text) Copying $TARGET_ARCH sysroot"
   1386     run2 rm -rf "$SYSROOT" &&
   1387     run2 copy_directory "$SRC_SYSROOT" "$SYSROOT"
   1388 }
   1389 
   1390 build_host_gcc_core ()
   1391 {
   1392     local SRC_DIR="$TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION"
   1393     local INSTALL_DIR="$(host_gcc_install_dir)"
   1394     local ARGS NEW_PATH
   1395 
   1396     stamps_do build-binutils-$BINUTILS_VERSION-$HOST-$TARGET build_host_binutils
   1397     stamps_do sysroot-gcc-$SYSTEM-$TOOLCHAIN copy_target_sysroot
   1398 
   1399     build_host_prereqs
   1400 
   1401     NEW_PATH=$(host_gcc_install_dir)/bin:$(host_binutils_install_dir)/bin
   1402     if [ "$HOST" != "$BUILD" ]; then
   1403         NEW_PATH=$(build_gcc_install_dir)/bin:$(build_binutils_install_dir)/bin
   1404     fi
   1405 
   1406     ARGS=$HOST_PREREQS_ARGS
   1407 
   1408     # Plugins are not supported well before 4.7. On 4.7 it's required to have
   1409     # -flto working. Flag --enable-plugins (note 's') is actually for binutils,
   1410     # this is compiler requirement to have binutils configured this way. Flag
   1411     # --disable-plugin is for gcc -
   1412     # In fact, enable-plugins is broken all Canadian Cross GCC.
   1413     #  see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50229
   1414     case "$GCC_VERSION" in
   1415      4.4.3|4.6|4.7)
   1416        ARGS=$ARGS" --disable-plugins --disable-plugin"
   1417        ;;
   1418     # Doesn't even work on 4.8
   1419      *)
   1420        ARGS=$ARGS" --enable-plugins  --enable-plugin"
   1421        ;;
   1422     esac
   1423 
   1424     ARGS=$ARGS" --with-gnu-as --with-gnu-ld"
   1425     ARGS=$ARGS" --enable-threads --disable-libssp --disable-libmudflap"
   1426     ARGS=$ARGS" --disable-libstdc__-v3 --disable-sjlj-exceptions"
   1427     ARGS=$ARGS" --disable-tls"
   1428     ARGS=$ARGS" --disable-libquadmath --disable-libitm --disable-bootstrap"
   1429     ARGS=$ARGS" --enable-languages=c,c++"
   1430     ARGS=$ARGS" --disable-shared"
   1431     ARGS=$ARGS" --disable-nls"
   1432     ARGS=$ARGS" --disable-werror"
   1433     ARGS=$ARGS" --enable-target-optspace"
   1434 
   1435     case "$GCC_VERSION" in
   1436      4.4.3)
   1437        ARGS=$ARGS" --disable-libgomp"
   1438        ;;
   1439      *)
   1440        case $TARGET_ARCH in
   1441 	     arm) ARGS=$ARGS" --enable-libgomp";;
   1442 	     x86) ARGS=$ARGS" --disable-libgomp";;
   1443 	     mips|mipsel) ARGS=$ARGS" --disable-libgomp";;
   1444 	 esac
   1445 	 ;;
   1446     esac
   1447 
   1448     # Place constructors/destructors in .init_array/.fini_array, not in
   1449     # .ctors/.dtors on Android. Note that upstream Linux GLibc is now doing
   1450     # the same.
   1451     ARGS=$ARGS" --enable-initfini-array"
   1452 
   1453     case $TARGET_ARCH in
   1454         arm)
   1455             ARGS=$ARGS" --with-arch=armv5te --with-float=soft --with-fpu=vfpv3-d16"
   1456             ;;
   1457         x86)
   1458             ARGS=$ARGS" --with-arch=i686 --with-tune=atom --with-fpmath=sse"
   1459             ;;
   1460         mips)
   1461             # Add --disable-fixed-point to disable fixed-point support
   1462             # Add --disable-threads for eh_frame handling in a single thread
   1463             ARGS=$ARGS" --with-arch=mips32 --disable-fixed-point --disable-threads"
   1464             ;;
   1465     esac
   1466 
   1467     dump "$(host_text)$(toolchain_text) Building gcc-core"
   1468     (
   1469         setup_host_env &&
   1470         BUILD_DIR="$(host_build_dir_for gcc-$GCC_VERSION-$TARGET)" &&
   1471         run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* &&
   1472         cd "$BUILD_DIR" &&
   1473         PATH=$NEW_PATH:$PATH &&
   1474         run2 "$SRC_DIR"/configure \
   1475             --prefix="$INSTALL_DIR" \
   1476             --build=$BUILD \
   1477             --host=$HOST \
   1478             --target=$TARGET \
   1479             --with-sysroot="$INSTALL_DIR/sysroot" \
   1480             $HOST_PREREQS_ARGS $ARGS &&
   1481         run2 make -j$NUM_JOBS all-gcc &&
   1482         run2 make -j$NUM_INSTALL_JOBS install-gcc
   1483     )
   1484     return $?
   1485 }
   1486 
   1487 build_target_gcc_libs ()
   1488 {
   1489     local SRC_DIR="$TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION"
   1490     local INSTALL_DIR="$(host_gcc_install_dir)"
   1491     local ARGS NEW_PATH
   1492 
   1493     stamps_do gcc-core-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_host_gcc_core
   1494 
   1495     NEW_PATH=$(host_gcc_install_dir)/bin:$(host_binutils_install_dir)/bin
   1496 
   1497     dump "$(host_text)$(toolchain_text) Building target libraries"
   1498     (
   1499         setup_host_env &&
   1500         BUILD_DIR="$(host_build_dir_for gcc-$GCC_VERSION-$TARGET)" &&
   1501         cd "$BUILD_DIR" &&
   1502         PATH=$NEW_PATH:$PATH &&
   1503         run2 make -j$NUM_JOBS all &&
   1504         run2 make -j$NUM_INSTALL_JOBS install
   1505     )
   1506     return $?
   1507 }
   1508 
   1509 copy_target_gcc_libs ()
   1510 {
   1511     local SRC_DIR DST_DIR
   1512     dump "$(host_text)$(toolchain_text) Copying target GCC libraries"
   1513 
   1514     SRC_DIR="$(build_gcc_install_dir)/$TARGET"
   1515     DST_DIR="$(host_gcc_install_dir)/$TARGET"
   1516 
   1517     run2 copy_directory "$SRC_DIR" "$DST_DIR"
   1518 }
   1519 
   1520 build_host_gcc ()
   1521 {
   1522     if [ "$SYSTEM" = "$BUILD_TAG" -a -z "$NO_TARGET_LIBS" ]; then
   1523         # This is a regular-cross build, and we need to build the target GCC libraries.
   1524         stamps_do gcc-all-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_target_gcc_libs
   1525     else
   1526         # This is a canadian-cross build, or we don't need the target GCC libraries.
   1527         stamps_do gcc-core-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_host_gcc_core
   1528     fi
   1529 }
   1530 
   1531 # $1: host system tag (e.g. linux-x86)
   1532 # $2: toolchain name (e.g. x86-4.4.3)
   1533 build_gcc ()
   1534 {
   1535     local SYSTEM=$1
   1536     local TOOLCHAIN=$2
   1537 
   1538     # When performing canadian-cross builds, ensure we generate the
   1539     # host toolchain first (even if we don't need target GCC libraries)
   1540     if [ "$SYSTEM" != "$BUILD_TAG" ]; then
   1541         build_gcc $BUILD_TAG $TOOLCHAIN
   1542     fi
   1543 
   1544     # We do this both in the setup and build phase to ensure we perform
   1545     # as many checks as possible before launching the (long) build procedure.
   1546     setup_build_for_host $SYSTEM
   1547     setup_build_for_toolchain $TOOLCHAIN
   1548 
   1549     if [ "$PHASE" = build ]; then
   1550         stamps_do build-gcc-$SYSTEM-$TOOLCHAIN build_host_gcc
   1551     fi
   1552 }
   1553 
   1554 # $1: host system tag (e.g. linux-x86)
   1555 # $2: toolchain name (e.g. x86-4.4.3)
   1556 install_gcc ()
   1557 {
   1558     local SYSTEM=$1
   1559     local TOOLCHAIN=$2
   1560     local BINUTILS_DIR GCC_DIR TARGET_LIBS_DIR INSTALL_DIR PROG
   1561 
   1562     build_gcc $SYSTEM $TOOLCHAIN
   1563 
   1564     dump "$(host_text)$(toolchain_text) Installing to NDK."
   1565 
   1566     BINUTILS_DIR=$(host_binutils_install_dir)
   1567     GCC_DIR=$(host_gcc_install_dir)
   1568     TARGET_LIBS_DIR=$(build_gcc_install_dir)
   1569     INSTALL_DIR=$TOOLCHAIN_INSTALL_DIR
   1570 
   1571     # Copy binutils binaries
   1572     run2 copy_directory "$BINUTILS_DIR/bin" "$INSTALL_DIR/bin" &&
   1573     run2 copy_directory "$BINUTILS_DIR/$TARGET/lib" "$INSTALL_DIR/$TARGET/lib" &&
   1574 
   1575     # The following is used to copy the libbfd. See --enable-install-libbfd
   1576     # which is set in build_host_binutils above.
   1577     run2 copy_directory "$BINUTILS_DIR/$HOST/$TARGET/include" "$INSTALL_DIR/include" &&
   1578     run2 copy_directory "$BINUTILS_DIR/$HOST/$TARGET/lib"     "$INSTALL_DIR/lib$(tag_to_bits $SYSTEM)" &&
   1579 
   1580     # Copy gcc core binaries
   1581     run2 copy_directory "$GCC_DIR/bin" "$INSTALL_DIR/bin" &&
   1582     run2 copy_directory "$GCC_DIR/lib/gcc/$TARGET" "$INSTALL_DIR/lib/gcc/$TARGET" &&
   1583     run2 copy_directory "$GCC_DIR/libexec/gcc/$TARGET" "$INSTALL_DIR/libexec/gcc/$TARGET" &&
   1584 
   1585     # Copy target gcc libraries
   1586     run2 copy_directory "$TARGET_LIBS_DIR/lib/gcc/$TARGET" "$INSTALL_DIR/lib/gcc/$TARGET"
   1587 
   1588     # We need to generate symlinks for the binutils binaries from
   1589     # $INSTALL_DIR/$TARGET/bin/$PROG to $INSTALL_DIR/bin/$TARGET-$PROG
   1590     mkdir -p "$INSTALL_DIR/$TARGET/bin" &&
   1591     for PROG in $(cd $BINUTILS_DIR/$TARGET/bin && ls *); do
   1592         (cd "$INSTALL_DIR/$TARGET/bin" && rm -f $PROG && ln -s ../../bin/$TARGET-$PROG $PROG)
   1593         fail_panic
   1594     done
   1595 
   1596     # Copy the license files
   1597     local TOOLCHAIN_LICENSES="$ANDROID_NDK_ROOT"/build/tools/toolchain-licenses
   1598     run cp -f "$TOOLCHAIN_LICENSES"/COPYING "$TOOLCHAIN_LICENSES"/COPYING.LIB "$INSTALL_DIR"
   1599 }
   1600 
   1601 # $1: host system tag (e.g. linux-x86)
   1602 # $2: toolchain name (e.g. x86-4.4.3)
   1603 # $3: package directory.
   1604 package_gcc ()
   1605 {
   1606     local SYSTEM=$1
   1607     local TOOLCHAIN=$2
   1608     local PACKAGE_DIR="$3"
   1609     local PACKAGE_NAME="$TOOLCHAIN-$SYSTEM.tar.bz2"
   1610     local PACKAGE_FILE="$PACKAGE_DIR/$PACKAGE_NAME"
   1611 
   1612     setup_build_for_toolchain $TOOLCHAIN
   1613 
   1614     dump "Packaging $PACKAGE_NAME."
   1615     pack_archive "$PACKAGE_FILE" "$NDK_DIR" "$TOOLCHAIN_SUB_DIR"
   1616 }
   1617 
   1618 setup_build
   1619 
   1620 for PHASE in setup build; do
   1621     for SYSTEM in $HOST_SYSTEMS; do
   1622         setup_build_for_host $SYSTEM
   1623         for TOOLCHAIN in $TOOLCHAINS; do
   1624             build_gcc $SYSTEM $TOOLCHAIN
   1625         done
   1626     done
   1627 done
   1628 
   1629 for SYSTEM in $HOST_SYSTEMS; do
   1630     setup_build_for_host $SYSTEM
   1631     for TOOLCHAIN in $TOOLCHAINS; do
   1632         install_gcc $SYSTEM $TOOLCHAIN
   1633     done
   1634 done
   1635 
   1636 if [ "$PACKAGE_DIR" ]; then
   1637     for SYSTEM in $HOST_SYSTEMS; do
   1638         setup_build_for_host $SYSTEM
   1639         for TOOLCHAIN in $TOOLCHAINS; do
   1640             package_gcc $SYSTEM $TOOLCHAIN "$PACKAGE_DIR"
   1641         done
   1642     done
   1643     echo "Done. See the content of $PACKAGE_DIR:"
   1644     ls -l "$PACKAGE_DIR"
   1645     echo ""
   1646 fi
   1647