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