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