build-mingw64-toolchain.sh: new script

This patch adds a new script that is capable of
generating a new Linux-hosted toolchain that generates
Win32 and Win64 executables.

The patch takes cares of downloading all required sources
from official sites, configure them, and run the build.

This should allow us to provide 64-bit Windows toolchain
binaries in the future.

Change-Id: I6c28372f6ac26cf1a18618a21101bd216f3e2590
WARNING: The patch works on Linux. It fails on Darwin due to
         strange libtool breakage when building binutils, and
         has never been tested on other systems.
diff --git a/build/tools/build-mingw64-toolchain.sh b/build/tools/build-mingw64-toolchain.sh
new file mode 100755
index 0000000..a8af95f
--- /dev/null
+++ b/build/tools/build-mingw64-toolchain.sh
@@ -0,0 +1,603 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Rebuild the mingw64 cross-toolchain from scratch
+#
+
+PROGNAME=$(basename $0)
+
+HELP=
+VERBOSE=1
+
+# This will be reset later.
+LOG_FILE=/dev/null
+
+panic ()
+{
+    1>&2 echo "Error: $@"
+    exit 1
+}
+
+fail_panic ()
+{
+    if [ $? != 0 ]; then
+        panic "$@"
+    fi
+}
+
+var_value ()
+{
+    eval echo \"$1\"
+}
+
+var_append ()
+{
+    local _varname=$1
+    local _varval=$(var_value $_varname)
+    shift
+    if [ -z "$_varval" ]; then
+        eval $_varname=\"$*\"
+    else
+        eval $_varname=\$$_varname\" $*\"
+    fi
+}
+
+run ()
+{
+    if [ "$VERBOSE" -gt 0 ]; then
+        echo "COMMAND: >>>> $@" > $LOG_FILE
+    fi
+    if [ "$VERBOSE" -gt 1 ]; then
+        echo "COMMAND: >>>> $@"
+    fi
+    if [ "$VERBOSE" -gt 1 ]; then
+        "$@"
+    else
+        &>$LOG_FILE "$@"
+    fi
+}
+
+log ()
+{
+    if [ "$LOG_FILE" ]; then
+        echo "$@" > $LOG_FILE
+    fi
+    if [ "$VERBOSE" -gt 0 ]; then
+        echo "$@"
+    fi
+}
+
+# For now, only tested on Linux
+OS=$(uname -s)
+EXEEXT= # executable extension
+case $OS in
+    Linux) OS=linux;;
+    Darwin) OS=darwin;;
+    CYGWIN*|*_NT-*) OS=windows;
+        if [ "$OSTYPE" = cygwgin ]; then
+            OS=cygwin
+        fi
+        EXEEXT=.exe
+        ;;
+esac
+
+ARCH=$(uname -m)
+case $ARCH in
+    i?86) ARCH=i686;;
+    amd64) ARCH=x86_64;;
+esac
+
+case $OS in
+    linux)
+        NUM_CORES=$(grep -c -e '^processor' /proc/cpuinfo)
+        ;;
+    darwin|freebsd)
+        NUM_CORES=`sysctl -n hw.ncpu`
+        ;;
+    windows|cygwin)
+        NUM_CORES=$NUMBER_OF_PROCESSORS
+        ;;
+    *)  # let's play safe here
+        NUM_CORES=1
+        ;;
+esac
+
+# Warn our users, because the script probably fails on anything but Linux
+# at that point (e.g. there are strange libtool build breakages on darwin).
+if [ "$OS" != "linux" ]; then
+    echo "WARNING: WARNING: WARNING: THIS SCRIPT PROBABLY ONLY WORKS ON LINUX!!"
+fi
+
+GMP_VERSION=5.0.4
+MPFR_VERSION=3.1.0
+MPC_VERSION=0.8.2
+BINUTILS_VERSION=2.22
+GCC_VERSION=4.6.3
+MINGW_W64_VERSION=v2.0.2
+
+JOBS=$(( $NUM_CORES * 2 ))
+
+
+HOST_BINPREFIX=
+TARGET_ARCH=x86_64
+TARGET_MULTILIBS=true  # not empty to enable multilib
+PACKAGE_DIR=
+FORCE_ALL=
+FORCE_BUILD=
+CLEANUP=
+
+TEMP_DIR=/tmp/build-mingw64-toolchain-$USER
+
+for opt; do
+    optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
+    case $opt in
+        -h|-?|--help) HELP=true;;
+        --verbose) VERBOSE=$(( $VERBOSE + 1 ));;
+        --quiet) VERBOSE=$(( $VERBOSE - 1 ));;
+        --binprefix=*) HOST_BINPREFIX=$optarg;;
+        -j*|--jobjs=*) JOBS=$optarg;;
+        --target-arch=*) TARGET_ARCH=$optarg;;
+        --no-multilib) TARGET_MULTILIBS="";;
+        --force-build) FORCE_BUILD=true;;
+        --force-all) FORCE_ALL=true;;
+        --work-dir=*) TEMP_DIR=$optarg;;
+        --package-dir=*) PACKAGE_DIR=$optarg;;
+        --cleanup) CLEANUP=true;;
+        --gcc-version=*) GCC_VERSION=$optarg;;
+        --binutils-version=*) BINUTILS_VERSION=$optarg;;
+        --gmp-version=*) GMP_VERSION=$optarg;;
+        --mpfr-version=*) MPFR_VERSION=$optarg;;
+        --mpc-version=*) MPC_VERSION=$optarg;;
+        --mingw-version=*) MINGW_W64_VERSION=$optarg;;
+        -*) panic "Unknown option '$opt', see --help for list of valid ones.";;
+        *) panic "This script doesn't take any parameter, see --help for details.";;
+    esac
+done
+
+
+if [ "$HELP" ]; then
+    echo "Usage: $PROGNAME [options]"
+    echo ""
+    echo "This program is used to rebuild a mingw64 cross-toolchain from scratch."
+    echo ""
+    echo "Valid options:"
+    echo "  -h|-?|--help                 Print this message."
+    echo "  --verbose                    Increase verbosity."
+    echo "  --quiet                      Decrease verbosity."
+    echo "  --gcc-version=<version>      Select gcc version [$GCC_VERSION]."
+    echo "  --binutil-version=<version>  Select binutils version [$BINUTILS_VERSION]."
+    echo "  --gmp-version=<version>      Select libgmp version [$GMP_VERSION]."
+    echo "  --mpfr-version=<version>     Select libmpfr version [$MPFR_VERSION]."
+    echo "  --mpc-version=<version>      Select libmpc version [$MPC_VERSION]."
+    echo "  --mingw-version=<version>    Select mingw-w64 version [$MINGW_W64_VERSION]."
+    echo "  --jobs=<num>                 Run <num> build tasks in parallel [$JOBS]."
+    echo "  -j<num>                      Same as --jobs=<num>."
+    echo "  --binprefix=<prefix>         Specify bin prefix for host toolchain."
+    echo "  --no-multilib                Disable multilib toolchain build."
+    echo "  --arch=<arch>                Select default target architecture [$TARGET_ARCH]."
+    echo "  --force-all                  Redo everything from scratch."
+    echo "  --force-build                Force a rebuild (keep sources)."
+    echo "  --cleanup                    Remove all temp files after build."
+    echo "  --work-dir=<path>            Specify work/build directory [$TEMP_DIR]."
+    echo "  --package-dir=<path>         Package toolchain to directory."
+    echo ""
+    exit 0
+fi
+
+if [ "$CLEANUP" ]; then
+    if [ -z "$PACKAGE_DIR" ]; then
+        panic "You should only use --cleanup with --package-dir=<path> !".
+    fi
+fi
+
+BUILD_TAG64=x86_64-linux-gnu
+BUILD_TAG32=i686-linux-gnu
+
+# We don't want debug executables
+BUILD_CFLAGS="-O2 -fomit-frame-pointer -s"
+BUILD_LDFLAGS=""
+
+# On Darwin, we want to use the 10.4 / 10.5 / 10.6 SDKs to generate binaries
+# that work on "old" platform releases.
+if [ "$OS" = darwin ]; then
+    # Use the check for the availability of a compatibility SDK in Darwin
+    # this can be used to generate binaries compatible with either Tiger or
+    # Leopard.
+    #
+    # $1: SDK root path
+    # $2: MacOS X minimum version (e.g. 10.4)
+    check_darwin_sdk ()
+    {
+        if [ -d "$1" ] ; then
+            var_append BUILD_CFLAGS "-isysroot $1 -mmacosx-version-min=$2 -DMAXOSX_DEPLOYEMENT_TARGET=$2"
+            var_append BUILD_LDFLAGS "-Wl,-syslibroot,$sdk -mmacosx-version-min=$2"
+            return 0  # success
+        fi
+        return 1
+    }
+
+    if check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku 10.4; then
+        log "Generating Tiger-compatible binaries!"
+    elif check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk 10.5; then
+        log "Generating Leopard-compatible binaries!"
+    elif check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk 10.6; then
+        log "Generating Snow Leopard-compatible binaries!"
+    else
+        osx_version=`sw_vers -productVersion`
+        log "Generating $osx_version-compatible binaries!"
+    fi
+fi
+
+mkdir -p $TEMP_DIR
+if [ "$FORCE_ALL" ]; then
+    log "Cleaning up work directory..."
+    rm -rf $TEMP_DIR/*
+fi
+
+LOG_FILE=$TEMP_DIR/build.log
+rm -f $LOG_FILE && touch $LOG_FILE
+if [ "$VERBOSE" -eq 1 ]; then
+    echo  "To follow build, use in another terminal: tail -F $LOG_FILE"
+fi
+
+case $TARGET_ARCH in
+    x86_64) TARGET_BITS=64;;
+    i686) TARGET_BITS=32;;
+    *) panic "Invalid --target parameter. Valid values are: x86_64 i686";;
+esac
+TARGET_TAG=$TARGET_ARCH-w64-mingw32
+log "Target arch: $TARGET_TAG"
+log "Target bits: $TARGET_BITS"
+
+# Determine bitness of host architecture
+PROBE_CC=${CC:-gcc}
+if [ "$HOST_BINPREFIX" ]; then
+    PROBE_CC=$HOST_BINPREFIX-gcc
+fi
+echo "int main() { return 0; }" > $TEMP_DIR/test-host-cc.c
+$PROBE_CC -c $TEMP_DIR/test-host-cc.c -o $TEMP_DIR/test-host-cc.o > /dev/null
+fail_panic "Host compiler doesn't work: $PROBE_CC"
+
+file $TEMP_DIR/test-host-cc.o | grep -q -e "x86[_-]64"
+if [ $? != 0 ]; then
+    log "Host compiler generates 32-bit code: $PROBE_CC"
+    HOST_ARCH=i686
+    HOST_BITS=32
+else
+    log "Host compiler generates 64-bit code: $PROBE_CC"
+    HOST_ARCH=x86_64
+    HOST_BITS=64
+fi
+
+case $OS in
+    linux) HOST_TAG=$HOST_ARCH-linux-gnu;;
+    darwin) HOST_TAG=$HOST_ARCH-apple-darwinx11;;
+    cygwin) HOST_TAG=$HOST_ARCH-pc-cygwin;;
+    *) panic "Unsupported host operating system!"
+esac
+log "Host arch: $HOST_TAG"
+
+download_package ()
+{
+    # Assume the packages are already downloaded under $ARCHIVE_DIR
+    local PKG_URL=$1
+    local PKG_NAME=$(basename $PKG_URL)
+
+    case $PKG_NAME in
+        *.tar.bz2)
+            PKG_BASENAME=${PKG_NAME%%.tar.bz2}
+            ;;
+        *.tar.gz)
+            PKG_BASENAME=${PKG_NAME%%.tar.gz}
+            ;;
+        *)
+            panic "Unknown archive type: $PKG_NAME"
+    esac
+
+    if [ ! -f "$ARCHIVE_DIR/$PKG_NAME" ]; then
+        log "Downloading $PKG_URL..."
+        (cd $ARCHIVE_DIR && run curl -L -o "$PKG_NAME" "$PKG_URL")
+        fail_panic "Can't download '$PKG_URL'"
+    fi
+
+    MD5SUM=$(md5sum $ARCHIVE_DIR/$PKG_NAME | cut -d" " -f1)
+    echo "$MD5SUM  $PKG_URL" >> $INSTALL_DIR/README
+
+    if [ ! -d "$SRC_DIR/$PKG_BASENAME" ]; then
+        log "Uncompressing $PKG_URL into $SRC_DIR"
+        case $PKG_NAME in
+            *.tar.bz2)
+                run tar xjf $ARCHIVE_DIR/$PKG_NAME -C $SRC_DIR
+                ;;
+            *.tar.gz)
+                run tar xzf $ARCHIVE_DIR/$PKG_NAME -C $SRC_DIR
+                ;;
+            *)
+                panic "Unknown archive type: $PKG_NAME"
+                ;;
+        esac
+        fail_panic "Can't uncompress $ARCHIVE_DIR/$PKG_NAME"
+    fi
+}
+
+# Download and unpack source packages from official sites
+ARCHIVE_DIR=$TEMP_DIR/archive
+SRC_DIR=$TEMP_DIR/src
+STAMP_DIR=$TEMP_DIR/timestamps
+
+mkdir -p $ARCHIVE_DIR
+mkdir -p $SRC_DIR
+mkdir -p $STAMP_DIR
+
+if [ "$FORCE_BUILD" ]; then
+    rm -f $STAMP_DIR/*
+    rm -rf $INSTALL_DIR
+    rm -rf $BUILD_DIR
+fi
+
+# Make temp install directory
+INSTALL_DIR=$TEMP_DIR/install-$HOST_TAG/x86_64-w64-mingw32
+BUILD_DIR=$TEMP_DIR/build-$HOST_TAG
+
+mkdir -p $INSTALL_DIR
+mkdir -p $BUILD_DIR
+
+# Copy this script
+cp $0 $INSTALL_DIR/ &&
+echo "This file has been automatically generated on $(date) with the following command:" > $INSTALL_DIR/README &&
+echo "$PROGNAME $@" >> $INSTALL_DIR/README &&
+echo "" >> $INSTALL_DIR/README &&
+echo "The MD5 hashes for the original sources packages are:" >> $INSTALL_DIR/README
+fail_panic "Could not copy script to installation directory."
+
+download_package http://ftp.gnu.org/gnu/gmp/gmp-$GMP_VERSION.tar.bz2
+download_package http://ftp.gnu.org/gnu/mpfr/mpfr-$MPFR_VERSION.tar.bz2
+download_package http://www.multiprecision.org/mpc/download/mpc-$MPC_VERSION.tar.gz
+download_package http://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.bz2
+download_package http://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.bz2
+download_package http://downloads.sourceforge.net/project/mingw-w64/mingw-w64/mingw-w64-release/mingw-w64-$MINGW_W64_VERSION.tar.gz
+
+# Let's generate the licenses/ directory
+LICENSES_DIR=$INSTALL_DIR/licenses/
+mkdir -p $LICENSES_DIR
+if [ ! -f $STAMP_DIR/licenses ]; then
+    LICENSE_FILES=$(cd $SRC_DIR && find . -name "COPYING*")
+    # Copy all license files to $LICENSES_DIR
+    (tar cf - -C $SRC_DIR $LICENSE_FILES) | (tar xf - -C $LICENSES_DIR)
+    touch $STAMP_DIR/licenses
+fi
+
+setup_build_env ()
+{
+    local BINPREFIX=$1
+
+    if [ "$BINPREFIX" ]; then
+        CC=$BINPREFIX-gcc
+        CXX=$BINPREFIX-g++
+        LD=$BINPREFIX-ld
+        AS=$BINPREFIX-as
+        AR=$BINPREFIX-ar
+        RANLIB=$BINPREFIX-ranlib
+        STRIP=$BINPREFIX-strip
+        export CC CXX LD AS AR RANLIB STRIP
+    elif [ "$OS" = darwin ]; then
+        # Needed on OS X otherwise libtool will try to use gcc and $BUILD_CFLAGS
+        LD=ld
+    fi
+
+    export CFLAGS="$BUILD_CFLAGS"
+    export CXXFLAGS="$BUILD_CFLAGS"
+    export LDFLAGS="$BUILD_LDFLAGS"
+}
+
+setup_install_env ()
+{
+    export PATH=$INSTALL_DIR/bin:$PATH
+}
+
+build_host_package ()
+{
+    local PKGNAME=$1
+    shift
+
+    if [ ! -f $STAMP_DIR/$PKGNAME ]; then
+        (
+            mkdir -p $BUILD_DIR/$PKGNAME &&
+            cd $BUILD_DIR/$PKGNAME &&
+            setup_build_env $HOST_BINPREFIX &&
+            log "$PKGNAME: Configuring" &&
+            run $SRC_DIR/$PKGNAME/configure "$@"
+            fail_panic "Can't configure $PKGNAME !!"
+
+            log "$PKGNAME: Building" &&
+            run make -j$JOBS
+            fail_panic "Can't build $PKGNAME !!"
+
+            log "$PKGNAME: Installing" &&
+            run make install
+            fail_panic "Can't install $PKGNAME"
+        ) || exit 1
+        touch $STAMP_DIR/$PKGNAME
+    fi
+}
+
+export ABI=$HOST_BITS
+BASE_HOST_OPTIONS="--prefix=$INSTALL_DIR --disable-shared"
+build_host_package gmp-$GMP_VERSION $BASE_HOST_OPTIONS
+var_append BASE_HOST_OPTIONS "--with-gmp=$INSTALL_DIR"
+
+build_host_package mpfr-$MPFR_VERSION $BASE_HOST_OPTIONS
+var_append BASE_HOST_OPTIONS "--with-mpfr=$INSTALL_DIR"
+
+build_host_package mpc-$MPC_VERSION $BASE_HOST_OPTIONS
+var_append BASE_HOST_OPTIONS "--with-mpc=$INSTALL_DIR"
+
+BINUTILS_CONFIGURE_OPTIONS=$BASE_HOST_OPTIONS
+var_append BINUTILS_CONFIGURE_OPTIONS "--target=$TARGET_TAG --disable-nls"
+if [ "$TARGET_MULTILIBS" ]; then
+    var_append BINUTILS_CONFIGURE_OPTIONS "--enable-targets=x86_64-w64-mingw32,i686-w64-mingw32"
+fi
+
+var_append BINUTILS_CONFIGURE_OPTIONS "--with-sysroot=$INSTALL_DIR"
+
+build_host_package binutils-$BINUTILS_VERSION $BINUTILS_CONFIGURE_OPTIONS
+
+# Install the right mingw64 headers into the sysroot
+build_mingw_headers ()
+{
+    local PKGNAME=$1
+    if [ ! -f "$STAMP_DIR/$PKGNAME" ]; then
+        (
+            mkdir -p $BUILD_DIR/$PKGNAME &&
+            cd $BUILD_DIR/$PKGNAME &&
+            log "$PKGNAME: Configuring" &&
+            run $SRC_DIR/mingw-w64-$MINGW_W64_VERSION/mingw-w64-headers/configure --prefix=$INSTALL_DIR --host=$TARGET_TAG --build=$HOST_TAG
+            fail_panic "Can't configure mingw-64-headers"
+
+            log "$PKGNAME: Installing" &&
+            run make install -j$JOBS &&
+            run cd $INSTALL_DIR && 
+            run ln -s $TARGET_TAG mingw &&
+            run cd $INSTALL_DIR/mingw && 
+            run ln -s lib lib$TARGET_BITS
+            fail_panic "Can't configure mingw-64-headers"
+        ) || exit 1
+        touch $STAMP_DIR/$PKGNAME
+    fi
+}
+
+# Slightly different from build_host_package because we need to call
+# 'make all-gcc' and 'make install-gcc' as a special case.
+#
+build_core_gcc ()
+{
+    local PKGNAME=$1
+    shift
+
+    if [ ! -f "$STAMP_DIR/core-$PKGNAME" ]; then
+        (
+            mkdir -p $BUILD_DIR/$PKGNAME &&
+            cd $BUILD_DIR/$PKGNAME &&
+            setup_build_env $HOST_BINPREFIX &&
+            log "core-$PKGNAME: Configuring" &&
+            run $SRC_DIR/$PKGNAME/configure "$@"
+            fail_panic "Can't configure $PKGNAME !!"
+
+            log "core-$PKGNAME: Building" &&
+            run make -j$JOBS all-gcc
+            fail_panic "Can't build $PKGNAME !!"
+
+            log "core-$PKGNAME: Installing" &&
+            run make -j$JOBS install-gcc
+            fail_panic "Can't install $PKGNAME"
+        ) || exit 1
+        touch $STAMP_DIR/core-$PKGNAME
+    fi
+}
+
+
+# Build and install the C runtime files needed by the toolchain
+build_mingw_crt ()
+{
+    local PKGNAME=$1
+    shift
+
+    if [ ! -f $STAMP_DIR/$PKGNAME ]; then
+        (
+            mkdir -p $BUILD_DIR/$PKGNAME &&
+            cd $BUILD_DIR/$PKGNAME &&
+            export PATH=$INSTALL_DIR/bin:$PATH
+            log "$PKGNAME: Configuring" &&
+            run $SRC_DIR/mingw-w64-$MINGW_W64_VERSION/mingw-w64-crt/configure "$@"
+            fail_panic "Can't configure $PKGNAME !!"
+
+            log "$PKGNAME: Building" &&
+            run make -j$JOBS
+            fail_panic "Can't build $PKGNAME !!"
+
+            log "$PKGNAME: Installing" &&
+            run make -j$JOBS install
+            fail_panic "Can't install $PKGNAME"
+        ) || exit 1
+        touch $STAMP_DIR/$PKGNAME
+    fi
+}
+
+
+build_libgcc ()
+{
+    local PKGNAME=$1
+    shift
+
+    if [ ! -f "$STAMP_DIR/libgcc-$PKGNAME" ]; then
+        (
+            # No configure step here! We're resuming work that was started
+            # in build_core_gcc.
+            cd $BUILD_DIR/$PKGNAME &&
+            setup_build_env $HOST_BINPREFIX &&
+            log "libgcc-$PKGNAME: Building" &&
+            run make -j$JOBS
+            fail_panic "Can't build libgcc-$PKGNAME !!"
+
+            log "libgcc-$PKGNAME: Installing" &&
+            run make -j$JOBS install
+            fail_panic "Can't install libgcc-$PKGNAME"
+        ) || exit 1
+
+        touch "$STAMP_DIR/libgcc-$PKGNAME"
+    fi
+}
+
+GCC_CONFIGURE_OPTIONS=$BASE_HOST_OPTIONS
+var_append GCC_CONFIGURE_OPTIONS "--target=$TARGET_TAG"
+if [ "$TARGET_MULTILIBS" ]; then
+    var_append GCC_CONFIGURE_OPTIONS "--enable-targets=all"
+fi
+var_append GCC_CONFIGURE_OPTIONS "--enable-languages=c,c++"
+var_append GCC_CONFIGURE_OPTIONS "--with-sysroot=$INSTALL_DIR"
+
+build_mingw_headers mingw-w64-headers
+
+build_core_gcc gcc-$GCC_VERSION $GCC_CONFIGURE_OPTIONS
+
+CRT_CONFIGURE_OPTIONS="--host=$TARGET_TAG --with-sysroot=$INSTALL_DIR --prefix=$INSTALL_DIR"
+if [ "$TARGET_MULTILIBS" ]; then
+    var_append CRT_CONFIGURE_OPTIONS "--enable-lib32"
+fi
+
+build_mingw_crt mingw-w64-crt $CRT_CONFIGURE_OPTIONS
+
+build_libgcc gcc-$GCC_VERSION
+
+if [ "$PACKAGE_DIR" ]; then
+    mkdir -p $PACKAGE_DIR
+    fail_panic "Could not create packaging directory: $PACKAGE_DIR"
+    PACKAGE_NAME=$PACKAGE_DIR/$TARGET_TAG-$OS-$HOST_ARCH.tar.bz2
+    log "Packaging $TARGET_TAG toolchain to $PACKAGE_NAME"
+    run tar cjf $PACKAGE_NAME -C $(dirname $INSTALL_DIR) $TARGET_TAG/
+    fail_panic "Could not package $TARGET_TAG toolchain!"
+    log "Done. See $PACKAGE_DIR:"
+    ls -l $PACKAGE_NAME
+else
+    log "Done. See: $INSTALL_DIR"
+fi
+
+if [ "$CLEANUP" ]; then
+    log "Cleaning up..."
+    rm -rf $TEMP_DIR/*
+fi
+
+exit 0