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