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.6,x86-4.6,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 # We always use the default gold linker. 189 # bfd is used for some of the older toolchains or archs not supported by gold. 190 DEFAULT_LD=gold 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.6) 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 x86_64) TARGET=x86_64-linux-android;; 977 mips|mipsel) TARGET=mipsel-linux-android; TARGET_ARCH=mips;; 978 *) panic "Unknown target toolchain architecture: $TARGET_ARCH" 979 esac 980 981 # MPC is only needed starting with GCC 4.5 982 HOST_NEED_MPC= 983 if version_is_greater_than $GCC_VERSION 4.5; then 984 HOST_NEED_MPC=true 985 fi 986 987 # TODO: We will need to place these under 988 # $NDK_DIR/prebuilts/$HOST/android-$TARGET_ARCH-gcc-$GCC_VERSION/ 989 # in a future patch. 990 TOOLCHAIN_SUB_DIR=toolchains/$TOOLCHAIN/prebuilt/$HOST_TAG 991 TOOLCHAIN_INSTALL_DIR=$NDK_DIR/$TOOLCHAIN_SUB_DIR 992 993 # These will go into CFLAGS_FOR_TARGET and others during the build 994 # of GCC target libraries. 995 if [ -z "$NO_STRIP" ]; then 996 TARGET_CFLAGS="-O2 -s" 997 else 998 TARGET_CFLAGS="-Os -g" 999 fi 1000 1001 TARGET_CXXFLAGS=$TARGET_CFLAGS 1002 TARGET_LDFLAGS="" 1003 1004 case $TARGET_ARCH in 1005 mips) 1006 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1007 # You can't really build these separately at the moment. 1008 # Add -fpic, because MIPS NDK will need to link .a into .so. 1009 TARGET_CFLAGS=$TARGET_CFLAGS" -fexceptions -fpic" 1010 TARGET_CXXFLAGS=$TARGET_CXXFLAGS" -frtti -fpic" 1011 ;; 1012 esac 1013 } 1014 1015 # This function is used to setup the build environment whenever we 1016 # generate host-specific binaries. 1017 # 1018 setup_host_env () 1019 { 1020 CC=$HOST-gcc 1021 CXX=$HOST-g++ 1022 LD=$HOST-ld 1023 AR=$HOST-ar 1024 AS=$HOST-as 1025 RANLIB=$HOST-ranlib 1026 NM=$HOST-nm 1027 STRIP=$HOST-strip 1028 STRINGS=$HOST-strings 1029 export CC CXX AS LD AR RANLIB STRIP STRINGS NM 1030 1031 CFLAGS= 1032 CXXFLAGS= 1033 LDFLAGS= 1034 if [ -z "$NO_STRIP" ]; then 1035 CFLAGS="-O2 -Os -fomit-frame-pointer -s" 1036 CXXFLAGS=$CFLAGS 1037 fi 1038 1039 # This should only used when building the target GCC libraries 1040 CFLAGS_FOR_TARGET=$TARGET_CFLAGS 1041 CXXFLAGS_FOR_TARGET=$TARGET_CXXFLAGS 1042 LDFLAGS_FOR_TARGET=$TARGET_LDFLAGS 1043 1044 export CFLAGS CXXFLAGS LDFLAGS CFLAGS_FOR_TARGET CXXFLAGS_FOR_TARGET LDFLAGS_FOR_TARGET 1045 1046 PATH=$WRAPPERS_DIR:$PATH 1047 } 1048 1049 # $1: NDK architecture name (e.g. 'arm') 1050 arch_sysroot_install_dir () 1051 { 1052 echo "$BUILD_DIR/arch-$1/sysroot" 1053 } 1054 1055 # $1: NDK architecture name (e.g. 'arm') 1056 arch_sysroot_dir () 1057 { 1058 echo "$(arch_sysroot_install_dir $1)/$(get_default_platform_sysroot_for_arch $1)" 1059 } 1060 1061 # $1: architecture name 1062 gen_minimal_sysroot () 1063 { 1064 local ARCH=$1 1065 local INSTALL_DIR=$(arch_sysroot_install_dir $ARCH) 1066 1067 dump "$(arch_text) Generating minimal sysroot." 1068 run2 $NDK_BUILDTOOLS_PATH/gen-platforms.sh --minimal --arch=$ARCH --dst-dir="$INSTALL_DIR" 1069 } 1070 1071 1072 # $1: gmp version 1073 extract_gmp_sources () 1074 { 1075 local SRC_DIR="$TOP_BUILD_DIR/temp-src" 1076 1077 dump "Extracting gmp-$1" 1078 run2 mkdir -p "$SRC_DIR" && 1079 run2 tar xjf "$TOOLCHAIN_SRC_DIR/gmp/gmp-$1.tar.bz2" -C "$SRC_DIR" 1080 } 1081 1082 # $1: gmp version 1083 build_gmp () 1084 { 1085 local SRC_DIR="$TOP_BUILD_DIR/temp-src/gmp-$1" 1086 local INSTALL_DIR="$(host_prereqs_install_dir)" 1087 local BUILD_DIR 1088 1089 stamps_do extract-gmp-$1 extract_gmp_sources $1 1090 1091 dump "$(host_text) Building gmp-$1" 1092 ( 1093 setup_host_env && 1094 BUILD_DIR="$(host_build_dir_for gmp-$GMP_VERSION)" && 1095 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1096 cd "$BUILD_DIR" && 1097 run2 "$SRC_DIR"/configure \ 1098 --prefix=$INSTALL_DIR \ 1099 --build=$BUILD \ 1100 --host=$HOST \ 1101 --disable-shared && 1102 run2 make -j$NUM_JOBS && 1103 run2 make install -j$NUM_INSTALL_JOBS 1104 ) 1105 return $? 1106 } 1107 1108 extract_mpfr_sources () 1109 { 1110 local SRC_DIR="$TOP_BUILD_DIR/temp-src" 1111 1112 dump "Extracting mpfr-$1" 1113 run2 mkdir -p "$SRC_DIR" && 1114 run2 tar xjf "$TOOLCHAIN_SRC_DIR/mpfr/mpfr-$1.tar.bz2" -C "$SRC_DIR" 1115 } 1116 1117 # $1: mpfr-version 1118 build_mpfr () 1119 { 1120 local SRC_DIR="$TOP_BUILD_DIR/temp-src/mpfr-$1" 1121 local INSTALL_DIR="$(host_prereqs_install_dir)" 1122 local BUILD_DIR 1123 1124 stamps_do extract-mpfr-$MPFR_VERSION extract_mpfr_sources $1 1125 1126 stamps_do build-gmp-$GMP_VERSION-$HOST build_gmp $GMP_VERSION 1127 1128 dump "$(host_text) Building mpfr-$1" 1129 ( 1130 setup_host_env && 1131 BUILD_DIR="$(host_build_dir_for mpfr-$MPFR_VERSION)" && 1132 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1133 cd $BUILD_DIR && 1134 run2 "$SRC_DIR"/configure \ 1135 --prefix=$INSTALL_DIR \ 1136 --build=$BUILD \ 1137 --host=$HOST \ 1138 --disable-shared \ 1139 --with-gmp=$INSTALL_DIR && 1140 run2 make -j$NUM_JOBS && 1141 run2 make -j$NUM_INSTALL_JOBS install 1142 ) 1143 return $? 1144 } 1145 1146 # $1: mpc-version 1147 extract_mpc_sources () 1148 { 1149 local SRC_DIR="$TOP_BUILD_DIR/temp-src" 1150 1151 dump "Extracting mpc-$1" 1152 run2 mkdir -p "$SRC_DIR" && 1153 run2 tar xzf "$TOOLCHAIN_SRC_DIR/mpc/mpc-$1.tar.gz" -C "$SRC_DIR" 1154 } 1155 1156 1157 # $1: mpc-version 1158 build_mpc () 1159 { 1160 local SRC_DIR="$TOP_BUILD_DIR/temp-src/mpc-$1" 1161 local INSTALL_DIR="$(host_prereqs_install_dir)" 1162 local BUILD_DIR 1163 1164 stamps_do extract-mpc-$1 extract_mpc_sources $1 1165 1166 stamps_do build-mpfr-$MPFR_VERSION-$HOST build_mpfr $MPFR_VERSION 1167 1168 dump "$(host_text) Building mpc-$1" 1169 ( 1170 setup_host_env && 1171 BUILD_DIR="$(host_build_dir_for mpc-$MPC_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 --with-mpfr=$INSTALL_DIR && 1181 run2 make -j$NUM_JOBS && 1182 run2 make -j$NUM_INSTALL_JOBS install 1183 ) 1184 return $? 1185 } 1186 1187 # Build all pre-required host libraries (gmp, mpfr, etc...) that are needed 1188 # by binutils and gcc, as static libraries that will be placed under 1189 # $HOST_BUILD_DIR/temp-install 1190 # 1191 # $1: toolchain source directory 1192 # 1193 build_host_prereqs () 1194 { 1195 local INSTALL_DIR="$(host_prereqs_install_dir)" 1196 local ARGS 1197 1198 ARGS=" --with-gmp=$INSTALL_DIR --with-mpfr=$INSTALL_DIR" 1199 1200 # Only build MPC when we need it. 1201 if [ "$HOST_NEED_MPC" ]; then 1202 ARGS=$ARGS" --with-mpc=$INSTALL_DIR" 1203 stamps_do build-mpc-$MPC_VERSION-$HOST build_mpc $MPC_VERSION 1204 else 1205 stamps_do build-mpfr-$MPFR_VERSION-$HOST build_mpfr $MPFR_VERSION 1206 fi 1207 1208 # This gets used by build_host_binutils and others. 1209 HOST_PREREQS_ARGS=$ARGS 1210 } 1211 1212 build_host_binutils () 1213 { 1214 local SRC_DIR="$TOOLCHAIN_SRC_DIR/binutils/binutils-$BINUTILS_VERSION" 1215 local INSTALL_DIR="$(host_binutils_install_dir)" 1216 local PREREQS_INSTALL_DIR="$(host_prereqs_install_dir)" 1217 local ARGS 1218 1219 build_host_prereqs 1220 1221 ARGS=" --with-gmp=$PREREQS_INSTALL_DIR --with-mpfr=$PREREQS_INSTALL_DIR" 1222 if [ "$HOST_NEED_MPC" ]; then 1223 ARGS=$ARGS" --with-mpc=$PREREQS_INSTALL_DIR" 1224 fi 1225 1226 LD_NAME=$DEFAULT_LD 1227 1228 # Enable Gold globally. It can be built for all hosts. 1229 BUILD_GOLD=true 1230 1231 # Special case, gold is not ready for mips yet. 1232 if [ "$TARGET" = "mipsel-linux-android" ]; then 1233 BUILD_GOLD= 1234 fi 1235 1236 # Another special case, gold in binutils-2.21 for arch-x86 is buggy 1237 # (i.e. when building the platform with it, the system doesn't boot) 1238 # 1239 if [ "$BINUTILS_VERSION" = "2.21" -a "$TARGET" = "i686-linux-android" ]; then 1240 USE_LD_DEFAULT=true 1241 BUILD_GOLD= 1242 fi 1243 1244 # Another special case, for arch-x86_64 gold supports x32 starting from 2.23 1245 # 1246 if [ "$TARGET" = "x86_64-linux-android" ]; then 1247 if ! version_is_greater_than $BINUTILS_VERSION 2.23; then 1248 USE_LD_DEFAULT=true 1249 BUILD_GOLD= 1250 fi 1251 fi 1252 1253 # Another special case. Not or 2.19, it wasn't ready 1254 if [ "$BINUTILS_VERSION" = "2.19" ]; then 1255 BUILD_GOLD= 1256 fi 1257 1258 if [ "$DEFAULT_LD" = "gold" -a -z "$BUILD_GOLD" ]; then 1259 dump "$(host_text)$(target_text): Cannot build Gold for this toolchain!" 1260 BUILD_GOLD= 1261 fi 1262 1263 # Ok, if the user *really* wants it, we're going to build Gold anyway. 1264 # There are no guarantees about the correctness of the resulting binary. 1265 # --default-ld still determines the default linker to use by the toolchain. 1266 # 1267 if [ "$FORCE_GOLD_BUILD" -a -z "$BUILD_GOLD" ]; then 1268 dump "$(host_text)$(target_text): Warning: forcing build of potentially buggy Gold linker!" 1269 BUILD_GOLD=true 1270 fi 1271 1272 # The BFD linker is always built, but to build Gold, we need a specific 1273 # option for the binutils configure script. Note that its format has 1274 # changed during development. 1275 export host_configargs= 1276 if [ "$BUILD_GOLD" ]; then 1277 # The syntax of the --enable-gold option has changed. 1278 if version_is_greater_than $BINUTILS_VERSION 2.20; then 1279 if [ "$DEFAULT_LD" = "bfd" ]; then 1280 ARGS=$ARGS" --enable-gold --enable-ld=default" 1281 else 1282 ARGS=$ARGS" --enable-gold=default --enable-ld" 1283 fi 1284 else 1285 if [ "$DEFAULT_LD" = "bfd" ]; then 1286 ARGS=$ARGS" --enable-gold=both" 1287 else 1288 ARGS=$ARGS" --enable-gold=both/gold" 1289 fi 1290 fi 1291 # This ARG needs quoting when passed to run2. 1292 GOLD_LDFLAGS_ARG= 1293 if [ "$HOST_OS" = 'windows' ]; then 1294 # gold may have runtime dependency on libgcc_sjlj_1.dll and 1295 # libstdc++-6.dll when built by newer versions of mingw. 1296 # Link them statically to avoid that. 1297 if version_is_greater_than $BINUTILS_VERSION 2.22; then 1298 export host_configargs="--with-gold-ldflags='-static-libgcc -static-libstdc++'" 1299 elif version_is_greater_than $BINUTILS_VERSION 2.21; then 1300 GOLD_LDFLAGS_ARG="--with-gold-ldflags=-static-libgcc -static-libstdc++" 1301 else 1302 export LDFLAGS=$LDFLAGS" -static-libgcc -static-libstdc++" 1303 fi 1304 fi 1305 fi 1306 1307 # This is used to install libbfd which is later used to compile 1308 # oprofile for the platform. This is not technically required for 1309 # the NDK, but allows us to use the same toolchain for the platform 1310 # build. TODO: Probably want to move this step to its own script 1311 # like build-host-libbfd.sh in the future. 1312 ARGS=$ARGS" --enable-install-libbfd" 1313 1314 # Enable plugins support for binutils-2.21+ 1315 # This is common feature for binutils and gcc 1316 case "$BINUTILS_VERSION" in 1317 2.19) 1318 # Add nothing 1319 ;; 1320 *) 1321 ARGS=$ARGS" --enable-plugins" 1322 ;; 1323 esac 1324 1325 dump "$(host_text)$(target_text) Building binutils-$BINUTILS_VERSION" 1326 ( 1327 setup_host_env && 1328 BUILD_DIR="$(host_build_dir_for binutils-$BINUTILS_VERSION-$TARGET)" && 1329 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1330 cd "$BUILD_DIR" && 1331 run2 "$SRC_DIR"/configure \ 1332 --prefix="$INSTALL_DIR" \ 1333 --disable-shared \ 1334 --disable-werror \ 1335 --disable-nls \ 1336 --build=$BUILD \ 1337 --host=$HOST \ 1338 --target=$TARGET \ 1339 --with-sysroot="$INSTALL_DIR/sysroot" \ 1340 $ARGS && 1341 run2 make -j$NUM_JOBS && 1342 run2 make -j$NUM_INSTALL_JOBS install && 1343 # We need to take care of something weird, binutils-2.21 on mips 1344 # doesn't seem to build gold, and the Makefile script forgets to 1345 # copy it to $INSTALL/bin/mipsel-linux-android-ld. Take care of this 1346 # here with a symlink, which will be enough for now. 1347 if [ ! -f "$INSTALL_DIR/bin/$TARGET-ld" ]; then 1348 run2 ln -s "$TARGET-ld.bfd" "$INSTALL_DIR/bin/$TARGET-ld" 1349 fi 1350 ) 1351 return $? 1352 } 1353 1354 copy_target_sysroot () 1355 { 1356 local SRC_SYSROOT=$(arch_sysroot_dir $TARGET_ARCH) 1357 local SYSROOT=$(host_sysroot) 1358 1359 # We need the arch-specific minimal sysroot 1360 stamps_do sysroot-arch-$TARGET_ARCH gen_minimal_sysroot $TARGET_ARCH 1361 1362 dump "$(host_text)$(toolchain_text) Copying $TARGET_ARCH sysroot" 1363 run2 rm -rf "$SYSROOT" && 1364 run2 copy_directory "$SRC_SYSROOT" "$SYSROOT" 1365 } 1366 1367 build_host_gcc_core () 1368 { 1369 local SRC_DIR="$TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION" 1370 local INSTALL_DIR="$(host_gcc_install_dir)" 1371 local ARGS NEW_PATH 1372 1373 stamps_do build-binutils-$BINUTILS_VERSION-$HOST-$TARGET build_host_binutils 1374 stamps_do sysroot-gcc-$SYSTEM-$TOOLCHAIN copy_target_sysroot 1375 1376 build_host_prereqs 1377 1378 NEW_PATH=$(host_gcc_install_dir)/bin:$(host_binutils_install_dir)/bin 1379 if [ "$HOST" != "$BUILD" ]; then 1380 NEW_PATH=$(build_gcc_install_dir)/bin:$(build_binutils_install_dir)/bin 1381 fi 1382 1383 ARGS=$HOST_PREREQS_ARGS 1384 1385 case "$GCC_VERSION" in 1386 4.4.3) 1387 ARGS=$ARGS" --disable-plugin" 1388 ;; 1389 esac 1390 1391 ARGS=$ARGS" --with-gnu-as --with-gnu-ld" 1392 ARGS=$ARGS" --enable-threads --disable-libssp --disable-libmudflap" 1393 ARGS=$ARGS" --disable-libstdc__-v3 --disable-sjlj-exceptions" 1394 ARGS=$ARGS" --disable-tls" 1395 ARGS=$ARGS" --disable-libquadmath --disable-libitm --disable-bootstrap" 1396 ARGS=$ARGS" --enable-languages=c,c++" 1397 ARGS=$ARGS" --disable-shared" 1398 ARGS=$ARGS" --disable-nls" 1399 ARGS=$ARGS" --disable-werror" 1400 ARGS=$ARGS" --enable-target-optspace" 1401 ARGS=$ARGS" --enable-eh-frame-hdr-for-static" 1402 # TODO: Build fails for libsanitizer which appears in 4.8. Disable for now. 1403 ARGS=$ARGS" --disable-libsanitizer" 1404 1405 case "$GCC_VERSION" in 1406 4.4.3) 1407 ARGS=$ARGS" --disable-libgomp" 1408 ;; 1409 *) 1410 case $TARGET_ARCH in 1411 arm) ARGS=$ARGS" --enable-libgomp";; 1412 x86*) ARGS=$ARGS" --enable-libgomp";; 1413 mips|mipsel) ARGS=$ARGS" --disable-libgomp";; 1414 esac 1415 ;; 1416 esac 1417 1418 # Place constructors/destructors in .init_array/.fini_array, not in 1419 # .ctors/.dtors on Android. Note that upstream Linux GLibc is now doing 1420 # the same. 1421 ARGS=$ARGS" --enable-initfini-array" 1422 1423 case $TARGET_ARCH in 1424 arm) 1425 ARGS=$ARGS" --with-arch=armv5te --with-float=soft --with-fpu=vfpv3-d16" 1426 ;; 1427 x86) 1428 ARGS=$ARGS" --with-arch=i686 --with-tune=atom --with-fpmath=sse" 1429 ;; 1430 x86_64) 1431 ARGS=$ARGS" --with-arch=x86-64 --with-tune=atom --with-fpmath=sse --with-multilib-list=m32,m64,mx32" 1432 ;; 1433 mips) 1434 # Add --disable-fixed-point to disable fixed-point support 1435 # Add --disable-threads for eh_frame handling in a single thread 1436 ARGS=$ARGS" --with-arch=mips32 --disable-fixed-point --disable-threads" 1437 ;; 1438 esac 1439 1440 dump "$(host_text)$(toolchain_text) Building gcc-core" 1441 ( 1442 setup_host_env && 1443 BUILD_DIR="$(host_build_dir_for gcc-$GCC_VERSION-$TARGET)" && 1444 run2 mkdir -p "$BUILD_DIR" && run2 rm -rf "$BUILD_DIR"/* && 1445 cd "$BUILD_DIR" && 1446 PATH=$NEW_PATH:$PATH && 1447 run2 "$SRC_DIR"/configure \ 1448 --prefix="$INSTALL_DIR" \ 1449 --build=$BUILD \ 1450 --host=$HOST \ 1451 --target=$TARGET \ 1452 --with-sysroot="$INSTALL_DIR/sysroot" \ 1453 $HOST_PREREQS_ARGS $ARGS && 1454 run2 make -j$NUM_JOBS all-gcc && 1455 run2 make -j$NUM_INSTALL_JOBS install-gcc 1456 ) 1457 return $? 1458 } 1459 1460 build_target_gcc_libs () 1461 { 1462 local SRC_DIR="$TOOLCHAIN_SRC_DIR/gcc/gcc-$GCC_VERSION" 1463 local INSTALL_DIR="$(host_gcc_install_dir)" 1464 local ARGS NEW_PATH 1465 1466 stamps_do gcc-core-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_host_gcc_core 1467 1468 NEW_PATH=$(host_gcc_install_dir)/bin:$(host_binutils_install_dir)/bin 1469 1470 dump "$(host_text)$(toolchain_text) Building target libraries" 1471 ( 1472 setup_host_env && 1473 BUILD_DIR="$(host_build_dir_for gcc-$GCC_VERSION-$TARGET)" && 1474 cd "$BUILD_DIR" && 1475 PATH=$NEW_PATH:$PATH && 1476 run2 make -j$NUM_JOBS all && 1477 run2 make -j$NUM_INSTALL_JOBS install 1478 ) 1479 return $? 1480 } 1481 1482 copy_target_gcc_libs () 1483 { 1484 local SRC_DIR DST_DIR 1485 dump "$(host_text)$(toolchain_text) Copying target GCC libraries" 1486 1487 SRC_DIR="$(build_gcc_install_dir)/$TARGET" 1488 DST_DIR="$(host_gcc_install_dir)/$TARGET" 1489 1490 run2 copy_directory "$SRC_DIR" "$DST_DIR" 1491 } 1492 1493 build_host_gcc () 1494 { 1495 if [ "$SYSTEM" = "$BUILD_TAG" -a -z "$NO_TARGET_LIBS" ]; then 1496 # This is a regular-cross build, and we need to build the target GCC libraries. 1497 stamps_do gcc-all-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_target_gcc_libs 1498 else 1499 # This is a canadian-cross build, or we don't need the target GCC libraries. 1500 stamps_do gcc-core-$GCC_VERSION-$SYSTEM-$TOOLCHAIN build_host_gcc_core 1501 fi 1502 } 1503 1504 # $1: host system tag (e.g. linux-x86) 1505 # $2: toolchain name (e.g. x86-4.4.3) 1506 build_gcc () 1507 { 1508 local SYSTEM=$1 1509 local TOOLCHAIN=$2 1510 1511 # When performing canadian-cross builds, ensure we generate the 1512 # host toolchain first (even if we don't need target GCC libraries) 1513 if [ "$SYSTEM" != "$BUILD_TAG" ]; then 1514 build_gcc $BUILD_TAG $TOOLCHAIN 1515 fi 1516 1517 # We do this both in the setup and build phase to ensure we perform 1518 # as many checks as possible before launching the (long) build procedure. 1519 setup_build_for_host $SYSTEM 1520 setup_build_for_toolchain $TOOLCHAIN 1521 1522 if [ "$PHASE" = build ]; then 1523 stamps_do build-gcc-$SYSTEM-$TOOLCHAIN build_host_gcc 1524 fi 1525 } 1526 1527 do_relink () 1528 { 1529 log "Relink $1 --> $2" 1530 local BASENAME DIRNAME 1531 DIRNAME=$(dirname "$1") 1532 BASENAME=$(basename "$1") 1533 ( cd "$DIRNAME" && rm -f "$BASENAME" && ln -s "$2" "$BASENAME" ) 1534 } 1535 1536 # $1: host system tag (e.g. linux-x86) 1537 # $2: toolchain name (e.g. x86-4.4.3) 1538 install_gcc () 1539 { 1540 local SYSTEM=$1 1541 local TOOLCHAIN=$2 1542 local BINUTILS_DIR GCC_DIR TARGET_LIBS_DIR INSTALL_DIR PROG 1543 1544 build_gcc $SYSTEM $TOOLCHAIN 1545 1546 dump "$(host_text)$(toolchain_text) Installing to NDK." 1547 1548 BINUTILS_DIR=$(host_binutils_install_dir) 1549 GCC_DIR=$(host_gcc_install_dir) 1550 TARGET_LIBS_DIR=$(build_gcc_install_dir) 1551 INSTALL_DIR=$TOOLCHAIN_INSTALL_DIR 1552 1553 # Copy binutils binaries 1554 run2 copy_directory "$BINUTILS_DIR/bin" "$INSTALL_DIR/bin" && 1555 run2 copy_directory "$BINUTILS_DIR/$TARGET/lib" "$INSTALL_DIR/$TARGET/lib" && 1556 1557 # The following is used to copy the libbfd. See --enable-install-libbfd 1558 # which is set in build_host_binutils above. 1559 run2 copy_directory "$BINUTILS_DIR/$HOST/$TARGET/include" "$INSTALL_DIR/include" && 1560 run2 copy_directory "$BINUTILS_DIR/$HOST/$TARGET/lib" "$INSTALL_DIR/lib$(tag_to_bits $SYSTEM)" && 1561 1562 # Copy gcc core binaries 1563 run2 copy_directory "$GCC_DIR/bin" "$INSTALL_DIR/bin" && 1564 run2 copy_directory "$GCC_DIR/lib/gcc/$TARGET" "$INSTALL_DIR/lib/gcc/$TARGET" && 1565 run2 copy_directory "$GCC_DIR/libexec/gcc/$TARGET" "$INSTALL_DIR/libexec/gcc/$TARGET" && 1566 1567 # Copy target gcc libraries 1568 run2 copy_directory "$TARGET_LIBS_DIR/lib/gcc/$TARGET" "$INSTALL_DIR/lib/gcc/$TARGET" 1569 run2 copy_directory "$TARGET_LIBS_DIR/$TARGET/lib" "$INSTALL_DIR/$TARGET/lib" 1570 # Multilib compiler should have these 1571 if [ -d "$TARGET_LIBS_DIR/$TARGET/libx32" ]; then 1572 run2 copy_directory "$TARGET_LIBS_DIR/$TARGET/libx32" "$INSTALL_DIR/$TARGET/libx32" 1573 fi 1574 if [ -d "$TARGET_LIBS_DIR/$TARGET/lib64" ]; then 1575 run2 copy_directory "$TARGET_LIBS_DIR/$TARGET/lib64" "$INSTALL_DIR/$TARGET/lib64" 1576 fi 1577 1578 # We need to generate symlinks for the binutils binaries from 1579 # $INSTALL_DIR/$TARGET/bin/$PROG to $INSTALL_DIR/bin/$TARGET-$PROG 1580 mkdir -p "$INSTALL_DIR/$TARGET/bin" && 1581 for PROG in $(cd $INSTALL_DIR/$TARGET/bin && ls * 2>/dev/null); do 1582 do_relink "$INSTALL_DIR/$TARGET/bin/$PROG" ../../bin/$TARGET-$PROG 1583 fail_panic 1584 done 1585 1586 # Also relink a few files under $INSTALL_DIR/bin/ 1587 do_relink "$INSTALL_DIR"/bin/$TARGET-c++ $TARGET-g++ && 1588 do_relink "$INSTALL_DIR"/bin/$TARGET-gcc-$GCC_VERSION $TARGET-gcc && 1589 if [ -f "$INSTALL_DIR"/bin/$TARGET-ld.gold ]; then 1590 do_relink "$INSTALL_DIR"/bin/$TARGET-ld $TARGET-ld.gold 1591 else 1592 do_relink "$INSTALL_DIR"/bin/$TARGET-ld $TARGET-ld.bfd 1593 fi 1594 fail_panic 1595 1596 # Remove unwanted $TARGET-run simulator to save about 800 KB. 1597 run2 rm -f "$INSTALL_DIR"/bin/$TARGET-run 1598 1599 # Copy the license files 1600 local TOOLCHAIN_LICENSES="$ANDROID_NDK_ROOT"/build/tools/toolchain-licenses 1601 run cp -f "$TOOLCHAIN_LICENSES"/COPYING "$TOOLCHAIN_LICENSES"/COPYING.LIB "$INSTALL_DIR" 1602 } 1603 1604 # $1: host system tag (e.g. linux-x86) 1605 # $2: toolchain name (e.g. x86-4.4.3) 1606 # $3: package directory. 1607 package_gcc () 1608 { 1609 local SYSTEM=$1 1610 local TOOLCHAIN=$2 1611 local PACKAGE_DIR="$3" 1612 local PACKAGE_NAME="$TOOLCHAIN-$SYSTEM.tar.bz2" 1613 local PACKAGE_FILE="$PACKAGE_DIR/$PACKAGE_NAME" 1614 1615 setup_build_for_toolchain $TOOLCHAIN 1616 1617 dump "Packaging $PACKAGE_NAME." 1618 pack_archive "$PACKAGE_FILE" "$NDK_DIR" "$TOOLCHAIN_SUB_DIR" 1619 } 1620 1621 setup_build 1622 1623 for PHASE in setup build; do 1624 for SYSTEM in $HOST_SYSTEMS; do 1625 setup_build_for_host $SYSTEM 1626 for TOOLCHAIN in $TOOLCHAINS; do 1627 build_gcc $SYSTEM $TOOLCHAIN 1628 done 1629 done 1630 done 1631 1632 for SYSTEM in $HOST_SYSTEMS; do 1633 setup_build_for_host $SYSTEM 1634 for TOOLCHAIN in $TOOLCHAINS; do 1635 install_gcc $SYSTEM $TOOLCHAIN 1636 done 1637 done 1638 1639 if [ "$PACKAGE_DIR" ]; then 1640 for SYSTEM in $HOST_SYSTEMS; do 1641 setup_build_for_host $SYSTEM 1642 for TOOLCHAIN in $TOOLCHAINS; do 1643 package_gcc $SYSTEM $TOOLCHAIN "$PACKAGE_DIR" 1644 done 1645 done 1646 echo "Done. See the content of $PACKAGE_DIR:" 1647 ls -l "$PACKAGE_DIR" 1648 echo "" 1649 fi 1650