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 mingw64 cross-toolchain from scratch
     18 #
     19 # See --help for usage example.
     20 
     21 PROGNAME=$(basename $0)
     22 PROGDIR=$(dirname $0)
     23 PROGDIR=$(cd $PROGDIR && pwd)
     24 
     25 HELP=
     26 VERBOSE=1
     27 
     28 # This will be reset later.
     29 LOG_FILE=/dev/null
     30 
     31 panic ()
     32 {
     33     1>&2 echo "Error: $@"
     34     exit 1
     35 }
     36 
     37 fail_panic ()
     38 {
     39     if [ $? != 0 ]; then
     40         panic "$@"
     41     fi
     42 }
     43 
     44 var_value ()
     45 {
     46     eval echo \"$1\"
     47 }
     48 
     49 var_append ()
     50 {
     51     local _varname=$1
     52     local _varval=$(var_value $_varname)
     53     shift
     54     if [ -z "$_varval" ]; then
     55         eval $_varname=\"$*\"
     56     else
     57         eval $_varname=\$$_varname\" $*\"
     58     fi
     59 }
     60 
     61 run ()
     62 {
     63     if [ "$VERBOSE" -gt 0 ]; then
     64         echo "COMMAND: >>>> $@" >> $LOG_FILE
     65     fi
     66     if [ "$VERBOSE" -gt 1 ]; then
     67         echo "COMMAND: >>>> $@"
     68     fi
     69     if [ "$VERBOSE" -gt 1 ]; then
     70         "$@"
     71     else
     72        "$@" > /dev/null 2>&1
     73     fi
     74 }
     75 
     76 log ()
     77 {
     78     if [ "$LOG_FILE" ]; then
     79         echo "$@" >> $LOG_FILE
     80     fi
     81     if [ "$VERBOSE" -gt 0 ]; then
     82         echo "$@"
     83     fi
     84 }
     85 
     86 # For now, only tested on Linux
     87 OS=$(uname -s)
     88 EXEEXT= # executable extension
     89 case $OS in
     90     Linux) OS=linux;;
     91     Darwin) OS=darwin;;
     92     CYGWIN*|*_NT-*) OS=windows;
     93         if [ "$OSTYPE" = cygwgin ]; then
     94             OS=cygwin
     95         fi
     96         EXEEXT=.exe
     97         ;;
     98 esac
     99 
    100 ARCH=$(uname -m)
    101 case $ARCH in
    102     i?86) ARCH=i686;;
    103     amd64) ARCH=x86_64;;
    104 esac
    105 
    106 case $OS in
    107     linux)
    108         NUM_CORES=$(grep -c -e '^processor' /proc/cpuinfo)
    109         ;;
    110     darwin|freebsd)
    111         NUM_CORES=`sysctl -n hw.ncpu`
    112         ;;
    113     windows|cygwin)
    114         NUM_CORES=$NUMBER_OF_PROCESSORS
    115         ;;
    116     *)  # let's play safe here
    117         NUM_CORES=1
    118         ;;
    119 esac
    120 
    121 # Warn our users, because the script probably fails on anything but Linux
    122 # at that point (e.g. there are strange libtool build breakages on darwin).
    123 if [ "$OS" != "linux" ]; then
    124     echo "WARNING: WARNING: WARNING: THIS SCRIPT PROBABLY ONLY WORKS ON LINUX!!"
    125 fi
    126 
    127 # GMP moving home?
    128 # GMP_VERSION=5.1.0
    129 # GMP_URL=ftp://ftp.gmplib.org/pub/gmp-$GMP_VERSION/
    130 # ..but the old one is still there:
    131 GMP_VERSION=5.0.5
    132 GMP_URL=http://ftp.gnu.org/gnu/gmp/
    133 
    134 MPFR_VERSION=3.1.1
    135 MPC_VERSION=1.0.1
    136 BINUTILS_VERSION=2.24
    137 GCC_VERSION=4.8.3
    138 
    139 # Need at least revision 5166
    140 # For reference, I've built a working NDK with 5445
    141 # (latest as of Sun Feb 3 2013 is 5578)
    142 MINGW_W64_VERSION=svn@5861
    143 
    144 JOBS=$(( $NUM_CORES * 2 ))
    145 
    146 
    147 HOST_BINPREFIX=
    148 TARGET_ARCH=x86_64
    149 TARGET_MULTILIBS=true  # not empty to enable multilib
    150 PACKAGE_DIR=
    151 FORCE_ALL=
    152 FORCE_BUILD=
    153 CLEANUP=
    154 
    155 TEMP_DIR=/tmp/build-mingw64-toolchain-$USER
    156 
    157 for opt; do
    158     optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
    159     case $opt in
    160         -h|-?|--help) HELP=true;;
    161         --verbose) VERBOSE=$(( $VERBOSE + 1 ));;
    162         --quiet) VERBOSE=$(( $VERBOSE - 1 ));;
    163         --binprefix=*) HOST_BINPREFIX=$optarg;;
    164         -j*|--jobs=*) JOBS=$optarg;;
    165         --target-arch=*) TARGET_ARCH=$optarg;;
    166         --no-multilib) TARGET_MULTILIBS="";;
    167         --force-build) FORCE_BUILD=true;;
    168         --force-all) FORCE_ALL=true;;
    169         --work-dir=*) TEMP_DIR=$optarg;;
    170         --package-dir=*) PACKAGE_DIR=$optarg;;
    171         --cleanup) CLEANUP=true;;
    172         --gcc-version=*) GCC_VERSION=$optarg;;
    173         --binutils-version=*) BINUTILS_VERSION=$optarg;;
    174         --gmp-version=*) GMP_VERSION=$optarg;;
    175         --mpfr-version=*) MPFR_VERSION=$optarg;;
    176         --mpc-version=*) MPC_VERSION=$optarg;;
    177         --mingw-version=*) MINGW_W64_VERSION=$optarg;;
    178         -*) panic "Unknown option '$opt', see --help for list of valid ones.";;
    179         *) panic "This script doesn't take any parameter, see --help for details.";;
    180     esac
    181 done
    182 
    183 
    184 if [ "$HELP" ]; then
    185     cat <<EOF
    186 Usage: $PROGNAME [options]
    187 
    188 This program is used to rebuild a mingw64 cross-toolchain from scratch.
    189 
    190 It uses your host 'gcc' by default to generate a cross-toolchain named
    191 either x86_64-w64-mingw32 or i686-w64-mingw32, depending on your compiler's
    192 target bitness. For example:
    193 
    194     /path/to/build-mingw64-toolchain.sh
    195 
    196 All toolchain binaries can generate both Win32 and Win64 executables.
    197 The default target is Win64, but you can change this to Win32 by using
    198 the '--target-arch=i686' option. Otherwise, use -m32 or -m64 at compile/link
    199 time to select a specific target.
    200 
    201 It is possible to use --binprefix=<prefix> to specify an alternative host
    202 toolchain prefix, e.g. <prefix>-gcc to compile. For example, to generate
    203 64-bit binaries that can run on older Linux distributions, using the Android
    204 SDK's compatibility Linux toolchain, one can do the following:
    205 
    206     SDK_TOOLCHAIN=<some-dir>
    207     PREBUILTS=https://android.googlesource.com/platform/prebuilts
    208     git clone \$PREBUILTS/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8 \\
    209         \$SDK_TOOLCHAIN
    210     PATH=\$SDK_TOOLCHAIN/bin:\$PATH \\
    211     /path/to/build-mingw64-toolchain.sh --binprefix=x86_64-linux
    212 
    213 In the example above, the script will use 'x86_64-linux-gcc' and related
    214 tools to build the final binaries.
    215 
    216 It is recommended to use --package-dir=<path> to generate tarballs of the
    217 generated toolchains under <path>/, for easier redistribution.
    218 
    219 Valid options:
    220   -h|-?|--help                 Print this message."
    221   --verbose                    Increase verbosity."
    222   --quiet                      Decrease verbosity."
    223   --gcc-version=<version>      Select gcc version [$GCC_VERSION]."
    224   --binutil-version=<version>  Select binutils version [$BINUTILS_VERSION]."
    225   --gmp-version=<version>      Select libgmp version [$GMP_VERSION]."
    226   --mpfr-version=<version>     Select libmpfr version [$MPFR_VERSION]."
    227   --mpc-version=<version>      Select libmpc version [$MPC_VERSION]."
    228   --mingw-version=<version>    Select mingw-w64 version [$MINGW_W64_VERSION]."
    229   --jobs=<num>                 Run <num> build tasks in parallel [$JOBS]."
    230   -j<num>                      Same as --jobs=<num>."
    231   --binprefix=<prefix>         Specify bin prefix for host toolchain."
    232   --no-multilib                Disable multilib toolchain build."
    233   --target-arch=<arch>         Select default target architecture [$TARGET_ARCH]."
    234   --force-all                  Redo everything from scratch."
    235   --force-build                Force a rebuild (keep sources)."
    236   --cleanup                    Remove all temp files after build."
    237   --work-dir=<path>            Specify work/build directory [$TEMP_DIR]."
    238   --package-dir=<path>         Package toolchain to directory."
    239 
    240 EOF
    241     exit 0
    242 fi
    243 
    244 if [ "$CLEANUP" ]; then
    245     if [ -z "$PACKAGE_DIR" ]; then
    246         panic "You should only use --cleanup with --package-dir=<path> !".
    247     fi
    248 fi
    249 
    250 BUILD_TAG64=x86_64-linux-gnu
    251 BUILD_TAG32=i686-linux-gnu
    252 
    253 # We don't want debug executables
    254 BUILD_CFLAGS="-O2 -fomit-frame-pointer -s"
    255 BUILD_LDFLAGS=""
    256 
    257 # On Darwin, we want to use the 10.4 / 10.5 / 10.6 SDKs to generate binaries
    258 # that work on "old" platform releases.
    259 if [ "$OS" = darwin ]; then
    260     # Use the check for the availability of a compatibility SDK in Darwin
    261     # this can be used to generate binaries compatible with either Tiger or
    262     # Leopard.
    263     #
    264     # $1: SDK root path
    265     # $2: MacOS X minimum version (e.g. 10.4)
    266     check_darwin_sdk ()
    267     {
    268         if [ -d "$1" ] ; then
    269             var_append BUILD_CFLAGS "-isysroot $1 -mmacosx-version-min=$2 -DMAXOSX_DEPLOYEMENT_TARGET=$2"
    270             var_append BUILD_LDFLAGS "-Wl,-syslibroot,$sdk -mmacosx-version-min=$2"
    271             return 0  # success
    272         fi
    273         return 1
    274     }
    275 
    276     if check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku 10.4; then
    277         log "Generating Tiger-compatible binaries!"
    278     elif check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk 10.5; then
    279         log "Generating Leopard-compatible binaries!"
    280     elif check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk 10.6; then
    281         log "Generating Snow Leopard-compatible binaries!"
    282     else
    283         osx_version=`sw_vers -productVersion`
    284         log "Generating $osx_version-compatible binaries!"
    285     fi
    286 fi
    287 
    288 mkdir -p $TEMP_DIR
    289 if [ "$FORCE_ALL" ]; then
    290     log "Cleaning up work directory..."
    291     rm -rf $TEMP_DIR/*
    292 fi
    293 
    294 LOG_FILE=$TEMP_DIR/build.log
    295 rm -f $LOG_FILE && touch $LOG_FILE
    296 if [ "$VERBOSE" -eq 1 ]; then
    297     echo  "To follow build, use in another terminal: tail -F $LOG_FILE"
    298 fi
    299 
    300 case $TARGET_ARCH in
    301     x86_64) TARGET_BITS=64;;
    302     i686) TARGET_BITS=32;;
    303     *) panic "Invalid --target parameter. Valid values are: x86_64 i686";;
    304 esac
    305 TARGET_TAG=$TARGET_ARCH-w64-mingw32
    306 log "Target arch: $TARGET_TAG"
    307 log "Target bits: $TARGET_BITS"
    308 
    309 # Determine bitness of host architecture
    310 PROBE_CC=${CC:-gcc}
    311 if [ -n "$HOST_BINPREFIX" ]; then
    312     # If $HOST_BINPREFIX is a directory but not ends with '/', append '/'.
    313     # Otherwise, append '-'.
    314     if [ -d "$HOST_BINPREFIX" ] ; then
    315         if [ -n "${HOST_BINPREFIX##*/}" ] ; then
    316 	    HOST_BINPREFIX="${HOST_BINPREFIX}/"
    317 	fi
    318     else
    319         HOST_BINPREFIX="${HOST_BINPREFIX}-"
    320     fi
    321     PROBE_CC=${HOST_BINPREFIX}gcc
    322 fi
    323 echo "Using GCC: $PROBE_CC"
    324 echo "int main() { return 0; }" > $TEMP_DIR/test-host-cc.c
    325 $PROBE_CC -c $TEMP_DIR/test-host-cc.c -o $TEMP_DIR/test-host-cc.o > /dev/null
    326 fail_panic "Host compiler doesn't work: $PROBE_CC"
    327 
    328 file $TEMP_DIR/test-host-cc.o | grep -q -e "x86[_-]64"
    329 if [ $? != 0 ]; then
    330     log "Host compiler generates 32-bit code: $PROBE_CC"
    331     HOST_ARCH=i686
    332     HOST_BITS=32
    333 else
    334     log "Host compiler generates 64-bit code: $PROBE_CC"
    335     HOST_ARCH=x86_64
    336     HOST_BITS=64
    337 fi
    338 
    339 case $OS in
    340     linux) HOST_TAG=$HOST_ARCH-linux-gnu;;
    341     darwin) HOST_TAG=$HOST_ARCH-apple-darwinx11;;
    342     cygwin) HOST_TAG=$HOST_ARCH-pc-cygwin;;
    343     *) panic "Unsupported host operating system!"
    344 esac
    345 log "Host arch: $HOST_TAG"
    346 
    347 download_package ()
    348 {
    349     # Assume the packages are already downloaded under $ARCHIVE_DIR
    350     local PKG_URL=$1
    351     local PKG_NAME=$(basename $PKG_URL)
    352 
    353     case $PKG_NAME in
    354         *.tar.bz2)
    355             PKG_BASENAME=${PKG_NAME%%.tar.bz2}
    356             ;;
    357         *.tar.gz)
    358             PKG_BASENAME=${PKG_NAME%%.tar.gz}
    359             ;;
    360         *)
    361             panic "Unknown archive type: $PKG_NAME"
    362     esac
    363 
    364     if [ ! -f "$ARCHIVE_DIR/$PKG_NAME" ]; then
    365         log "Downloading $PKG_URL..."
    366         (cd $ARCHIVE_DIR && run curl -L -o "$PKG_NAME" "$PKG_URL")
    367         fail_panic "Can't download '$PKG_URL'"
    368     fi
    369 
    370     MD5SUM=$(md5sum $ARCHIVE_DIR/$PKG_NAME | cut -d" " -f1)
    371     echo "$MD5SUM  $PKG_URL" >> $INSTALL_DIR/README
    372 
    373     if [ ! -d "$SRC_DIR/$PKG_BASENAME" ]; then
    374         log "Uncompressing $PKG_URL into $SRC_DIR"
    375         case $PKG_NAME in
    376             *.tar.bz2)
    377                 run tar xjf $ARCHIVE_DIR/$PKG_NAME -C $SRC_DIR
    378                 ;;
    379             *.tar.gz)
    380                 run tar xzf $ARCHIVE_DIR/$PKG_NAME -C $SRC_DIR
    381                 ;;
    382             *)
    383                 panic "Unknown archive type: $PKG_NAME"
    384                 ;;
    385         esac
    386         fail_panic "Can't uncompress $ARCHIVE_DIR/$PKG_NAME"
    387     fi
    388 }
    389 
    390 # Download and unpack source packages from official sites
    391 ARCHIVE_DIR=$TEMP_DIR/archive
    392 SRC_DIR=$TEMP_DIR/src
    393 STAMP_DIR=$TEMP_DIR/timestamps
    394 
    395 mkdir -p $ARCHIVE_DIR
    396 mkdir -p $SRC_DIR
    397 mkdir -p $STAMP_DIR
    398 
    399 INSTALL_DIR=$TEMP_DIR/install-$HOST_TAG/$TARGET_TAG
    400 BUILD_DIR=$TEMP_DIR/build-$HOST_TAG
    401 
    402 if [ "$FORCE_BUILD" ]; then
    403     rm -f $STAMP_DIR/*
    404     rm -rf $INSTALL_DIR
    405     rm -rf $BUILD_DIR
    406 fi
    407 
    408 # Make temp install directory
    409 mkdir -p $INSTALL_DIR
    410 mkdir -p $BUILD_DIR
    411 
    412 # Copy this script
    413 cp $0 $INSTALL_DIR/ &&
    414 echo "This file has been automatically generated on $(date) with the following command:" > $INSTALL_DIR/README &&
    415 echo "$PROGNAME $@" >> $INSTALL_DIR/README &&
    416 echo "" >> $INSTALL_DIR/README &&
    417 echo "The MD5 hashes for the original sources packages are:" >> $INSTALL_DIR/README
    418 fail_panic "Could not copy script to installation directory."
    419 
    420 download_package ${GMP_URL}gmp-${GMP_VERSION}.tar.bz2
    421 download_package http://ftp.gnu.org/gnu/mpfr/mpfr-$MPFR_VERSION.tar.bz2
    422 download_package http://www.multiprecision.org/mpc/download/mpc-$MPC_VERSION.tar.gz
    423 download_package http://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.bz2
    424 download_package http://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.bz2
    425 
    426 PREFIX_FOR_TARGET=$INSTALL_DIR/$TARGET_TAG
    427 WITH_WIDL=$INSTALL_DIR/bin
    428 MINGW_W64_REVISION=
    429 MINGW_W64_VERSION_NO_REV=$(echo $MINGW_W64_VERSION | awk 'BEGIN { FS="@" }; { print $1 }')
    430 if [ "$MINGW_W64_VERSION_NO_REV" = "svn" ];  then
    431     MINGW_W64_REVISION=$(echo $MINGW_W64_VERSION | awk 'BEGIN { FS="@" }; { print $2 }')
    432     if [ ! -z "$MINGW_W64_REVISION" ] ; then
    433         if [ $MINGW_W64_REVISION -lt 5186 ] ; then
    434             PREFIX_FOR_TARGET=$INSTALL_DIR
    435         fi
    436         if [ $MINGW_W64_REVISION -lt 5252 ] ; then
    437             WITH_WIDL=mingw-w64-widl
    438         elif [ $MINGW_W64_REVISION -lt 5258 ] ; then
    439             WITH_WIDL=$TARGET_TAG-widl
    440         fi
    441         MINGW_W64_REVISION2=-r$MINGW_W64_REVISION
    442         MINGW_W64_REVISION=@${MINGW_W64_REVISION}
    443     fi
    444     MINGW_W64_SRC=$SRC_DIR/mingw-w64-svn$MINGW_W64_REVISION2
    445     MINGW_W64_VERSION=svn
    446 fi
    447 
    448 if [ -z "$MINGW_W64_REVISION" ] ; then
    449     # Released versions of MinGW-w64 don't provide easily accessible information
    450     # about the svn revision which this script needs to know.
    451     fail_panic "Building MinGW-w64 toolchain requires specifying an svn version"
    452 fi
    453 
    454 if [ ! -d $MINGW_W64_SRC ]; then
    455     MINGW64_SVN_URL=https://svn.code.sf.net/p/mingw-w64/code/trunk$MINGW_W64_REVISION
    456     echo "Checking out $MINGW64_SVN_URL $MINGW_W64_SRC"
    457     run svn co $MINGW64_SVN_URL $MINGW_W64_SRC
    458     PATCHES_DIR="$PROGDIR/toolchain-patches-host/mingw-w64"
    459     if [ -d "$PATCHES_DIR" ] ; then
    460         PATCHES=$(find "$PATCHES_DIR" -name "*.patch" | sort)
    461         for PATCH in $PATCHES; do
    462             echo "Patching mingw-w64-$MINGW_W64_REVISION with $PATCH"
    463             (cd $MINGW_W64_SRC && run patch -p0 < $PATCH)
    464         done
    465     fi
    466 fi
    467 
    468 # Let's generate the licenses/ directory
    469 LICENSES_DIR=$INSTALL_DIR/licenses/
    470 mkdir -p $LICENSES_DIR
    471 if [ ! -f $STAMP_DIR/licenses ]; then
    472     LICENSE_FILES=$(cd $SRC_DIR && find . -name "COPYING*")
    473     # Copy all license files to $LICENSES_DIR
    474     (tar cf - -C $SRC_DIR $LICENSE_FILES) | (tar xf - -C $LICENSES_DIR)
    475     touch $STAMP_DIR/licenses
    476 fi
    477 
    478 setup_build_env ()
    479 {
    480     local BINPREFIX=$1
    481 
    482     if [ "$BINPREFIX" ]; then
    483         CC=${BINPREFIX}gcc
    484         CXX=${BINPREFIX}g++
    485         LD=${BINPREFIX}ld
    486         AS=${BINPREFIX}as
    487         AR=${BINPREFIX}ar
    488         RANLIB=${BINPREFIX}ranlib
    489         STRIP=${BINPREFIX}strip
    490         export CC CXX LD AS AR RANLIB STRIP
    491     elif [ "$OS" = darwin ]; then
    492         # Needed on OS X otherwise libtool will try to use gcc and $BUILD_CFLAGS
    493         LD=ld
    494     fi
    495 
    496     export CFLAGS="$BUILD_CFLAGS"
    497     export CXXFLAGS="$BUILD_CFLAGS"
    498     export LDFLAGS="$BUILD_LDFLAGS"
    499 }
    500 
    501 setup_install_env ()
    502 {
    503     export PATH=$INSTALL_DIR/bin:$PATH
    504 }
    505 
    506 build_host_package ()
    507 {
    508     local PKGNAME=$1
    509     shift
    510 
    511     if [ ! -f $STAMP_DIR/$PKGNAME ]; then
    512         (
    513             mkdir -p $BUILD_DIR/$PKGNAME &&
    514             cd $BUILD_DIR/$PKGNAME &&
    515             setup_build_env $HOST_BINPREFIX &&
    516             log "$PKGNAME: Configuring" &&
    517             run $SRC_DIR/$PKGNAME/configure "$@"
    518             fail_panic "Can't configure $PKGNAME !!"
    519 
    520             log "$PKGNAME: Building" &&
    521             run make -j$JOBS
    522             fail_panic "Can't build $PKGNAME !!"
    523 
    524             log "$PKGNAME: Installing" &&
    525             run make install
    526             fail_panic "Can't install $PKGNAME"
    527         ) || exit 1
    528         touch $STAMP_DIR/$PKGNAME
    529     fi
    530 }
    531 
    532 export ABI=$HOST_BITS
    533 BASE_HOST_OPTIONS="--prefix=$INSTALL_DIR --disable-shared"
    534 build_host_package gmp-$GMP_VERSION $BASE_HOST_OPTIONS
    535 var_append BASE_HOST_OPTIONS "--with-gmp=$INSTALL_DIR"
    536 
    537 build_host_package mpfr-$MPFR_VERSION $BASE_HOST_OPTIONS
    538 var_append BASE_HOST_OPTIONS "--with-mpfr=$INSTALL_DIR"
    539 
    540 build_host_package mpc-$MPC_VERSION $BASE_HOST_OPTIONS
    541 var_append BASE_HOST_OPTIONS "--with-mpc=$INSTALL_DIR"
    542 
    543 BINUTILS_CONFIGURE_OPTIONS=$BASE_HOST_OPTIONS
    544 var_append BINUTILS_CONFIGURE_OPTIONS "--target=$TARGET_TAG --disable-nls"
    545 if [ "$TARGET_MULTILIBS" ]; then
    546     var_append BINUTILS_CONFIGURE_OPTIONS "--enable-targets=x86_64-w64-mingw32,i686-w64-mingw32"
    547 fi
    548 
    549 var_append BINUTILS_CONFIGURE_OPTIONS "--with-sysroot=$INSTALL_DIR"
    550 
    551 build_host_package binutils-$BINUTILS_VERSION $BINUTILS_CONFIGURE_OPTIONS
    552 
    553 build_mingw_tools ()
    554 {
    555     local PKGNAME=$1
    556     echo "$STAMP_DIR/$PKGNAME"
    557     if [ ! -f "$STAMP_DIR/$PKGNAME" ]; then
    558         (
    559             mkdir -p $BUILD_DIR/$PKGNAME &&
    560             cd $BUILD_DIR/$PKGNAME &&
    561             log "$PKGNAME: Configuring" &&
    562             run $MINGW_W64_SRC/mingw-w64-tools/widl/configure --prefix=$INSTALL_DIR --target=$TARGET_TAG
    563             fail_panic "Can't configure mingw-64-tools"
    564             log "$PKGNAME: Installing" &&
    565             run make install -j$JOBS
    566         ) || exit 1
    567         touch $STAMP_DIR/$PKGNAME
    568     fi
    569 }
    570 
    571 # Install the right mingw64 headers into the sysroot
    572 build_mingw_headers ()
    573 {
    574     local PKGNAME=$1
    575     if [ ! -f "$STAMP_DIR/$PKGNAME" ]; then
    576         (
    577             # If --with-widl only identifies the program name (svn version dependent)...
    578             if [ $(basename "$WITH_WIDL") = "$WITH_WIDL" ] ; then
    579                 # ...then need to add the right path too.
    580                 export PATH=$PATH:$INSTALL_DIR/bin
    581             fi
    582             fail_panic "Can't find widl"
    583             mkdir -p $BUILD_DIR/$PKGNAME &&
    584             cd $BUILD_DIR/$PKGNAME &&
    585             log "$PKGNAME: Configuring" &&
    586             run $MINGW_W64_SRC/mingw-w64-headers/configure --prefix=$PREFIX_FOR_TARGET --host=$TARGET_TAG \
    587                 --build=$HOST_TAG --with-widl=$WITH_WIDL --enable-sdk=all
    588             fail_panic "Can't configure mingw-64-headers"
    589 
    590             run make
    591             log "$PKGNAME: Installing" &&
    592             run make install -j$JOBS &&
    593             run cd $INSTALL_DIR &&
    594             run ln -s $TARGET_TAG mingw &&
    595             run cd $INSTALL_DIR/mingw &&
    596             run ln -s lib lib$TARGET_BITS
    597             fail_panic "Can't install mingw-64-headers"
    598         ) || exit 1
    599         touch $STAMP_DIR/$PKGNAME
    600     fi
    601 }
    602 
    603 # Slightly different from build_host_package because we need to call
    604 # 'make all-gcc' and 'make install-gcc' as a special case.
    605 #
    606 build_core_gcc ()
    607 {
    608     local PKGNAME=$1
    609     shift
    610 
    611     if [ ! -f "$STAMP_DIR/core-$PKGNAME" ]; then
    612         (
    613             mkdir -p $BUILD_DIR/$PKGNAME &&
    614             cd $BUILD_DIR/$PKGNAME &&
    615             setup_build_env $HOST_BINPREFIX &&
    616             log "core-$PKGNAME: Configuring" &&
    617             run $SRC_DIR/$PKGNAME/configure "$@"
    618             fail_panic "Can't configure $PKGNAME !!"
    619 
    620             log "core-$PKGNAME: Building" &&
    621             run make -j$JOBS all-gcc
    622             fail_panic "Can't build $PKGNAME !!"
    623 
    624             log "core-$PKGNAME: Installing" &&
    625             run make -j$JOBS install-gcc
    626             fail_panic "Can't install $PKGNAME"
    627         ) || exit 1
    628         touch $STAMP_DIR/core-$PKGNAME
    629     fi
    630 }
    631 
    632 
    633 # Build and install the C runtime files needed by the toolchain
    634 build_mingw_crt ()
    635 {
    636     local PKGNAME=$1
    637     shift
    638 
    639     if [ ! -f $STAMP_DIR/$PKGNAME ]; then
    640         (
    641             mkdir -p $BUILD_DIR/$PKGNAME &&
    642             cd $BUILD_DIR/$PKGNAME &&
    643             export PATH=$INSTALL_DIR/bin:$PATH
    644             log "$PKGNAME: Configuring" &&
    645             run $MINGW_W64_SRC/mingw-w64-crt/configure "$@"
    646             fail_panic "Can't configure $PKGNAME !!"
    647 
    648             log "$PKGNAME: Building" &&
    649             run make -j$JOBS
    650             fail_panic "Can't build $PKGNAME !!"
    651 
    652             log "$PKGNAME: Installing" &&
    653             run make -j$JOBS install
    654             fail_panic "Can't install $PKGNAME"
    655         ) || exit 1
    656         touch $STAMP_DIR/$PKGNAME
    657     fi
    658 }
    659 
    660 
    661 build_libgcc ()
    662 {
    663     local PKGNAME=$1
    664     shift
    665 
    666     if [ ! -f "$STAMP_DIR/libgcc-$PKGNAME" ]; then
    667         (
    668             # No configure step here! We're resuming work that was started
    669             # in build_core_gcc.
    670             cd $BUILD_DIR/$PKGNAME &&
    671             setup_build_env $HOST_BINPREFIX &&
    672             log "libgcc-$PKGNAME: Building" &&
    673             run make -j$JOBS
    674             fail_panic "Can't build libgcc-$PKGNAME !!"
    675 
    676             log "libgcc-$PKGNAME: Installing" &&
    677             run make -j$JOBS install
    678             fail_panic "Can't install libgcc-$PKGNAME"
    679         ) || exit 1
    680 
    681         touch "$STAMP_DIR/libgcc-$PKGNAME"
    682     fi
    683 }
    684 
    685 GCC_CONFIGURE_OPTIONS=$BASE_HOST_OPTIONS
    686 var_append GCC_CONFIGURE_OPTIONS "--target=$TARGET_TAG"
    687 if [ "$TARGET_MULTILIBS" ]; then
    688     var_append GCC_CONFIGURE_OPTIONS "--enable-targets=all"
    689 fi
    690 var_append GCC_CONFIGURE_OPTIONS "--enable-languages=c,c++"
    691 var_append GCC_CONFIGURE_OPTIONS "--with-sysroot=$INSTALL_DIR"
    692 
    693 # A bug in MinGW-w64 forces us to build and use widl.
    694 build_mingw_tools mingw-w64-tools
    695 build_mingw_headers mingw-w64-headers
    696 
    697 build_core_gcc gcc-$GCC_VERSION $GCC_CONFIGURE_OPTIONS
    698 
    699 CRT_CONFIGURE_OPTIONS="--host=$TARGET_TAG --with-sysroot=$INSTALL_DIR --prefix=$PREFIX_FOR_TARGET"
    700 if [ "$TARGET_MULTILIBS" ]; then
    701     var_append CRT_CONFIGURE_OPTIONS "--enable-lib32"
    702 fi
    703 
    704 build_mingw_crt mingw-w64-crt $CRT_CONFIGURE_OPTIONS
    705 
    706 build_libgcc gcc-$GCC_VERSION
    707 
    708 if [ "$PACKAGE_DIR" ]; then
    709     mkdir -p $PACKAGE_DIR
    710     fail_panic "Could not create packaging directory: $PACKAGE_DIR"
    711     PACKAGE_NAME=$PACKAGE_DIR/$TARGET_TAG-$OS-$HOST_ARCH.tar.bz2
    712     log "Packaging $TARGET_TAG toolchain to $PACKAGE_NAME"
    713     run tar cjf $PACKAGE_NAME -C $(dirname $INSTALL_DIR) $TARGET_TAG/
    714     fail_panic "Could not package $TARGET_TAG toolchain!"
    715     log "Done. See $PACKAGE_DIR:"
    716     ls -l $PACKAGE_NAME
    717 else
    718     log "Done. See: $INSTALL_DIR"
    719 fi
    720 
    721 if [ "$CLEANUP" ]; then
    722     log "Cleaning up..."
    723     rm -rf $TEMP_DIR/*
    724 fi
    725 
    726 exit 0
    727