1 # Common functions for all prebuilt-related scripts 2 # This is included/sourced by other scripts 3 # 4 5 # ensure stable sort order 6 export LC_ALL=C 7 8 # NDK_BUILDTOOLS_PATH should point to the directory containing 9 # this script. If it is not defined, assume that this is one of 10 # the scripts in the same directory that sourced this file. 11 # 12 if [ -z "$NDK_BUILDTOOLS_PATH" ]; then 13 NDK_BUILDTOOLS_PATH=$(dirname $0) 14 if [ ! -f "$NDK_BUILDTOOLS_PATH/prebuilt-common.sh" ]; then 15 echo "INTERNAL ERROR: Please define NDK_BUILDTOOLS_PATH to point to $$NDK/build/tools" 16 exit 1 17 fi 18 fi 19 20 NDK_BUILDTOOLS_ABSPATH=$(cd $NDK_BUILDTOOLS_PATH && pwd) 21 22 . $NDK_BUILDTOOLS_PATH/../core/ndk-common.sh 23 . $NDK_BUILDTOOLS_PATH/dev-defaults.sh 24 25 #==================================================== 26 # 27 # UTILITY FUNCTIONS 28 # 29 #==================================================== 30 31 # Return the maximum length of a series of strings 32 # 33 # Usage: len=`max_length <string1> <string2> ...` 34 # 35 max_length () 36 { 37 echo "$@" | tr ' ' '\n' | awk 'BEGIN {max=0} {len=length($1); if (len > max) max=len} END {print max}' 38 } 39 40 # Translate dashes to underscores 41 # Usage: str=`dashes_to_underscores <values>` 42 dashes_to_underscores () 43 { 44 echo $@ | tr '-' '_' 45 } 46 47 # Translate underscores to dashes 48 # Usage: str=`underscores_to_dashes <values>` 49 underscores_to_dashes () 50 { 51 echo $@ | tr '_' '-' 52 } 53 54 # Translate commas to spaces 55 # Usage: str=`commas_to_spaces <list>` 56 commas_to_spaces () 57 { 58 echo $@ | tr ',' ' ' 59 } 60 61 # Translate spaces to commas 62 # Usage: list=`spaces_to_commas <string>` 63 spaces_to_commas () 64 { 65 echo $@ | tr ' ' ',' 66 } 67 68 # Remove trailing path of a path 69 # $1: path 70 remove_trailing_slash () { 71 echo ${1%%/} 72 } 73 74 # Reverse a file path directory 75 # foo -> . 76 # foo/bar -> .. 77 # foo/bar/zoo -> ../.. 78 reverse_path () 79 { 80 local path cur item 81 path=${1%%/} # remove trailing slash 82 cur="." 83 if [ "$path" != "." ] ; then 84 for item in $(echo "$path" | tr '/' ' '); do 85 cur="../$cur" 86 done 87 fi 88 echo ${cur%%/.} 89 } 90 91 # test_reverse_path () 92 # { 93 # rr=`reverse_path $1` 94 # if [ "$rr" != "$2" ] ; then 95 # echo "ERROR: reverse_path '$1' -> '$rr' (expected '$2')" 96 # fi 97 # } 98 # 99 # test_reverse_path . . 100 # test_reverse_path ./ . 101 # test_reverse_path foo .. 102 # test_reverse_path foo/ .. 103 # test_reverse_path foo/bar ../.. 104 # test_reverse_path foo/bar/ ../.. 105 # test_reverse_path foo/bar/zoo ../../.. 106 # test_reverse_path foo/bar/zoo/ ../../.. 107 108 # Sort a space-separated list and remove duplicates 109 # $1+: slist 110 # Output: new slist 111 sort_uniq () 112 { 113 local RET 114 RET=$(echo $@ | tr ' ' '\n' | sort -u) 115 echo $RET 116 } 117 118 # Return the list of all regular files under a given directory 119 # $1: Directory path 120 # Output: list of files, relative to $1 121 list_files_under () 122 { 123 if [ -d "$1" ]; then 124 (cd $1 && find . -type f | sed -e "s!./!!" | sort -u) 125 else 126 echo "" 127 fi 128 } 129 130 #==================================================== 131 # 132 # OPTION PROCESSING 133 # 134 #==================================================== 135 136 # We recognize the following option formats: 137 # 138 # -f 139 # --flag 140 # 141 # -s<value> 142 # --setting=<value> 143 # 144 145 # NOTE: We translate '-' into '_' when storing the options in global variables 146 # 147 148 OPTIONS="" 149 OPTION_FLAGS="" 150 OPTION_SETTINGS="" 151 152 # Set a given option attribute 153 # $1: option name 154 # $2: option attribute 155 # $3: attribute value 156 # 157 option_set_attr () 158 { 159 eval OPTIONS_$1_$2=\"$3\" 160 } 161 162 # Get a given option attribute 163 # $1: option name 164 # $2: option attribute 165 # 166 option_get_attr () 167 { 168 echo `var_value OPTIONS_$1_$2` 169 } 170 171 # Register a new option 172 # $1: option 173 # $2: small abstract for the option 174 # $3: optional. default value 175 # 176 register_option_internal () 177 { 178 optlabel= 179 optname= 180 optvalue= 181 opttype= 182 while [ -n "1" ] ; do 183 # Check for something like --setting=<value> 184 echo "$1" | grep -q -E -e '^--[^=]+=<.+>$' 185 if [ $? = 0 ] ; then 186 optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'` 187 optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'` 188 opttype="long_setting" 189 break 190 fi 191 192 # Check for something like --flag 193 echo "$1" | grep -q -E -e '^--[^=]+$' 194 if [ $? = 0 ] ; then 195 optlabel="$1" 196 opttype="long_flag" 197 break 198 fi 199 200 # Check for something like -f<value> 201 echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$' 202 if [ $? = 0 ] ; then 203 optlabel=`expr -- "$1" : '\(-.\).*'` 204 optvalue=`expr -- "$1" : '-.\(<.+>\)'` 205 opttype="short_setting" 206 break 207 fi 208 209 # Check for something like -f 210 echo "$1" | grep -q -E -e '^-.$' 211 if [ $? = 0 ] ; then 212 optlabel="$1" 213 opttype="short_flag" 214 break 215 fi 216 217 echo "ERROR: Invalid option format: $1" 218 echo " Check register_option call" 219 exit 1 220 done 221 222 log "new option: type='$opttype' name='$optlabel' value='$optvalue'" 223 224 optname=`dashes_to_underscores $optlabel` 225 OPTIONS="$OPTIONS $optname" 226 OPTIONS_TEXT="$OPTIONS_TEXT $1" 227 option_set_attr $optname label "$optlabel" 228 option_set_attr $optname otype "$opttype" 229 option_set_attr $optname value "$optvalue" 230 option_set_attr $optname text "$1" 231 option_set_attr $optname abstract "$2" 232 option_set_attr $optname default "$3" 233 } 234 235 # Register a new option with a function callback. 236 # 237 # $1: option 238 # $2: name of function that will be called when the option is parsed 239 # $3: small abstract for the option 240 # $4: optional. default value 241 # 242 register_option () 243 { 244 local optname optvalue opttype optlabel 245 register_option_internal "$1" "$3" "$4" 246 option_set_attr $optname funcname "$2" 247 } 248 249 # Register a new option with a variable store 250 # 251 # $1: option 252 # $2: name of variable that will be set by this option 253 # $3: small abstract for the option 254 # 255 # NOTE: The current value of $2 is used as the default 256 # 257 register_var_option () 258 { 259 local optname optvalue opttype optlabel 260 register_option_internal "$1" "$3" "`var_value $2`" 261 option_set_attr $optname varname "$2" 262 } 263 264 265 MINGW=no 266 do_mingw_option () { MINGW=yes; } 267 268 register_mingw_option () 269 { 270 if [ "$HOST_OS" = "linux" ] ; then 271 register_option "--mingw" do_mingw_option "Generate windows binaries on Linux." 272 fi 273 } 274 275 TRY64=no 276 do_try64_option () { TRY64=yes; } 277 278 register_try64_option () 279 { 280 register_option "--try-64" do_try64_option "Generate 64-bit binaries." 281 } 282 283 284 register_jobs_option () 285 { 286 NUM_JOBS=$BUILD_NUM_CPUS 287 register_var_option "-j<number>" NUM_JOBS "Use <number> parallel build jobs" 288 } 289 290 # Print the help, including a list of registered options for this program 291 # Note: Assumes PROGRAM_PARAMETERS and PROGRAM_DESCRIPTION exist and 292 # correspond to the parameters list and the program description 293 # 294 print_help () 295 { 296 local opt text abstract default 297 298 echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS" 299 echo "" 300 if [ -n "$PROGRAM_DESCRIPTION" ] ; then 301 echo "$PROGRAM_DESCRIPTION" 302 echo "" 303 fi 304 echo "Valid options (defaults are in brackets):" 305 echo "" 306 307 maxw=`max_length "$OPTIONS_TEXT"` 308 AWK_SCRIPT=`echo "{ printf \"%-${maxw}s\", \\$1 }"` 309 for opt in $OPTIONS; do 310 text=`option_get_attr $opt text | awk "$AWK_SCRIPT"` 311 abstract=`option_get_attr $opt abstract` 312 default=`option_get_attr $opt default` 313 if [ -n "$default" ] ; then 314 echo " $text $abstract [$default]" 315 else 316 echo " $text $abstract" 317 fi 318 done 319 echo "" 320 } 321 322 option_panic_no_args () 323 { 324 echo "ERROR: Option '$1' does not take arguments. See --help for usage." 325 exit 1 326 } 327 328 option_panic_missing_arg () 329 { 330 echo "ERROR: Option '$1' requires an argument. See --help for usage." 331 exit 1 332 } 333 334 extract_parameters () 335 { 336 local opt optname otype value name fin funcname 337 PARAMETERS="" 338 while [ -n "$1" ] ; do 339 # If the parameter does not begin with a dash 340 # it is not an option. 341 param=`expr -- "$1" : '^\([^\-].*\)$'` 342 if [ -n "$param" ] ; then 343 if [ -z "$PARAMETERS" ] ; then 344 PARAMETERS="$1" 345 else 346 PARAMETERS="$PARAMETERS $1" 347 fi 348 shift 349 continue 350 fi 351 352 while [ -n "1" ] ; do 353 # Try to match a long setting, i.e. --option=value 354 opt=`expr -- "$1" : '^\(--[^=]*\)=.*$'` 355 if [ -n "$opt" ] ; then 356 otype="long_setting" 357 value=`expr -- "$1" : '^--[^=]*=\(.*\)$'` 358 break 359 fi 360 361 # Try to match a long flag, i.e. --option 362 opt=`expr -- "$1" : '^\(--.*\)$'` 363 if [ -n "$opt" ] ; then 364 otype="long_flag" 365 value="yes" 366 break 367 fi 368 369 # Try to match a short setting, i.e. -o<value> 370 opt=`expr -- "$1" : '^\(-[A-Za-z0-9]\)..*$'` 371 if [ -n "$opt" ] ; then 372 otype="short_setting" 373 value=`expr -- "$1" : '^-.\(.*\)$'` 374 break 375 fi 376 377 # Try to match a short flag, i.e. -o 378 opt=`expr -- "$1" : '^\(-.\)$'` 379 if [ -n "$opt" ] ; then 380 otype="short_flag" 381 value="yes" 382 break 383 fi 384 385 echo "ERROR: Unknown option '$1'. Use --help for list of valid values." 386 exit 1 387 done 388 389 #echo "Found opt='$opt' otype='$otype' value='$value'" 390 391 name=`dashes_to_underscores $opt` 392 found=0 393 for xopt in $OPTIONS; do 394 if [ "$name" != "$xopt" ] ; then 395 continue 396 fi 397 # Check that the type is correct here 398 # 399 # This also allows us to handle -o <value> as -o<value> 400 # 401 xotype=`option_get_attr $name otype` 402 if [ "$otype" != "$xotype" ] ; then 403 case "$xotype" in 404 "short_flag") 405 option_panic_no_args $opt 406 ;; 407 "short_setting") 408 if [ -z "$2" ] ; then 409 option_panic_missing_arg $opt 410 fi 411 value="$2" 412 shift 413 ;; 414 "long_flag") 415 option_panic_no_args $opt 416 ;; 417 "long_setting") 418 option_panic_missing_arg $opt 419 ;; 420 esac 421 fi 422 found=1 423 break 424 break 425 done 426 if [ "$found" = "0" ] ; then 427 echo "ERROR: Unknown option '$opt'. See --help for usage." 428 exit 1 429 fi 430 # Set variable or launch option-specific function. 431 varname=`option_get_attr $name varname` 432 if [ -n "$varname" ] ; then 433 eval ${varname}=\"$value\" 434 else 435 eval `option_get_attr $name funcname` \"$value\" 436 fi 437 shift 438 done 439 } 440 441 do_option_help () 442 { 443 print_help 444 exit 0 445 } 446 447 VERBOSE=no 448 VERBOSE2=no 449 do_option_verbose () 450 { 451 if [ $VERBOSE = "yes" ] ; then 452 VERBOSE2=yes 453 else 454 VERBOSE=yes 455 fi 456 } 457 458 register_option "--help" do_option_help "Print this help." 459 register_option "--verbose" do_option_verbose "Enable verbose mode." 460 461 #==================================================== 462 # 463 # TOOLCHAIN AND ABI PROCESSING 464 # 465 #==================================================== 466 467 # Determine optional variable value 468 # $1: final variable name 469 # $2: option variable name 470 # $3: small description for the option 471 fix_option () 472 { 473 if [ -n "$2" ] ; then 474 eval $1="$2" 475 log "Using specific $3: $2" 476 else 477 log "Using default $3: `var_value $1`" 478 fi 479 } 480 481 482 # If SYSROOT is empty, check that $1/$2 contains a sysroot 483 # and set the variable to it. 484 # 485 # $1: sysroot path 486 # $2: platform/arch suffix 487 check_sysroot () 488 { 489 if [ -z "$SYSROOT" ] ; then 490 log "Probing directory for sysroot: $1/$2" 491 if [ -d $1/$2 ] ; then 492 SYSROOT=$1/$2 493 fi 494 fi 495 } 496 497 # Determine sysroot 498 # $1: Option value (or empty) 499 # 500 fix_sysroot () 501 { 502 if [ -n "$1" ] ; then 503 eval SYSROOT="$1" 504 log "Using specified sysroot: $1" 505 else 506 SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH 507 SYSROOT= 508 check_sysroot $NDK_DIR/platforms $SYSROOT_SUFFIX 509 check_sysroot $ANDROID_NDK_ROOT/platforms $SYSROOT_SUFFIX 510 check_sysroot `dirname $ANDROID_NDK_ROOT`/development/ndk/platforms $SYSROOT_SUFFIX 511 512 if [ -z "$SYSROOT" ] ; then 513 echo "ERROR: Could not find NDK sysroot path for $SYSROOT_SUFFIX." 514 echo " Use --sysroot=<path> to specify one." 515 exit 1 516 fi 517 fi 518 519 if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then 520 echo "ERROR: Invalid sysroot path: $SYSROOT" 521 echo " Use --sysroot=<path> to indicate a valid one." 522 exit 1 523 fi 524 } 525 526 # Use the check for the availability of a compatibility SDK in Darwin 527 # this can be used to generate binaries compatible with either Tiger or 528 # Leopard. 529 # 530 # $1: SDK root path 531 # $2: MacOS X minimum version (e.g. 10.4) 532 check_darwin_sdk () 533 { 534 if [ -d "$1" ] ; then 535 HOST_CFLAGS="-isysroot $1 -mmacosx-version-min=$2 -DMAXOSX_DEPLOYEMENT_TARGET=$2" 536 HOST_LDFLAGS="-Wl,-syslibroot,$sdk -mmacosx-version-min=$2" 537 return 0 # success 538 fi 539 return 1 540 } 541 542 543 handle_mingw () 544 { 545 # Now handle the --mingw flag 546 if [ "$MINGW" = "yes" ] ; then 547 case $HOST_TAG in 548 linux-*) 549 ;; 550 *) 551 echo "ERROR: Can only enable mingw on Linux platforms !" 552 exit 1 553 ;; 554 esac 555 if [ "$TRY64" = "yes" ]; then 556 ABI_CONFIGURE_HOST=amd64-mingw32msvc 557 else 558 ABI_CONFIGURE_HOST=i586-mingw32msvc 559 fi 560 HOST_OS=windows 561 HOST_TAG=windows 562 HOST_EXE=.exe 563 fi 564 } 565 566 handle_host () 567 { 568 # For now, we only support building 32-bit binaries anyway 569 if [ "$TRY64" != "yes" ]; then 570 force_32bit_binaries # to modify HOST_TAG and others 571 HOST_BITS=32 572 fi 573 handle_mingw 574 } 575 576 setup_ccache () 577 { 578 # Support for ccache compilation 579 if [ "$NDK_CCACHE" ]; then 580 NDK_CCACHE_CC=$CC 581 NDK_CCACHE_CXX=$CXX 582 # Unfortunately, we can just do CC="$NDK_CCACHE $CC" because some 583 # configure scripts are not capable of dealing with this properly 584 # E.g. the ones used to rebuild the GCC toolchain from scratch. 585 # So instead, use a wrapper script 586 CC=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-gcc.sh 587 CXX=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-g++.sh 588 export NDK_CCACHE_CC NDK_CCACHE_CXX 589 log "Using ccache compilation" 590 log "NDK_CCACHE_CC=$NDK_CCACHE_CC" 591 log "NDK_CCACHE_CXX=$NDK_CCACHE_CXX" 592 fi 593 } 594 595 prepare_common_build () 596 { 597 # On Linux, detect our legacy-compatible toolchain when in the Android 598 # source tree, and use it to force the generation of glibc-2.7 compatible 599 # binaries. 600 # 601 # We only do this if the CC variable is not defined to a given value 602 # and the --mingw or --try-64 options are not used. 603 # 604 if [ "$HOST_OS" = "linux" -a -z "$CC" -a "$MINGW" != "yes" -a "$TRY64" != "yes" ]; then 605 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3" 606 if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then 607 log "Forcing generation of Linux binaries with legacy toolchain" 608 CC="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-gcc" 609 CXX="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-g++" 610 fi 611 fi 612 613 # Force generation of 32-bit binaries on 64-bit systems 614 CC=${CC:-gcc} 615 CXX=${CXX:-g++} 616 case $HOST_TAG in 617 darwin-*) 618 # Try to build with Tiger SDK if available 619 if check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku 10.4; then 620 log "Generating Tiger-compatible binaries!" 621 # Otherwise with Leopard SDK 622 elif check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk 10.5; then 623 log "Generating Leopard-compatible binaries!" 624 else 625 local version=`sw_vers -productVersion` 626 log "Generating $version-compatible binaries!" 627 fi 628 ;; 629 esac 630 631 # Force generation of 32-bit binaries on 64-bit systems. 632 # We used to test the value of $HOST_TAG for *-x86_64, but this is 633 # not sufficient on certain systems. 634 # 635 # For example, Snow Leopard can be booted with a 32-bit kernel, running 636 # a 64-bit userland, with a compiler that generates 64-bit binaries by 637 # default *even* though "gcc -v" will report --target=i686-apple-darwin10! 638 # 639 # So know, simply probe for the size of void* by performing a small runtime 640 # compilation test. 641 # 642 cat > $TMPC <<EOF 643 /* this test should fail if the compiler generates 64-bit machine code */ 644 int test_array[1-2*(sizeof(void*) != 4)]; 645 EOF 646 log -n "Checking whether the compiler generates 32-bit binaries..." 647 HOST_BITS=32 648 log2 $CC $HOST_CFLAGS -c -o $TMPO $TMPC 649 $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1 650 if [ $? != 0 ] ; then 651 echo "no" 652 if [ "$TRY64" != "yes" ]; then 653 # NOTE: We need to modify the definitions of CC and CXX directly 654 # here. Just changing the value of CFLAGS / HOST_CFLAGS 655 # will not work well with the GCC toolchain scripts. 656 CC="$CC -m32" 657 CXX="$CXX -m32" 658 else 659 HOST_BITS=64 660 fi 661 else 662 log "yes" 663 fi 664 665 # For now, we only support building 32-bit binaries anyway 666 if [ "$TRY64" != "yes" ]; then 667 force_32bit_binaries # to modify HOST_TAG and others 668 HOST_BITS=32 669 fi 670 } 671 672 prepare_host_build () 673 { 674 prepare_common_build 675 676 # Now deal with mingw 677 if [ "$MINGW" = "yes" ]; then 678 handle_mingw 679 CC=$ABI_CONFIGURE_HOST-gcc 680 CXX=$ABI_CONFIGURE_HOST-g++ 681 LD=$ABI_CONFIGURE_HOST-ld 682 AR=$ABI_CONFIGURE_HOST-ar 683 AS=$ABI_CONFIGURE_HOST-as 684 RANLIB=$ABI_CONFIGURE_HOST-ranlib 685 export CC CXX LD AR AS RANLIB 686 fi 687 688 setup_ccache 689 } 690 691 692 prepare_target_build () 693 { 694 # detect build tag 695 case $HOST_TAG in 696 linux-x86) 697 ABI_CONFIGURE_BUILD=i386-linux-gnu 698 ;; 699 linux-x86_64) 700 ABI_CONFIGURE_BUILD=x86_64-linux-gnu 701 ;; 702 darwin-x86) 703 ABI_CONFIGURE_BUILD=i686-apple-darwin 704 ;; 705 darwin-x86_64) 706 ABI_CONFIGURE_BUILD=x86_64-apple-darwin 707 ;; 708 windows) 709 ABI_CONFIGURE_BUILD=i686-pc-cygwin 710 ;; 711 *) 712 echo "ERROR: Unsupported HOST_TAG: $HOST_TAG" 713 echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh" 714 ;; 715 esac 716 717 # By default, assume host == build 718 ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD" 719 720 prepare_common_build 721 HOST_GMP_ABI=$HOST_BITS 722 723 # Now handle the --mingw flag 724 if [ "$MINGW" = "yes" ] ; then 725 handle_mingw 726 # It turns out that we need to undefine this to be able to 727 # perform a canadian-cross build with mingw. Otherwise, the 728 # GMP configure scripts will not be called with the right options 729 HOST_GMP_ABI= 730 fi 731 732 setup_ccache 733 } 734 735 parse_toolchain_name () 736 { 737 if [ -z "$TOOLCHAIN" ] ; then 738 echo "ERROR: Missing toolchain name!" 739 exit 1 740 fi 741 742 ABI_CFLAGS_FOR_TARGET= 743 ABI_CXXFLAGS_FOR_TARGET= 744 745 # Determine ABI based on toolchain name 746 # 747 case "$TOOLCHAIN" in 748 arm-linux-androideabi-*) 749 ARCH="arm" 750 ABI="armeabi" 751 ABI_CONFIGURE_TARGET="arm-linux-androideabi" 752 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te" 753 # Disable ARM Gold linker for now, it doesn't build on Windows, it 754 # crashes with SIGBUS on Darwin, and produces weird executables on 755 # linux that strip complains about... Sigh. 756 #ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --enable-gold=both/gold" 757 758 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 759 # You can't really build these separately at the moment. 760 ABI_CFLAGS_FOR_TARGET="-fexceptions" 761 ABI_CXXFLAGS_FOR_TARGET="-frtti" 762 ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --enable-libstdc__-v3" 763 ;; 764 x86-*) 765 ARCH="x86" 766 ABI=$ARCH 767 ABI_INSTALL_NAME="x86" 768 ABI_CONFIGURE_TARGET="i686-android-linux" 769 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 770 # You can't really build these separately at the moment. 771 ABI_CFLAGS_FOR_TARGET="-fexceptions -fPIC" 772 ABI_CXXFLAGS_FOR_TARGET="-frtti" 773 ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --enable-libstdc__-v3" 774 ;; 775 * ) 776 echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|x86-*)" 777 echo "" 778 print_help 779 exit 1 780 ;; 781 esac 782 783 log "Targetting CPU: $ARCH" 784 785 GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'` 786 log "Using GCC version: $GCC_VERSION" 787 788 # Determine --host value when building gdbserver 789 case "$TOOLCHAIN" in 790 arm-*) 791 GDBSERVER_HOST=arm-eabi-linux 792 GDBSERVER_CFLAGS="-fno-short-enums" 793 ;; 794 x86-*) 795 GDBSERVER_HOST=i686-android-linux-gnu 796 GDBSERVER_CFLAGS= 797 ;; 798 esac 799 800 } 801 802 # Return the host "tag" used to identify prebuilt host binaries. 803 # NOTE: Handles the case where '$MINGW = true' 804 # For now, valid values are: linux-x86, darwin-x86 and windows 805 get_prebuilt_host_tag () 806 { 807 local RET=$HOST_TAG 808 if [ "$MINGW" = "yes" ]; then 809 RET=windows 810 fi 811 case $RET in 812 linux-x86_64) 813 if [ "$TRY64" = "no" ]; then 814 RET=linux-x86 815 fi 816 ;; 817 darwin_x86_64) 818 if [ "$TRY64" = "no" ]; then 819 RET=darwin-x86 820 fi 821 ;; 822 esac 823 echo $RET 824 } 825 826 # Return the executable suffix corresponding to host executables 827 get_prebuilt_host_exe_ext () 828 { 829 if [ "$MINGW" = "yes" ]; then 830 echo ".exe" 831 else 832 echo "" 833 fi 834 } 835 836 # Convert an ABI name into an Architecture name 837 # $1: ABI name 838 # Result: Arch name 839 convert_abi_to_arch () 840 { 841 local RET 842 case $1 in 843 armeabi|armeabi-v7a) 844 RET=arm 845 ;; 846 x86) 847 RET=x86 848 ;; 849 *) 850 2> echo "ERROR: Unsupported ABI name: $1, use one of: armeabi, armeabi-v7a or x86" 851 exit 1 852 ;; 853 esac 854 echo "$RET" 855 } 856 857 # Return the default binary path prefix for a given architecture 858 # For example: arm -> toolchains/arm-linux-androideabi-4.4.3/prebuilt/<system>/bin/arm-linux-androideabi- 859 # $1: Architecture name 860 # $2: optional, system name, defaults to $HOST_TAG 861 get_default_toolchain_binprefix_for_arch () 862 { 863 local NAME PREFIX DIR BINPREFIX 864 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 865 NAME=$(get_default_toolchain_name_for_arch $1) 866 PREFIX=$(get_default_toolchain_prefix_for_arch $1) 867 DIR=$(get_toolchain_install . $NAME $SYSTEM) 868 BINPREFIX=${DIR#./}/bin/$PREFIX- 869 echo "$BINPREFIX" 870 } 871 872 # Return default API level for a given arch 873 # This is the level used to build the toolchains. 874 # 875 # $1: Architecture name 876 get_default_api_level_for_arch () 877 { 878 # For now, always build the toolchain against API level 9 879 # (We have local toolchain patches under build/tools/toolchain-patches 880 # to ensure that the result works on previous platforms properly). 881 local LEVEL=9 882 echo $LEVEL 883 } 884 885 # Return the default platform sysroot corresponding to a given architecture 886 # This is the sysroot used to build the toolchain and other binaries like 887 # the STLport libraries. 888 # $1: Architecture name 889 get_default_platform_sysroot_for_arch () 890 { 891 local LEVEL=$(get_default_api_level_for_arch $1) 892 echo "platforms/android-$LEVEL/arch-$1" 893 } 894 895 # Guess what? 896 get_default_platform_sysroot_for_abi () 897 { 898 local ARCH=$(convert_abi_to_arch $1) 899 $(get_default_platform_sysroot_for_arch $ARCH) 900 } 901 902 903 904 # Return the host/build specific path for prebuilt toolchain binaries 905 # relative to $1. 906 # 907 # $1: target root NDK directory 908 # $2: toolchain name 909 # $3: optional, host system name 910 # 911 get_toolchain_install () 912 { 913 local NDK="$1" 914 shift 915 echo "$NDK/$(get_toolchain_install_subdir $@)" 916 } 917 918 # $1: toolchain name 919 # $2: optional, host system name 920 get_toolchain_install_subdir () 921 { 922 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 923 echo "toolchains/$1/prebuilt/$SYSTEM" 924 } 925 926 # Return the relative install prefix for prebuilt host 927 # executables (relative to the NDK top directory). 928 # NOTE: This deals with MINGW==yes appropriately 929 # 930 # $1: optional, system name 931 # Out: relative path to prebuilt install prefix 932 get_prebuilt_install_prefix () 933 { 934 local TAG=${1:-$(get_prebuilt_host_tag)} 935 echo "prebuilt/$TAG" 936 } 937 938 # Return the relative path of an installed prebuilt host 939 # executable 940 # NOTE: This deals with MINGW==yes appropriately. 941 # 942 # $1: executable name 943 # $2: optional, host system name 944 # Out: path to prebuilt host executable, relative 945 get_prebuilt_host_exec () 946 { 947 local PREFIX EXE 948 PREFIX=$(get_prebuilt_install_prefix $2) 949 EXE=$(get_prebuilt_host_exe_ext) 950 echo "$PREFIX/bin/$1$EXE" 951 } 952 953 # Return the name of a given host executable 954 # $1: executable base name 955 # Out: executable name, with optional suffix (e.g. .exe for windows) 956 get_host_exec_name () 957 { 958 local EXE=$(get_prebuilt_host_exe_ext) 959 echo "$1$EXE" 960 } 961 962 # Return the directory where host-specific binaries are installed. 963 # $1: target root NDK directory 964 get_host_install () 965 { 966 echo "$1/$(get_prebuilt_install_prefix)" 967 } 968 969 # Set the toolchain target NDK location. 970 # this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX 971 # $1: target NDK path 972 # $2: toolchain name 973 set_toolchain_ndk () 974 { 975 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 976 log "Using toolchain path: $TOOLCHAIN_PATH" 977 978 TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET 979 log "Using toolchain prefix: $TOOLCHAIN_PREFIX" 980 } 981 982 # Check that a toolchain is properly installed at a target NDK location 983 # 984 # $1: target root NDK directory 985 # $2: toolchain name 986 # 987 check_toolchain_install () 988 { 989 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 990 if [ ! -d "$TOOLCHAIN_PATH" ] ; then 991 echo "ERROR: Toolchain '$2' not installed in '$NDK_DIR'!" 992 echo " Ensure that the toolchain has been installed there before." 993 exit 1 994 fi 995 996 set_toolchain_ndk $1 $2 997 } 998 999 1000 # 1001 # The NDK_TMPDIR variable is used to specify a root temporary directory 1002 # when invoking toolchain build scripts. If it is not defined, we will 1003 # create one here, and export the value to ensure that any scripts we 1004 # call after that use the same one. 1005 # 1006 if [ -z "$NDK_TMPDIR" ]; then 1007 NDK_TMPDIR=/tmp/ndk-$USER/tmp/build-$$ 1008 mkdir -p $NDK_TMPDIR 1009 if [ $? != 0 ]; then 1010 echo "ERROR: Could not create NDK_TMPDIR: $NDK_TMPDIR" 1011 exit 1 1012 fi 1013 export NDK_TMPDIR 1014 fi 1015 1016 # Define HOST_TAG32, as the 32-bit version of HOST_TAG 1017 # We do this by replacing an -x86_64 suffix by -x86 1018 HOST_TAG32=$HOST_TAG 1019 case $HOST_TAG32 in 1020 *-x86_64) 1021 HOST_TAG32=${HOST_TAG%%_64} 1022 ;; 1023 esac 1024