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 host GCC toolchain binaries from sources. 18# 19# NOTE: this script does not rebuild gdb, see build-host-gdb.sh for this. 20# 21 22# include common function and variable definitions 23. `dirname $0`/prebuilt-common.sh 24 25PROGRAM_PARAMETERS="[<toolchain-name>+]" 26PROGRAM_DESCRIPTION="\ 27This program is used to rebuild one or more NDK cross-toolchains from scratch. 28To use it, you will first need to call download-toolchain-sources.sh to download 29the toolchain sources, then pass the corresponding directory with the 30--toolchain-src-dir=<path> option. 31 32If you don't pass any parameter, the script will rebuild all NDK toolchains 33for the current host system [$HOST_TAG]. You can otherwise give a list of 34toolchains among the following names: 35 36 arm-linux-androideabi-4.8 37 arm-linux-androideabi-4.9 38 x64-4.8 39 x86-4.9 40 mipsel-linux-android-4.8 41 mipsel-linux-android-4.9 42 aarch64-linux-android-4.9 43 mips64el-linux-android-4.9 44 x86_64-4.9 45 46By default, the script rebuilds the toolchain(s) for you host system [$HOST_TAG], 47but you can use --systems=<tag1>,<tag2>,.. to ask binaries that can run on 48several distinct systems. Each <tag> value in the list can be one of the 49following: 50 51 linux-x86 52 linux-x86_64 53 windows 54 windows-x86 (equivalent to 'windows') 55 windows-x86_64 56 darwin-x86 57 darwin-x86_64 58 59For example, here's how to rebuild the ARM toolchains on Linux 60for four different systems: 61 62 $PROGNAME --toolchain-src-dir=/path/to/toolchain/src \ 63 --systems=linux-x86,linux-x86_64,windows,windows-x86_64 \ 64 arm-linux-androideabi-4.8 \ 65 arm-linux-androideabi-4.9 66 67You can build Windows binaries on Linux if you have a Windows-targetting 68cross-toolchain installed and in your path. Note that the script named 69'build-mingw64-toolchain.sh' can be used to rebuild such a toolchain 70(x86_64-w64-mingw32) from sources if you don't have one available. 71 72Building the toolchains directly under Cygwin/MSys has not be tested and 73is not recommended (it will be *extremely* slow, if it ever works). 74 75On Darwin, the script will try to probe any compatibility SDK installed 76on your development machine and will use the first it finds among a list 77of well-known names. You can however force a specific usage with the 78--darwin-sdk-version=<version> name, where <version> can be one of 10.4, 10.5, 7910.6, 10.7, etc. 80 81The generated binaries should run on 10.5 or higher. You can force a 82different compatibility minimum with --darwin-min-version. 83 84If you want to build Darwin binaries on a non-Darwin machine, you will 85have to define DARWIN_TOOLCHAIN / DARWIN_SYSROOT in your environment first 86(note: this feature is highly experimental). 87 88The script is sufficiently clever to minimize all build steps, especially 89if you try to build several toolchains for several distinct host systems. Note 90however that generating a canadian-cross toolchain (e.g. building on Linux a 91Windows toolchain that targets Android ARM binaries) will force the generation 92of a host toolchain as well, in case it is not listed in your --systems list. 93This is required to generate proper target GCC libraries. 94 95The toolchain binaries are installed under \$NDK_DIR/toolchains by default, 96but you can use --ndk-dir=<path> to specify a different NDK installation path. 97The script will try to build the Gold linker for host/target combination that 98are well supported (Gold doesn't build / is buggy for some of them). However, 99the BFD linker is still the default used by the generated toolchain. You can 100change this behaviour with two options: 101 102 --default-ld=<name> Changes the default toolchain linker. 103 <name> can be one of 'default', 'bfd' and 'gold'. 104 105 For now, 'default' is an alias for 'bfd', but we plan 106 to map it to 'gold' for some combos in the future, once 107 we're confident it works reliably 108 109 --force-gold-build Force the build of the Gold linker, even if it is known 110 to fail or generate a buggy linker. Only use this for 111 experimentation (e.g. with your own patched toolchain 112 sources). 113" 114 115BINUTILS_VERSION=$DEFAULT_BINUTILS_VERSION 116register_var_option "--binutils-version=<version>" BINUTILS_VERSION "Select binutils version" 117 118GMP_VERSION=$DEFAULT_GMP_VERSION 119register_var_option "--gmp-version=<version>" GMP_VERSION "Select gmp version" 120 121MPFR_VERSION=$DEFAULT_MPFR_VERSION 122register_var_option "--mpfr-version=<version>" MPFR_VERSION "Select mpfr version" 123 124MPC_VERSION=$DEFAULT_MPC_VERSION 125register_var_option "--mpc-version=<version>" MPC_VERSION "Select mpc version" 126 127TOOLCHAIN_SRC_DIR= 128register_var_option "--toolchain-src-dir=<path>" TOOLCHAIN_SRC_DIR "Select toolchain source directory" 129 130NDK_DIR=$ANDROID_NDK_ROOT 131register_var_option "--ndk-dir=<path>" NDK_DIR "Select NDK install directory" 132 133BUILD_DIR= 134register_var_option "--build-dir=<path>" BUILD_DIR "Build GCC into directory" 135 136PACKAGE_DIR= 137register_var_option "--package-dir=<path>" PACKAGE_DIR "Package prebuilt tarballs into directory" 138 139HOST_SYSTEMS="$HOST_TAG" 140register_var_option "--systems=<list>" HOST_SYSTEMS "Build binaries for these host systems" 141 142FORCE= 143register_var_option "--force" FORCE "Force full rebuild" 144 145NO_TARGET_LIBS= 146register_var_option "--no-target-libs" NO_TARGET_LIBS "Don't build gcc target libs." 147 148NO_STRIP= 149register_var_option "--no-strip" NO_STRIP "Don't strip generated binaries." 150 151NO_COLOR= 152register_var_option "--no-color" NO_COLOR "Don't output colored text." 153 154if [ "$HOST_OS" = darwin ]; then 155 DARWIN_SDK_VERSION= 156 register_var_option "--darwin-sdk-version=<version>" DARWIN_SDK "Select Darwin SDK version." 157 158 DARWIN_MIN_VERSION= 159 register_var_option "--darwin-min-version=<version>" DARWIN_MIN_VERSION "Select minimum OS X version of generated host toolchains." 160fi 161 162DEFAULT_LD= 163register_var_option "--default-ld=<name>" DEFAULT_LD "Select default linker ('bfd' or 'gold')." 164 165FORCE_GOLD_BUILD= 166register_var_option "--force-gold-build" FORCE_GOLD_BUILD "Always try to build Gold (experimental)." 167 168register_jobs_option 169 170 171extract_parameters "$@" 172 173TOOLCHAINS=$PARAMETERS 174if [ -z "$TOOLCHAINS" ]; then 175 TOOLCHAINS="arm-linux-androideabi-4.8,x86-4.8,mipsel-linux-android-4.8" 176 dump "Auto-config: $TOOLCHAINS" 177fi 178 179if [ -z "$TOOLCHAIN_SRC_DIR" ]; then 180 panic "Please use --toolchain-src-dir=<path> to select toolchain source directory." 181fi 182 183if [ -z "$BUILD_DIR" ]; then 184 BUILD_DIR=/tmp/ndk-$USER/build/host-gcc 185fi 186 187case $DEFAULT_LD in 188 gold|bfd) 189 ;; 190 "") 191 # We always use the default gold linker. 192 # bfd is used for some of the older toolchains or archs not supported by gold. 193 DEFAULT_LD=gold 194 ;; 195 *) 196 panic "Invalid --default-ld name '$DEFAULT_LD', valid values are: bfd gold" 197 ;; 198esac 199 200HOST_SYSTEMS=$(commas_to_spaces $HOST_SYSTEMS) 201TOOLCHAINS=$(commas_to_spaces $TOOLCHAINS) 202 203# The values of HOST_OS/ARCH/TAG will be redefined during the build to 204# match those of the system the generated compiler binaries will run on. 205# 206# Save the original ones into BUILD_XXX variants, corresponding to the 207# machine where the build happens. 208# 209BUILD_OS=$HOST_OS 210BUILD_ARCH=$HOST_ARCH 211BUILD_TAG=$HOST_TAG 212 213# Important note: When identifying a build or host system, there is 214# a difference between 'NDK system tags' and "GNU configuration triplet'. 215# 216# A "system tag" is specific to the NDK and identifies a given host 217# system for the toolchain binaries, valid values: 218# 219# linux-x86 220# linux-x86_64 221# windows (historical alias to windows-x86) 222# windows-x86 223# windows-x86_64 224# darwin-x86 225# darwin-x86_64 226# 227# A GNU configuration triplet identifies a system too, but it used by 228# configure scripts, not the NDK. They vary a lot too and some of the 229# scripts are *very* picky about the exact values being used. 230# 231# Typical values that are known to work properly: 232# 233# i686-linux-gnu (Linux x86 system, with GNU libc) 234# x86_64-linux-gnu (Same, with x86_64 CPU) 235# i586-mingw32msvc (Windows 32-bits, MSVCRT.DLL) 236# i586-pc-mingw32msvc (same) 237# i686-w64-mingw32 (same, slightly different sources) 238# x86_64-w64-mingw32 (Windows 64-bits, MSVCRT.DLL) 239# i686-apple-darwin (OS X / Darwin, x86 CPU) 240# x86_64-apple-darwin (OS X / Darwin, x86_64 CPU) 241# 242# A cross-toolchain will typically use the GNU configuration triplet as 243# a prefix for all its binaries, but not always. For example, the 'mingw32' 244# package on Ubuntu provides a Windows cross-toolchain that uses the 245# i586-mingw32msvc prefix, but if you try to use it as a configuration 246# triplet when configuring binutils-2.21, the build will fail. You need to 247# pass i586-pc-mingw32msvc instead (binutils-2.19 accepts both). 248# 249# Another issue is that some toolchains need to use additional compiler 250# flags to deal with backwards-compatibility SDKs (Darwin) or 32/64 bit 251# code generation. Note all build scripts accept the same mix of 252# '--with-cflags=...' or 'export CFLAGS' configuration, which makes 253# things pretty difficult to manage. 254# 255# To work-around these issues, the script will generate "wrapper toolchains" 256# with the prefix that the configure scripts expects. I.e. small scripts that 257# redirect to the correct toolchain, eventually adding hidden extra compiler 258# flags. This seems to completely get rid of the problems described above. 259# 260 261 262# $1: system tag (e.g. linux-x86) 263tag_to_os () 264{ 265 local RET 266 case $1 in 267 linux-*) RET="linux";; 268 darwin-*) RET="darwin";; 269 windows|windows-*) RET="windows";; 270 esac 271 echo $RET 272} 273 274# $1: system tag (e.g. linux-x86) 275tag_to_arch () 276{ 277 local RET 278 case $1 in 279 windows|*-x86) RET=x86;; 280 *-x86_64) RET=x86_64;; 281 esac 282 echo $RET 283} 284 285# $1: system tag (e.g. linux-x86) 286tag_to_bits () 287{ 288 local RET 289 case $1 in 290 windows|*-x86) RET=32;; 291 *-x86_64) RET=64;; 292 esac 293 echo $RET 294} 295 296if [ "$NO_COLOR" ]; then 297 COLOR_GREEN= 298 COLOR_PURPLE= 299 COLOR_CYAN= 300 COLOR_END= 301else 302 COLOR_GREEN="\e[32m" 303 COLOR_PURPLE="\e[35m" 304 COLOR_CYAN="\e[36m" 305 COLOR_END="\e[0m" 306fi 307 308# Pretty printing with colors! 309host_text () 310{ 311 printf "[${COLOR_GREEN}${HOST}${COLOR_END}]" 312} 313 314toolchain_text () 315{ 316 printf "[${COLOR_PURPLE}${TOOLCHAIN}${COLOR_END}]" 317} 318 319target_text () 320{ 321 printf "[${COLOR_CYAN}${TARGET}${COLOR_END}]" 322} 323 324arch_text () 325{ 326 # Print arch name in cyan 327 printf "[${COLOR_CYAN}${ARCH}${COLOR_END}]" 328} 329 330# We're going to cheat a little here. If we're only building a linux-x86 331# on a linux-x86_64 machine, we want to change the value of BUILD_TAG 332# to linux-x86 instead to speed-up the build. 333# 334# More generally speaking, we need to verify that if: 335# - we build a $BUILD_OS-x86 toolchain on a $BUILD_OS-x86_64 machine 336# - we don't want to build $BUILD_OS-x86_64 either. 337# 338# Then we can change our BUILD values to $BUILD_OS-x86 339# This assumes that the build machine's toolchain can generate both 340# 32-bit and 64-bit binaries with either -m32 or -m64 341# 342BUILD_BUILD_32= 343BUILD_BUILD_64= 344for SYSTEM in $HOST_SYSTEMS; do 345 if [ "$(tag_to_os $SYSTEM)" = "$BUILD_OS" ]; then 346 BUILD_BUILD_OS=true 347 case $(tag_to_bits $SYSTEM) in 348 32) BUILD_BUILD_32=true;; 349 64) BUILD_BUILD_64=true;; 350 esac 351 fi 352done 353 354case $(tag_to_bits $BUILD_TAG) in 355 64) 356 # Building on a 64-bit machine 357 if [ "$BUILD_BUILD_32" -a -z "$BUILD_BUILD_64" ]; then 358 # Ok, we want to build a 32-bit toolchain on a 64-bit machine 359 # So cheat a little now :-) 360 BUILD_ARCH=x86 361 BUILD_TAG=$BUILD_OS-$BUILD_ARCH 362 dump "Forcing build config: $BUILD_TAG" 363 fi 364 ;; 365esac 366 367BUILD_BITS=$(tag_to_bits $BUILD_TAG) 368 369# On Darwin, parallel installs of certain libraries do not work on 370# some multi-core machines. So define NUM_BUILD_JOBS as 1 on this 371# platform. 372case $BUILD_OS in 373 darwin) NUM_INSTALL_JOBS=1;; 374 *) NUM_INSTALL_JOBS=$NUM_JOBS;; 375esac 376 377tag_to_config_triplet () 378{ 379 local RET 380 case $1 in 381 linux-x86) RET=i686-linux-gnu;; 382 linux-x86_64) RET=x86_64-linux-gnu;; 383 darwin-x86) RET=i686-apple-darwin;; 384 darwin-x86_64) RET=x86_64-apple-darwin;; 385 windows|windows-x86) RET=i586-pc-mingw32msvc;; 386 windows-x86_64) RET=x86_64-w64-mingw32;; 387 esac 388 echo "$RET" 389} 390 391run_on_setup () 392{ 393 if [ "$PHASE" = setup ]; then 394 run "$@" 395 fi 396} 397 398setup_build () 399{ 400 run_on_setup mkdir -p "$BUILD_DIR" 401 if [ -n "$FORCE" ]; then 402 rm -rf "$BUILD_DIR"/* 403 fi 404 405 TOP_BUILD_DIR=$BUILD_DIR 406 407 setup_default_log_file $BUILD_DIR/build.log 408 409 WRAPPERS_DIR="$BUILD_DIR/toolchain-wrappers" 410 run_on_setup mkdir -p "$WRAPPERS_DIR" && run_on_setup rm -rf "$WRAPPERS_DIR/*" 411 412 STAMPS_DIR="$BUILD_DIR/timestamps" 413 run_on_setup mkdir -p "$STAMPS_DIR" 414 if [ -n "$FORCE" ]; then 415 run_on_setup rm -f "$STAMPS_DIR"/* 416 fi 417 418 if [ "$PACKAGE_DIR" ]; then 419 mkdir -p "$PACKAGE_DIR" 420 fail_panic "Can't create packaging directory: $PACKAGE_DIR" 421 fi 422 423 BUILD=$(tag_to_config_triplet $BUILD_TAG) 424} 425 426stamps_do () 427{ 428 local NAME=$1 429 shift 430 if [ ! -f "$STAMPS_DIR/$NAME" ]; then 431 "$@" 432 fail_panic 433 mkdir -p "$STAMPS_DIR" && touch "$STAMPS_DIR/$NAME" 434 fi 435} 436 437# Check that a given compiler generates code correctly 438# 439# This is to detect bad/broken toolchains, e.g. amd64-mingw32msvc 440# is totally broken on Ubuntu 10.10 and 11.04 441# 442# $1: compiler 443# $2: optional extra flags 444# 445check_compiler () 446{ 447 local CC="$1" 448 local TMPC=/tmp/build-host-gcc-$USER-$$.c 449 local TMPE=${TMPC%%.c} 450 local TMPL=$TMPC.log 451 local RET 452 shift 453 cat > $TMPC <<EOF 454int main(void) { return 0; } 455EOF 456 log_n "Checking compiler code generation ($CC)... " 457 $CC -o $TMPE $TMPC "$@" >$TMPL 2>&1 458 RET=$? 459 rm -f $TMPC $TMPE $TMPL 460 if [ "$RET" = 0 ]; then 461 log "yes" 462 else 463 log "no" 464 fi 465 return $RET 466} 467 468 469# $1: toolchain install dir 470# $2: toolchain prefix, no trailing dash (e.g. arm-linux-androideabi) 471# $3: optional -m32 or -m64. 472try_host_fullprefix () 473{ 474 local PREFIX="$1/bin/$2" 475 shift; shift; 476 if [ -z "$HOST_FULLPREFIX" ]; then 477 local GCC="$PREFIX-gcc" 478 if [ -f "$GCC" ]; then 479 if check_compiler "$GCC" "$@"; then 480 HOST_FULLPREFIX="${GCC%%gcc}" 481 dump "$(host_text) Using host gcc: $GCC $@" 482 else 483 dump "$(host_text) Ignoring broken host gcc: $GCC $@" 484 fi 485 fi 486 fi 487} 488 489# $1: host prefix, no trailing slash (e.g. i686-linux-android) 490# $2: optional compiler args (should be empty, -m32 or -m64) 491try_host_prefix () 492{ 493 local PREFIX="$1" 494 shift 495 if [ -z "$HOST_FULLPREFIX" ]; then 496 local GCC="$(which $PREFIX-gcc 2>/dev/null)" 497 if [ "$GCC" -a -e "$GCC" ]; then 498 if check_compiler "$GCC" "$@"; then 499 HOST_FULLPREFIX=${GCC%%gcc} 500 dump "$(host_text) Using host gcc: ${HOST_FULLPREFIX}gcc $@" 501 else 502 dump "$(host_text) Ignoring broken host gcc: $GCC $@" 503 fi 504 fi 505 fi 506} 507 508# Used to determine the minimum possible Darwin version that a Darwin SDK 509# can target. This actually depends from the host architecture. 510# $1: Host architecture name 511# out: SDK version number (e.g. 10.4 or 10.5) 512darwin_arch_to_min_version () 513{ 514 if [ "$DARWIN_MIN_VERSION" ]; then 515 echo "$DARWIN_MIN_VERSION" 516 elif [ "$1" = "x86" ]; then 517 echo "10.4" 518 else 519 echo "10.5" 520 fi 521} 522 523# Use the check for the availability of a compatibility SDK in Darwin 524# this can be used to generate binaries compatible with either Tiger or 525# Leopard. 526# 527# $1: SDK root path 528# $2: Darwin architecture 529check_darwin_sdk () 530{ 531 if [ -d "$1" -a -z "$HOST_CFLAGS" ] ; then 532 local MINVER=$(darwin_arch_to_min_version $2) 533 HOST_CFLAGS="-isysroot $1 -mmacosx-version-min=$MINVER -DMAXOSX_DEPLOYEMENT_TARGET=$MINVER" 534 HOST_CXXFLAGS=$HOST_CFLAGS 535 HOST_LDFLAGS="-syslibroot $1 -mmacosx-version-min=$MINVER" 536 dump "Generating $MINVER-compatible binaries." 537 return 0 # success 538 fi 539 return 1 540} 541 542# Check that a given compiler generates 32 or 64 bit code. 543# $1: compiler full path (.e.g /path/to/fullprefix-gcc) 544# $2: 32 or 64 545# $3: extract compiler flags 546# Return: success iff the compiler generates $2-bits code 547check_compiler_bitness () 548{ 549 local CC="$1" 550 local BITS="$2" 551 local TMPC=/tmp/build-host-gcc-bits-$USER-$$.c 552 local TMPL=$TMPC.log 553 local RET 554 shift; shift; 555 cat > $TMPC <<EOF 556/* this program will fail to compile if the compiler doesn't generate BITS-bits code */ 557int tab[1-2*(sizeof(void*)*8 != BITS)]; 558EOF 559 dump_n "$(host_text) Checking that the compiler generates $BITS-bits code ($@)... " 560 $CC -c -DBITS=$BITS -o /dev/null $TMPC $HOST_CFLAGS "$@" > $TMPL 2>&1 561 RET=$? 562 rm -f $TMPC $TMPL 563 if [ "$RET" = 0 ]; then 564 dump "yes" 565 else 566 dump "no" 567 fi 568 return $RET 569} 570 571# This function probes the system to find the best toolchain or cross-toolchain 572# to build binaries that run on a given host system. After that, it generates 573# a wrapper toolchain under $WRAPPERS_DIR with a prefix of ${HOST}- 574# where $HOST is a GNU configuration name. 575# 576# Important: this script might redefine $HOST to a different value! 577# Important: must be called after setup_build. 578# 579# $1: NDK system tag (e.g. linux-x86) 580# 581select_toolchain_for_host () 582{ 583 local HOST_CFLAGS HOST_CXXFLAGS HOST_LDFLAGS HOST_FULLPREFIX DARWIN_ARCH 584 585 # We do all the complex auto-detection magic in the setup phase, 586 # then save the result in host-specific global variables. 587 # 588 # In the build phase, we will simply restore the values into the 589 # global HOST_FULLPREFIX / HOST_BUILD_DIR 590 # variables. 591 # 592 593 # Try to find the best toolchain to do that job, assuming we are in 594 # a full Android platform source checkout, we can look at the prebuilts/ 595 # directory. 596 case $1 in 597 linux-x86) 598 # If possible, automatically use our custom toolchain to generate 599 # 32-bit executables that work on Ubuntu 8.04 and higher. 600 try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" i686-linux 601 try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.4.3" i686-linux 602 try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3" i686-linux 603 try_host_prefix i686-linux-gnu 604 try_host_prefix i686-linux 605 try_host_prefix x86_64-linux-gnu -m32 606 try_host_prefix x86_64-linux -m32 607 ;; 608 609 linux-x86_64) 610 # If possible, automaticaly use our custom toolchain to generate 611 # 64-bit executables that work on Ubuntu 8.04 and higher. 612 try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" x86_64-linux 613 try_host_prefix x86_64-linux-gnu 614 try_host_prefix x84_64-linux 615 try_host_prefix i686-linux-gnu -m64 616 try_host_prefix i686-linux -m64 617 ;; 618 619 darwin-*) 620 DARWIN_ARCH=$(tag_to_arch $1) 621 case $BUILD_OS in 622 darwin) 623 if [ "$DARWIN_SDK_VERSION" ]; then 624 # Compute SDK subdirectory name 625 case $DARWIN_SDK_VERSION in 626 10.4) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdku;; 627 *) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdk;; 628 esac 629 # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder. 630 check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_ARCH 631 check_darwin_sdk /Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_ARCH 632 else 633 # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder. 634 check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk $DARWIN_ARCH 635 check_darwin_sdk /Developer/SDKs/MacOSX10.7.sdk $DARWIN_ARCH 636 check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk $DARWIN_ARCH 637 # NOTE: The 10.5.sdk on Lion is buggy and cannot build basic C++ programs 638 #check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk $DARWIN_ARCH 639 # NOTE: The 10.4.sdku is not available anymore and could not be tested. 640 #check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku $DARWIN_ARCH 641 fi 642 if [ -z "$HOST_CFLAGS" ]; then 643 local version="$(sw_vers -productVersion)" 644 log "Generating $version-compatible binaries!" 645 fi 646 ;; 647 *) 648 if [ -z "$DARWIN_TOOLCHAIN" -o -z "$DARWIN_SYSROOT" ]; then 649 dump "If you want to build Darwin binaries on a non-Darwin machine," 650 dump "Please define DARWIN_TOOLCHAIN to name it, and DARWIN_SYSROOT to point" 651 dump "to the SDK. For example:" 652 dump "" 653 dump " DARWIN_TOOLCHAIN=\"i686-apple-darwin11\"" 654 dump " DARWIN_SYSROOT=\"~/darwin-cross/MacOSX10.7.sdk\"" 655 dump " export DARWIN_TOOLCHAIN DARWIN_SYSROOT" 656 dump "" 657 exit 1 658 fi 659 local DARWINMINVER=$(darwin_arch_to_min_version $2) 660 check_darwin_sdk $DARWIN_SYSROOT $DARWINARCH 661 try_host_prefix "$DARWIN_TOOLCHAIN" -m$(tag_to_bits $1) --sysroot "$DARWIN_SYSROOT" 662 if [ -z "$HOST_FULLPREFIX" ]; then 663 dump "It looks like $DARWIN_TOOLCHAIN-gcc is not in your path, or does not work correctly!" 664 exit 1 665 fi 666 dump "Using darwin cross-toolchain: ${HOST_FULLPREFIX}gcc" 667 ;; 668 esac 669 ;; 670 671 windows|windows-x86) 672 case $BUILD_OS in 673 linux) 674 # We favor these because they are more recent, and because 675 # we have a script to rebuild them from scratch. See 676 # build-mingw64-toolchain.sh. 677 try_host_prefix x86_64-w64-mingw32 -m32 678 try_host_prefix i686-w64-mingw32 679 # Typically provided by the 'mingw32' package on Debian 680 # and Ubuntu systems. 681 try_host_prefix i586-mingw32msvc 682 # Special note for Fedora: this distribution used 683 # to have a mingw32-gcc package that provided a 32-bit 684 # only cross-toolchain named i686-pc-mingw32. 685 # Later versions of the distro now provide a new package 686 # named mingw-gcc which provides i686-w64-mingw32 and 687 # x86_64-w64-mingw32 instead. 688 try_host_prefix i686-pc-mingw32 689 if [ -z "$HOST_FULLPREFIX" ]; then 690 dump "There is no Windows cross-compiler. Ensure that you" 691 dump "have one of these installed and in your path:" 692 dump " x86_64-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 693 dump " i686-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 694 dump " i586-mingw32msvc-gcc ('mingw32' Debian/Ubuntu package)" 695 dump " i686-pc-mingw32 (on Fedora)" 696 dump "" 697 exit 1 698 fi 699 # Adjust $HOST to match the toolchain to ensure proper builds. 700 # I.e. chose configuration triplets that are known to work 701 # with the gmp/mpfr/mpc/binutils/gcc configure scripts. 702 case $HOST_FULLPREFIX in 703 *-mingw32msvc-*|i686-pc-mingw32) 704 HOST=i586-pc-mingw32msvc 705 ;; 706 *) 707 HOST=i686-w64-mingw32msvc 708 ;; 709 esac 710 ;; 711 *) panic "Sorry, this script only supports building windows binaries on Linux." 712 ;; 713 esac 714 ;; 715 716 windows-x86_64) 717 # Sanity check for GMP which doesn't build with x86_64-w64-mingw32-gcc 718 # before 5.0. We already have 5.0.5 in AOSP toolchain source tree, so 719 # suggest it here. 720 if ! version_is_at_least $GMP_VERSION 5.0; then 721 dump "You cannot build a 64-bit Windows toolchain with this version of libgmp." 722 dump "Please use --gmp-version=5.0.5 to fix this." 723 exit 1 724 fi 725 case $BUILD_OS in 726 linux) 727 # See comments above for windows-x86 728 try_host_prefix x86_64-w64-mingw32 729 try_host_prefix i686-w64-mingw32 -m64 730 # Beware that this package is completely broken on many 731 # versions of no vinegar Ubuntu (i.e. it fails at building trivial 732 # programs). 733 try_host_prefix amd64-mingw32msvc 734 # There is no x86_64-pc-mingw32 toolchain on Fedora. 735 if [ -z "$HOST_FULLPREFIX" ]; then 736 dump "There is no Windows cross-compiler in your path. Ensure you" 737 dump "have one of these installed and in your path:" 738 dump " x86_64-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 739 dump " i686-w64-mingw32-gcc (see build-mingw64-toolchain.sh)" 740 dump " amd64-mingw32msvc-gcc (Debian/Ubuntu - broken until Ubuntu 11.10)" 741 dump "" 742 exit 1 743 fi 744 # See comment above for windows-x86 745 case $HOST_FULLPREFIX in 746 *-mingw32msvc*) 747 # Actually, this has never been tested. 748 HOST=amd64-pc-mingw32msvc 749 ;; 750 *) 751 HOST=x86_64-w64-mingw32 752 ;; 753 esac 754 ;; 755 756 *) panic "Sorry, this script only supports building windows binaries on Linux." 757 ;; 758 esac 759 ;; 760 esac 761 762 mkdir -p "$(host_build_dir)" 763 if [ "$FORCE" ]; then 764 rm -rf "$(host_build_dir)"/* 765 fi 766 767 # Determine the default bitness of our compiler. It it doesn't match 768 # HOST_BITS, tries to see if it supports -m32 or -m64 to change it. 769 if ! check_compiler_bitness ${HOST_FULLPREFIX}gcc $HOST_BITS; then 770 TRY_CFLAGS= 771 case $HOST_BITS in 772 32) TRY_CFLAGS=-m32;; 773 64) TRY_CFLAGS=-m64;; 774 esac 775 if ! check_compiler_bitness ${HOST_FULLPREFIX}gcc $HOST_BITS $TRY_CFLAGS; then 776 panic "Can't find a way to generate $HOST_BITS binaries with this compiler: ${HOST_FULLPREFIX}gcc" 777 fi 778 HOST_CFLAGS=$HOST_CFLAGS" "$TRY_CFLAGS 779 HOST_CXXFLAGS=$HOST_CXXFLAGS" "$TRY_CFLAGS 780 fi 781 782 # Support for ccache, to speed up rebuilds. 783 DST_PREFIX=$HOST_FULLPREFIX 784 if [ "$NDK_CCACHE" ]; then 785 DST_PREFIX="$NDK_CCACHE $HOST_FULLPREFIX" 786 fi 787 788 # We're going to generate a wrapper toolchain with the $HOST prefix 789 # i.e. if $HOST is 'i686-linux-gnu', then we're going to generate a 790 # wrapper toolchain named 'i686-linux-gnu-gcc' that will redirect 791 # to whatever HOST_FULLPREFIX points to, with appropriate modifier 792 # compiler/linker flags. 793 # 794 # This helps tremendously getting stuff to compile with the GCC 795 # configure scripts. 796 # 797 run $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh "$WRAPPERS_DIR" \ 798 --src-prefix="$HOST-" \ 799 --dst-prefix="$DST_PREFIX" \ 800 --cflags="$HOST_CFLAGS" \ 801 --cxxflags="$HOST_CXXFLAGS" \ 802 --ldflags="$HOST_LDFLAGS" 803} 804 805# Call this before anything else to setup a few important variables that are 806# used consistently to build any host-specific binaries. 807# 808# $1: Host system name (e.g. linux-x86), this is the name of the host system 809# where the generated GCC binaries will run, not the current machine's 810# type (this one is in $ORIGINAL_HOST_TAG instead). 811# 812setup_build_for_host () 813{ 814 local HOST_VARNAME=$(dashes_to_underscores $1) 815 local HOST_VAR=_HOST_${HOST_VARNAME} 816 817 # Determine the host configuration triplet in $HOST 818 HOST=$(tag_to_config_triplet $1) 819 HOST_OS=$(tag_to_os $1) 820 HOST_ARCH=$(tag_to_arch $1) 821 HOST_BITS=$(tag_to_bits $1) 822 HOST_TAG=$1 823 824 # Note: since select_toolchain_for_host can change the value of $HOST 825 # we need to save it in a variable to later get the correct one when 826 # this function is called again. 827 if [ -z "$(var_value ${HOST_VAR}_SETUP)" ]; then 828 select_toolchain_for_host $1 829 var_assign ${HOST_VAR}_CONFIG $HOST 830 var_assign ${HOST_VAR}_SETUP true 831 else 832 HOST=$(var_value ${HOST_VAR}_CONFIG) 833 fi 834} 835 836# Returns the location of all $HOST specific files (build and install) 837host_build_dir () 838{ 839 echo "$TOP_BUILD_DIR/$HOST" 840} 841 842# Return the location of the build directory for a specific component 843# $1: component name (e.g. gmp-4.2.4) 844host_build_dir_for () 845{ 846 echo "$(host_build_dir)/build-$1" 847} 848 849# Returns the install location of the $HOST pre-reqs libraries 850host_prereqs_install_dir () 851{ 852 echo "$(host_build_dir)/temp-prereqs" 853} 854 855# Returns the install location of the $HOST binutils cross-toolchain 856host_binutils_install_dir () 857{ 858 echo "$(host_build_dir)/temp-binutils-$BINUTILS_VERSION-$TARGET" 859} 860 861# Returns the install location of the $HOST binutils cross-toolchain 862build_binutils_install_dir () 863{ 864 echo "$TOP_BUILD_DIR/$BUILD/temp-binutils-$BINUTILS_VERSION-$TARGET" 865} 866 867# Returns the install location of the $HOST gcc cross-toolchain 868host_gcc_install_dir () 869{ 870 echo "$(host_build_dir)/temp-$TOOLCHAIN" 871} 872 873# Returns the install location of the $BUILD gcc cross-toolchain 874build_gcc_install_dir () 875{ 876 echo "$TOP_BUILD_DIR/$BUILD/temp-$TOOLCHAIN" 877} 878 879 880# Location of the host sysroot used during the build 881host_sysroot () 882{ 883 # This must be a sub-directory of $(host_gcc_install_dir) 884 # to generate relocatable binaries that are used by 885 # standalone versions of the toolchain. 886 # 887 # If you change this, you will need to modify make-standalone-toolchain.sh 888 # as well. 889 # 890 echo "$(host_gcc_install_dir)/sysroot" 891} 892 893# Returns the final install location of the $HOST toolchain 894# This ones contains the binutils binaries, the gcc ones, 895# the target libraries, but does *not* include the sysroot 896# and other stuff (e.g. documentation like info or man files). 897# 898host_gcc_final_dir () 899{ 900 echo "$(host_build_dir)/final-$TOOLCHAIN" 901} 902 903setup_build_for_toolchain () 904{ 905 GCC_VERSION=$(extract_version $1) 906 BINUTILS_VERSION=$(get_default_binutils_version_for_gcc $1) 907 908 TARGET_ARCH=$(echo $1 | cut -d - -f 1) 909 910 # NOTE: The 'mipsel' toolchain architecture name maps to the 'mips' 911 # NDK architecture name. 912 case $TARGET_ARCH in 913 arm) TARGET=arm-linux-androideabi;; 914 x86) TARGET=i686-linux-android;; 915 x86_64) TARGET=x86_64-linux-android;; 916 mips|mipsel) TARGET=mipsel-linux-android; TARGET_ARCH=mips;; 917 *) panic "Unknown target toolchain architecture: $TARGET_ARCH" 918 esac 919 920 # MPC is only needed starting with GCC 4.5 921 HOST_NEED_MPC= 922 if version_is_at_least $GCC_VERSION 4.5; then 923 HOST_NEED_MPC=true 924 fi 925 926 # TODO: We will need to place these under 927 # $NDK_DIR/prebuilts/$HOST/android-$TARGET_ARCH-gcc-$GCC_VERSION/ 928 # in a future patch. 929 TOOLCHAIN_SUB_DIR=toolchains/$TOOLCHAIN/prebuilt/$HOST_TAG 930 TOOLCHAIN_INSTALL_DIR=$NDK_DIR/$TOOLCHAIN_SUB_DIR 931 932 # These will go into CFLAGS_FOR_TARGET and others during the build 933 # of GCC target libraries. 934 if [ -z "$NO_STRIP" ]; then 935 TARGET_CFLAGS="-O2 -s" 936 else 937 TARGET_CFLAGS="-Os -g" 938 fi 939 940 TARGET_CXXFLAGS=$TARGET_CFLAGS 941 TARGET_LDFLAGS="" 942 943 case $TARGET_ARCH in 944 mips) 945 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 946 # You can't really build these separately at the moment. 947 # Add -fpic, because MIPS NDK will need to link .a into .so. 948 TARGET_CFLAGS=$TARGET_CFLAGS" -fexceptions -fpic" 949 TARGET_CXXFLAGS=$TARGET_CXXFLAGS" -frtti -fpic" 950 ;; 951 esac 952} 953 954# This function is used to setup the build environment whenever we 955# generate host-specific binaries. 956# 957setup_host_env () 958{ 959 CC=$HOST-gcc 960 CXX=$HOST-g++ 961 LD=$HOST-ld 962 AR=$HOST-ar 963 AS=$HOST-as 964 RANLIB=$HOST-ranlib 965 NM=$HOST-nm 966 STRIP=$HOST-strip 967 STRINGS=$HOST-strings 968 export CC CXX AS LD AR RANLIB STRIP STRINGS NM 969 970 CFLAGS= 971 CXXFLAGS= 972 LDFLAGS= 973 if [ -z "$NO_STRIP" ]; then 974 CFLAGS="-O2 -Os -fomit-frame-pointer -s" 975 CXXFLAGS=$CFLAGS 976 fi 977 978 # This should only used when building the target GCC libraries 979 CFLAGS_FOR_TARGET=$TARGET_CFLAGS 980 CXXFLAGS_FOR_TARGET=$TARGET_CXXFLAGS 981 LDFLAGS_FOR_TARGET=$TARGET_LDFLAGS 982 983 export CFLAGS CXXFLAGS LDFLAGS CFLAGS_FOR_TARGET CXXFLAGS_FOR_TARGET LDFLAGS_FOR_TARGET 984 985 PATH=$WRAPPERS_DIR:$PATH 986} 987 988# $1: NDK architecture name (e.g. 'arm') 989arch_sysroot_install_dir () 990{ 991 echo "$BUILD_DIR/arch-$1/sysroot" 992} 993 994# $1: NDK architecture name (e.g. 'arm') 995arch_sysroot_dir () 996{ 997 echo "$(arch_sysroot_install_dir $1)/$(get_default_platform_sysroot_for_arch $1)" 998} 999 1000# $1: architecture name 1001gen_minimal_sysroot () 1002{ 1003 local ARCH=$1 1004 local INSTALL_DIR=$(arch_sysroot_install_dir $ARCH) 1005 1006 dump "$(arch_text) Generating minimal sysroot." 1007 run2 $NDK_BUILDTOOLS_PATH/gen-platforms.sh --minimal --arch=$ARCH --dst-dir="$INSTALL_DIR" 1008} 1009 1010 1011# $1: gmp version 1012extract_gmp_sources () 1013{ 1014 local SRC_DIR="$TOP_BUILD_DIR/temp-src" 1015 1016 dump "Extracting gmp-$1" 1017 run2 mkdir -p "$SRC_DIR" && 1018 run2 tar xjf "$TOOLCHAIN_SRC_DIR/gmp/gmp-$1.tar.bz2" -C "$SRC_DIR" 1019} 1020 1021# $1: gmp version 1022build_gmp () 1023{ 1024 local SRC_DIR="$TOP_BUILD_DIR/temp-src/gmp-$1" 1025 local INSTALL_DIR="$(host_prereqs_install_dir)" 1026 local BUILD_DIR 1027 1028 stamps_do extract-gmp-$1 extract_gmp_sources $1 1029 1030 dump "$(host_text) Building gmp-$1" 1031 ( 1032 setup_host_env && 1033 BUILD_DIR="$(host_build_dir_for gmp-$GMP_VERSION)" && 1034 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1035 cd "$BUILD_DIR" && 1036 run2 "$SRC_DIR"/configure \ 1037 --prefix=$INSTALL_DIR \ 1038 --build=$BUILD \ 1039 --host=$HOST \ 1040 --disable-shared && 1041 run2 make -j$NUM_JOBS && 1042 run2 make install -j$NUM_INSTALL_JOBS 1043 ) 1044 return $? 1045} 1046 1047extract_mpfr_sources () 1048{ 1049 local SRC_DIR="$TOP_BUILD_DIR/temp-src" 1050 1051 dump "Extracting mpfr-$1" 1052 run2 mkdir -p "$SRC_DIR" && 1053 run2 tar xjf "$TOOLCHAIN_SRC_DIR/mpfr/mpfr-$1.tar.bz2" -C "$SRC_DIR" 1054} 1055 1056# $1: mpfr-version 1057build_mpfr () 1058{ 1059 local SRC_DIR="$TOP_BUILD_DIR/temp-src/mpfr-$1" 1060 local INSTALL_DIR="$(host_prereqs_install_dir)" 1061 local BUILD_DIR 1062 1063 stamps_do extract-mpfr-$MPFR_VERSION extract_mpfr_sources $1 1064 1065 stamps_do build-gmp-$GMP_VERSION-$HOST build_gmp $GMP_VERSION 1066 1067 dump "$(host_text) Building mpfr-$1" 1068 ( 1069 setup_host_env && 1070 BUILD_DIR="$(host_build_dir_for mpfr-$MPFR_VERSION)" && 1071 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1072 cd $BUILD_DIR && 1073 run2 "$SRC_DIR"/configure \ 1074 --prefix=$INSTALL_DIR \ 1075 --build=$BUILD \ 1076 --host=$HOST \ 1077 --disable-shared \ 1078 --with-gmp=$INSTALL_DIR && 1079 run2 make -j$NUM_JOBS && 1080 run2 make -j$NUM_INSTALL_JOBS install 1081 ) 1082 return $? 1083} 1084 1085# $1: mpc-version 1086extract_mpc_sources () 1087{ 1088 local SRC_DIR="$TOP_BUILD_DIR/temp-src" 1089 1090 dump "Extracting mpc-$1" 1091 run2 mkdir -p "$SRC_DIR" && 1092 run2 tar xzf "$TOOLCHAIN_SRC_DIR/mpc/mpc-$1.tar.gz" -C "$SRC_DIR" 1093} 1094 1095 1096# $1: mpc-version 1097build_mpc () 1098{ 1099 local SRC_DIR="$TOP_BUILD_DIR/temp-src/mpc-$1" 1100 local INSTALL_DIR="$(host_prereqs_install_dir)" 1101 local BUILD_DIR 1102 1103 stamps_do extract-mpc-$1 extract_mpc_sources $1 1104 1105 stamps_do build-mpfr-$MPFR_VERSION-$HOST build_mpfr $MPFR_VERSION 1106 1107 dump "$(host_text) Building mpc-$1" 1108 ( 1109 setup_host_env && 1110 BUILD_DIR="$(host_build_dir_for mpc-$MPC_VERSION)" && 1111 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1112 cd $BUILD_DIR && 1113 run2 "$SRC_DIR"/configure \ 1114 --prefix=$INSTALL_DIR \ 1115 --build=$BUILD \ 1116 --host=$HOST \ 1117 --disable-shared \ 1118 --with-gmp=$INSTALL_DIR \ 1119 --with-mpfr=$INSTALL_DIR && 1120 run2 make -j$NUM_JOBS && 1121 run2 make -j$NUM_INSTALL_JOBS install 1122 ) 1123 return $? 1124} 1125 1126# Build all pre-required host libraries (gmp, mpfr, etc...) that are needed 1127# by binutils and gcc, as static libraries that will be placed under 1128# $HOST_BUILD_DIR/temp-install 1129# 1130# $1: toolchain source directory 1131# 1132build_host_prereqs () 1133{ 1134 local INSTALL_DIR="$(host_prereqs_install_dir)" 1135 local ARGS 1136 1137 ARGS=" --with-gmp=$INSTALL_DIR --with-mpfr=$INSTALL_DIR" 1138 1139 # Only build MPC when we need it. 1140 if [ "$HOST_NEED_MPC" ]; then 1141 ARGS=$ARGS" --with-mpc=$INSTALL_DIR" 1142 stamps_do build-mpc-$MPC_VERSION-$HOST build_mpc $MPC_VERSION 1143 else 1144 stamps_do build-mpfr-$MPFR_VERSION-$HOST build_mpfr $MPFR_VERSION 1145 fi 1146 1147 # This gets used by build_host_binutils and others. 1148 HOST_PREREQS_ARGS=$ARGS 1149} 1150 1151build_host_binutils () 1152{ 1153 local SRC_DIR="$TOOLCHAIN_SRC_DIR/binutils/binutils-$BINUTILS_VERSION" 1154 local INSTALL_DIR="$(host_binutils_install_dir)" 1155 local PREREQS_INSTALL_DIR="$(host_prereqs_install_dir)" 1156 local ARGS 1157 1158 build_host_prereqs 1159 1160 ARGS=" --with-gmp=$PREREQS_INSTALL_DIR --with-mpfr=$PREREQS_INSTALL_DIR" 1161 if [ "$HOST_NEED_MPC" ]; then 1162 ARGS=$ARGS" --with-mpc=$PREREQS_INSTALL_DIR" 1163 fi 1164 1165 LD_NAME=$DEFAULT_LD 1166 1167 # Enable Gold globally. It can be built for all hosts. 1168 BUILD_GOLD=true 1169 1170 # Special case, gold is not ready for mips yet. 1171 if [ "$TARGET" = "mipsel-linux-android" ]; then 1172 BUILD_GOLD= 1173 fi 1174 1175 # Another special case, gold in binutils-2.21 for arch-x86 is buggy 1176 # (i.e. when building the platform with it, the system doesn't boot) 1177 # 1178 if [ "$BINUTILS_VERSION" = "2.21" -a "$TARGET" = "i686-linux-android" ]; then 1179 USE_LD_DEFAULT=true 1180 BUILD_GOLD= 1181 fi 1182 1183 # Another special case, for arch-x86_64 gold supports x32 starting from 2.23 1184 # 1185 if [ "$TARGET" = "x86_64-linux-android" ]; then 1186 if ! version_is_at_least $BINUTILS_VERSION 2.23; then 1187 USE_LD_DEFAULT=true 1188 BUILD_GOLD= 1189 fi 1190 fi 1191 1192 # Another special case. Not or 2.19, it wasn't ready 1193 if [ "$BINUTILS_VERSION" = "2.19" ]; then 1194 BUILD_GOLD= 1195 fi 1196 1197 if [ "$DEFAULT_LD" = "gold" -a -z "$BUILD_GOLD" ]; then 1198 dump "$(host_text)$(target_text): Cannot build Gold for this toolchain!" 1199 BUILD_GOLD= 1200 fi 1201 1202 # Ok, if the user *really* wants it, we're going to build Gold anyway. 1203 # There are no guarantees about the correctness of the resulting binary. 1204 # --default-ld still determines the default linker to use by the toolchain. 1205 # 1206 if [ "$FORCE_GOLD_BUILD" -a -z "$BUILD_GOLD" ]; then 1207 dump "$(host_text)$(target_text): Warning: forcing build of potentially buggy Gold linker!" 1208 BUILD_GOLD=true 1209 fi 1210 1211 # The BFD linker is always built, but to build Gold, we need a specific 1212 # option for the binutils configure script. Note that its format has 1213 # changed during development. 1214 export host_configargs= 1215 if [ "$BUILD_GOLD" ]; then 1216 # The syntax of the --enable-gold option has changed. 1217 if version_is_at_least $BINUTILS_VERSION 2.20; then 1218 if [ "$DEFAULT_LD" = "bfd" ]; then 1219 ARGS=$ARGS" --enable-gold --enable-ld=default" 1220 else 1221 ARGS=$ARGS" --enable-gold=default --enable-ld" 1222 fi 1223 else 1224 if [ "$DEFAULT_LD" = "bfd" ]; then 1225 ARGS=$ARGS" --enable-gold=both" 1226 else 1227 ARGS=$ARGS" --enable-gold=both/gold" 1228 fi 1229 fi 1230 # This ARG needs quoting when passed to run2. 1231 GOLD_LDFLAGS_ARG= 1232 if [ "$HOST_OS" = 'windows' ]; then 1233 # gold may have runtime dependency on libgcc_sjlj_1.dll and 1234 # libstdc++-6.dll when built by newer versions of mingw. 1235 # Link them statically to avoid that. 1236 if version_is_at_least $BINUTILS_VERSION 2.22; then 1237 export host_configargs="--with-gold-ldflags='-static-libgcc -static-libstdc++'" 1238 elif version_is_at_least $BINUTILS_VERSION 2.21; then 1239 GOLD_LDFLAGS_ARG="--with-gold-ldflags=-static-libgcc -static-libstdc++" 1240 else 1241 export LDFLAGS=$LDFLAGS" -static-libgcc -static-libstdc++" 1242 fi 1243 fi 1244 fi 1245 1246 # This is used to install libbfd which is later used to compile 1247 # oprofile for the platform. This is not technically required for 1248 # the NDK, but allows us to use the same toolchain for the platform 1249 # build. TODO: Probably want to move this step to its own script 1250 # like build-host-libbfd.sh in the future. 1251 ARGS=$ARGS" --enable-install-libbfd" 1252 1253 # Enable plugins support for binutils-2.21+ 1254 # This is common feature for binutils and gcc 1255 case "$BINUTILS_VERSION" in 1256 2.19) 1257 # Add nothing 1258 ;; 1259 *) 1260 ARGS=$ARGS" --enable-plugins" 1261 ;; 1262 esac 1263 1264 dump "$(host_text)$(target_text) Building binutils-$BINUTILS_VERSION" 1265 ( 1266 setup_host_env && 1267 BUILD_DIR="$(host_build_dir_for binutils-$BINUTILS_VERSION-$TARGET)" && 1268 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1269 cd "$BUILD_DIR" && 1270 run2 "$SRC_DIR"/configure \ 1271 --prefix="$INSTALL_DIR" \ 1272 --disable-shared \ 1273 --disable-werror \ 1274 --disable-nls \ 1275 --build=$BUILD \ 1276 --host=$HOST \ 1277 --target=$TARGET \ 1278 --with-sysroot="$INSTALL_DIR/sysroot" \ 1279 $ARGS && 1280 run2 make -j$NUM_JOBS && 1281 run2 make -j$NUM_INSTALL_JOBS install && 1282 # We need to take care of something weird, binutils-2.21 on mips 1283 # does not seem to build gold, and the Makefile script forgets to 1284 # copy it to $INSTALL/bin/mipsel-linux-android-ld. Take care of this 1285 # here with a symlink, which will be enough for now. 1286 if [ ! -f "$INSTALL_DIR/bin/$TARGET-ld" ]; then 1287 run2 ln -s "$TARGET-ld.bfd" "$INSTALL_DIR/bin/$TARGET-ld" 1288 fi 1289 ) 1290 return $? 1291} 1292 1293copy_target_sysroot () 1294{ 1295 local SRC_SYSROOT=$(arch_sysroot_dir $TARGET_ARCH) 1296 local SYSROOT=$(host_sysroot) 1297 1298 # We need the arch-specific minimal sysroot 1299 stamps_do sysroot-arch-$TARGET_ARCH gen_minimal_sysroot $TARGET_ARCH 1300 1301 dump "$(host_text)$(toolchain_text) Copying $TARGET_ARCH sysroot" 1302 run2 rm -rf "$SYSROOT" && 1303 run2 copy_directory "$SRC_SYSROOT" "$SYSROOT" 1304} 1305 1306build_host_gcc_core () 1307{ 1308 local SRC_DIR="$TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION" 1309 local INSTALL_DIR="$(host_gcc_install_dir)" 1310 local ARGS NEW_PATH 1311 1312 stamps_do build-binutils-$BINUTILS_VERSION-$HOST-$TARGET build_host_binutils 1313 stamps_do sysroot-gcc-$SYSTEM-$TOOLCHAIN copy_target_sysroot 1314 1315 build_host_prereqs 1316 1317 NEW_PATH=$(host_gcc_install_dir)/bin:$(host_binutils_install_dir)/bin 1318 if [ "$HOST" != "$BUILD" ]; then 1319 NEW_PATH=$(build_gcc_install_dir)/bin:$(build_binutils_install_dir)/bin 1320 fi 1321 1322 ARGS=$HOST_PREREQS_ARGS 1323 1324 case "$GCC_VERSION" in 1325 4.4.3) 1326 ARGS=$ARGS" --disable-plugin" 1327 ;; 1328 esac 1329 1330 ARGS=$ARGS" --with-gnu-as --with-gnu-ld" 1331 ARGS=$ARGS" --enable-threads --disable-libssp --disable-libmudflap --disable-libcilkrts --enable-gnu-indirect-function" 1332 ARGS=$ARGS" --disable-libstdc__-v3 --disable-sjlj-exceptions" 1333 ARGS=$ARGS" --disable-tls" 1334 ARGS=$ARGS" --disable-libquadmath --disable-libitm --disable-bootstrap" 1335 ARGS=$ARGS" --enable-languages=c,c++" 1336 ARGS=$ARGS" --disable-shared" 1337 ARGS=$ARGS" --disable-nls" 1338 ARGS=$ARGS" --disable-werror" 1339 ARGS=$ARGS" --enable-target-optspace" 1340 ARGS=$ARGS" --enable-eh-frame-hdr-for-static" 1341 # TODO: Build fails for libsanitizer which appears in 4.8. Disable for now. 1342 ARGS=$ARGS" --disable-libsanitizer" 1343 1344 case "$GCC_VERSION" in 1345 4.4.3) 1346 ARGS=$ARGS" --disable-libgomp" 1347 ;; 1348 *) 1349 case $TARGET_ARCH in 1350 arm) ARGS=$ARGS" --enable-libgomp";; 1351 x86*) ARGS=$ARGS" --enable-libgomp";; 1352 mips|mipsel) ARGS=$ARGS" --disable-libgomp";; 1353 esac 1354 ;; 1355 esac 1356 1357 # Place constructors/destructors in .init_array/.fini_array, not in 1358 # .ctors/.dtors on Android. Note that upstream Linux GLibc is now doing 1359 # the same. 1360 ARGS=$ARGS" --enable-initfini-array" 1361 1362 case $TARGET_ARCH in 1363 arm) 1364 ARGS=$ARGS" --with-arch=armv5te --with-float=soft --with-fpu=vfpv3-d16" 1365 ;; 1366 x86) 1367 case "$GCC_VERSION" in 1368 4.4.3|4.7) ARGS=$ARGS" --with-arch=i686 --with-tune=atom --with-fpmath=sse" ;; 1369 *) ARGS=$ARGS" --with-arch=i686 --with-tune=intel --with-fpmath=sse" ;; 1370 esac 1371 ;; 1372 x86_64) 1373 case "$GCC_VERSION" in 1374 4.4.3|4.7) ARGS=$ARGS" --with-arch=x86-64 --with-tune=atom --with-fpmath=sse --with-multilib-list=m32,m64,mx32" ;; 1375 *) ARGS=$ARGS" --with-arch=x86-64 --with-tune=intel --with-fpmath=sse --with-multilib-list=m32,m64,mx32" ;; 1376 esac 1377 ;; 1378 mips) 1379 # Add --disable-fixed-point to disable fixed-point support 1380 ARGS=$ARGS" --with-arch=mips32 --disable-fixed-point" 1381 ;; 1382 esac 1383 1384 dump "$(host_text)$(toolchain_text) Building gcc-core" 1385 ( 1386 setup_host_env && 1387 BUILD_DIR="$(host_build_dir_for gcc-$GCC_VERSION-$TARGET)" && 1388 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1389 cd "$BUILD_DIR" && 1390 PATH=$NEW_PATH:$PATH && 1391 run2 "$SRC_DIR"/configure \ 1392 --prefix="$INSTALL_DIR" \ 1393 --build=$BUILD \ 1394 --host=$HOST \ 1395 --target=$TARGET \ 1396 --with-sysroot="$INSTALL_DIR/sysroot" \ 1397 $HOST_PREREQS_ARGS $ARGS && 1398 run2 make -j$NUM_JOBS all-gcc && 1399 run2 make -j$NUM_INSTALL_JOBS install-gcc 1400 ) 1401 return $? 1402} 1403 1404build_target_gcc_libs () 1405{ 1406 local SRC_DIR="$TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION" 1407 local INSTALL_DIR="$(host_gcc_install_dir)" 1408 local ARGS NEW_PATH 1409 1410 stamps_do gcc-core-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_host_gcc_core 1411 1412 NEW_PATH=$(host_gcc_install_dir)/bin:$(host_binutils_install_dir)/bin 1413 1414 dump "$(host_text)$(toolchain_text) Building target libraries" 1415 ( 1416 setup_host_env && 1417 BUILD_DIR="$(host_build_dir_for gcc-$GCC_VERSION-$TARGET)" && 1418 cd "$BUILD_DIR" && 1419 PATH=$NEW_PATH:$PATH && 1420 run2 make -j$NUM_JOBS all && 1421 run2 make -j$NUM_INSTALL_JOBS install 1422 ) 1423 return $? 1424} 1425 1426copy_target_gcc_libs () 1427{ 1428 local SRC_DIR DST_DIR 1429 dump "$(host_text)$(toolchain_text) Copying target GCC libraries" 1430 1431 SRC_DIR="$(build_gcc_install_dir)/$TARGET" 1432 DST_DIR="$(host_gcc_install_dir)/$TARGET" 1433 1434 run2 copy_directory "$SRC_DIR" "$DST_DIR" 1435} 1436 1437build_host_gcc () 1438{ 1439 if [ "$SYSTEM" = "$BUILD_TAG" -a -z "$NO_TARGET_LIBS" ]; then 1440 # This is a regular-cross build, and we need to build the target GCC libraries. 1441 stamps_do gcc-all-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_target_gcc_libs 1442 else 1443 # This is a canadian-cross build, or we don't need the target GCC libraries. 1444 stamps_do gcc-core-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_host_gcc_core 1445 fi 1446} 1447 1448# $1: host system tag (e.g. linux-x86) 1449# $2: toolchain name (e.g. x86-4.4.3) 1450build_gcc () 1451{ 1452 local SYSTEM=$1 1453 local TOOLCHAIN=$2 1454 1455 # When performing canadian-cross builds, ensure we generate the 1456 # host toolchain first (even if we don't need target GCC libraries) 1457 if [ "$SYSTEM" != "$BUILD_TAG" ]; then 1458 build_gcc $BUILD_TAG $TOOLCHAIN 1459 fi 1460 1461 # We do this both in the setup and build phase to ensure we perform 1462 # as many checks as possible before launching the (long) build procedure. 1463 setup_build_for_host $SYSTEM 1464 setup_build_for_toolchain $TOOLCHAIN 1465 1466 if [ "$PHASE" = build ]; then 1467 stamps_do build-gcc-$SYSTEM-$TOOLCHAIN build_host_gcc 1468 fi 1469} 1470 1471do_relink () 1472{ 1473 log "Relink $1 --> $2" 1474 local BASENAME DIRNAME 1475 DIRNAME=$(dirname "$1") 1476 BASENAME=$(basename "$1") 1477 ( cd "$DIRNAME" && rm -f "$BASENAME" && ln -s "$2" "$BASENAME" ) 1478} 1479 1480# $1: host system tag (e.g. linux-x86) 1481# $2: toolchain name (e.g. x86-4.4.3) 1482install_gcc () 1483{ 1484 local SYSTEM=$1 1485 local TOOLCHAIN=$2 1486 local BINUTILS_DIR GCC_DIR TARGET_LIBS_DIR INSTALL_DIR PROG 1487 1488 build_gcc $SYSTEM $TOOLCHAIN 1489 1490 dump "$(host_text)$(toolchain_text) Installing to NDK." 1491 1492 BINUTILS_DIR=$(host_binutils_install_dir) 1493 GCC_DIR=$(host_gcc_install_dir) 1494 TARGET_LIBS_DIR=$(build_gcc_install_dir) 1495 INSTALL_DIR=$TOOLCHAIN_INSTALL_DIR 1496 1497 # Copy binutils binaries 1498 run2 copy_directory "$BINUTILS_DIR/bin" "$INSTALL_DIR/bin" && 1499 run2 copy_directory "$BINUTILS_DIR/$TARGET/lib" "$INSTALL_DIR/$TARGET/lib" && 1500 1501 # The following is used to copy the libbfd. See --enable-install-libbfd 1502 # which is set in build_host_binutils above. 1503 run2 copy_directory "$BINUTILS_DIR/$HOST/$TARGET/include" "$INSTALL_DIR/include" && 1504 run2 copy_directory "$BINUTILS_DIR/$HOST/$TARGET/lib" "$INSTALL_DIR/lib$(tag_to_bits $SYSTEM)" && 1505 1506 # Copy gcc core binaries 1507 run2 copy_directory "$GCC_DIR/bin" "$INSTALL_DIR/bin" && 1508 run2 copy_directory "$GCC_DIR/lib/gcc/$TARGET" "$INSTALL_DIR/lib/gcc/$TARGET" && 1509 run2 copy_directory "$GCC_DIR/libexec/gcc/$TARGET" "$INSTALL_DIR/libexec/gcc/$TARGET" && 1510 1511 # Copy target gcc libraries 1512 run2 copy_directory "$TARGET_LIBS_DIR/lib/gcc/$TARGET" "$INSTALL_DIR/lib/gcc/$TARGET" 1513 run2 copy_directory "$TARGET_LIBS_DIR/$TARGET/lib" "$INSTALL_DIR/$TARGET/lib" 1514 # Multilib compiler should have these 1515 if [ -d "$TARGET_LIBS_DIR/$TARGET/libx32" ]; then 1516 run2 copy_directory "$TARGET_LIBS_DIR/$TARGET/libx32" "$INSTALL_DIR/$TARGET/libx32" 1517 fi 1518 if [ -d "$TARGET_LIBS_DIR/$TARGET/lib32" ]; then 1519 run2 copy_directory "$TARGET_LIBS_DIR/$TARGET/lib32" "$INSTALL_DIR/$TARGET/lib32" 1520 fi 1521 if [ -d "$TARGET_LIBS_DIR/$TARGET/lib64" ]; then 1522 run2 copy_directory "$TARGET_LIBS_DIR/$TARGET/lib64" "$INSTALL_DIR/$TARGET/lib64" 1523 fi 1524 1525 # We need to generate symlinks for the binutils binaries from 1526 # $INSTALL_DIR/$TARGET/bin/$PROG to $INSTALL_DIR/bin/$TARGET-$PROG 1527 mkdir -p "$INSTALL_DIR/$TARGET/bin" && 1528 for PROG in $(cd $INSTALL_DIR/$TARGET/bin && ls * 2>/dev/null); do 1529 do_relink "$INSTALL_DIR/$TARGET/bin/$PROG" ../../bin/$TARGET-$PROG 1530 fail_panic 1531 done 1532 1533 # Also relink a few files under $INSTALL_DIR/bin/ 1534 do_relink "$INSTALL_DIR"/bin/$TARGET-c++ $TARGET-g++ && 1535 do_relink "$INSTALL_DIR"/bin/$TARGET-gcc-$GCC_VERSION $TARGET-gcc && 1536 if [ -f "$INSTALL_DIR"/bin/$TARGET-ld.gold ]; then 1537 do_relink "$INSTALL_DIR"/bin/$TARGET-ld $TARGET-ld.gold 1538 else 1539 do_relink "$INSTALL_DIR"/bin/$TARGET-ld $TARGET-ld.bfd 1540 fi 1541 fail_panic 1542 1543 # Remove unwanted $TARGET-run simulator to save about 800 KB. 1544 run2 rm -f "$INSTALL_DIR"/bin/$TARGET-run 1545 1546 # Copy the license files 1547 local TOOLCHAIN_LICENSES="$ANDROID_NDK_ROOT"/build/tools/toolchain-licenses 1548 run cp -f "$TOOLCHAIN_LICENSES"/COPYING "$TOOLCHAIN_LICENSES"/COPYING.LIB "$INSTALL_DIR" 1549} 1550 1551# $1: host system tag (e.g. linux-x86) 1552# $2: toolchain name (e.g. x86-4.4.3) 1553# $3: package directory. 1554package_gcc () 1555{ 1556 local SYSTEM=$1 1557 local TOOLCHAIN=$2 1558 local PACKAGE_DIR="$3" 1559 local PACKAGE_NAME="$TOOLCHAIN-$SYSTEM.tar.bz2" 1560 local PACKAGE_FILE="$PACKAGE_DIR/$PACKAGE_NAME" 1561 1562 setup_build_for_toolchain $TOOLCHAIN 1563 1564 dump "Packaging $PACKAGE_NAME." 1565 pack_archive "$PACKAGE_FILE" "$NDK_DIR" "$TOOLCHAIN_SUB_DIR" 1566} 1567 1568setup_build 1569 1570for PHASE in setup build; do 1571 for SYSTEM in $HOST_SYSTEMS; do 1572 setup_build_for_host $SYSTEM 1573 for TOOLCHAIN in $TOOLCHAINS; do 1574 build_gcc $SYSTEM $TOOLCHAIN 1575 done 1576 done 1577done 1578 1579for SYSTEM in $HOST_SYSTEMS; do 1580 setup_build_for_host $SYSTEM 1581 for TOOLCHAIN in $TOOLCHAINS; do 1582 install_gcc $SYSTEM $TOOLCHAIN 1583 done 1584done 1585 1586if [ "$PACKAGE_DIR" ]; then 1587 for SYSTEM in $HOST_SYSTEMS; do 1588 setup_build_for_host $SYSTEM 1589 for TOOLCHAIN in $TOOLCHAINS; do 1590 package_gcc $SYSTEM $TOOLCHAIN "$PACKAGE_DIR" 1591 done 1592 done 1593 echo "Done. See the content of $PACKAGE_DIR:" 1594 ls -l "$PACKAGE_DIR" 1595 echo "" 1596fi 1597