David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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) |
Joshua Lang | b02b988 | 2015-10-22 14:53:38 -0700 | [diff] [blame] | 24 | PATCHES_DIR=$PROGDIR/toolchain-patches |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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 |
Joshua Lang | b02b988 | 2015-10-22 14:53:38 -0700 | [diff] [blame] | 137 | BINUTILS_VERSION=2.25 |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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" |
Joshua Lang | b02b988 | 2015-10-22 14:53:38 -0700 | [diff] [blame] | 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 |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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 |
Joshua Lang | b02b988 | 2015-10-22 14:53:38 -0700 | [diff] [blame] | 469 | LOCAL_PATCHES_DIR="$PATCHES_DIR/mingw-w64" |
| 470 | if [ -d "$LOCAL_PATCHES_DIR" ] ; then |
| 471 | PATCHES=$(find "$LOCAL_PATCHES_DIR" -name "*.patch" | sort) |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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 | |
Joshua Lang | b02b988 | 2015-10-22 14:53:38 -0700 | [diff] [blame] | 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 | |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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 | |
Joshua Lang | b02b988 | 2015-10-22 14:53:38 -0700 | [diff] [blame] | 590 | build_binutils_package binutils-$BINUTILS_VERSION $BINUTILS_CONFIGURE_OPTIONS |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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 \ |
Joshua Lang | 42e13b6 | 2015-11-05 17:13:55 -0800 | [diff] [blame] | 626 | --build=$HOST_TAG --with-widl=$WITH_WIDL --enable-sdk=all --enable-secure-api |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 627 | fail_panic "Can't configure mingw-64-headers" |
| 628 | |
| 629 | run make |
| 630 | log "$PKGNAME: Installing" && |
| 631 | run make install -j$JOBS && |
David 'Digit' Turner | 2725a17 | 2014-06-17 01:32:30 +0200 | [diff] [blame] | 632 | run cd $INSTALL_DIR && |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 633 | run ln -s $TARGET_TAG mingw && |
David 'Digit' Turner | 2725a17 | 2014-06-17 01:32:30 +0200 | [diff] [blame] | 634 | run cd $INSTALL_DIR/mingw && |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 635 | run ln -s lib lib$TARGET_BITS |
David 'Digit' Turner | 2725a17 | 2014-06-17 01:32:30 +0200 | [diff] [blame] | 636 | fail_panic "Can't install mingw-64-headers" |
David 'Digit' Turner | 3523514 | 2014-06-03 15:18:04 +0200 | [diff] [blame] | 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 |