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