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