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 HOST_EXE= 547 if [ "$MINGW" = "yes" ] ; then 548 case $HOST_TAG in 549 linux-*) 550 ;; 551 *) 552 echo "ERROR: Can only enable mingw on Linux platforms !" 553 exit 1 554 ;; 555 esac 556 if [ "$TRY64" = "yes" ]; then 557 ABI_CONFIGURE_HOST=amd64-mingw32msvc 558 else 559 ABI_CONFIGURE_HOST=i586-mingw32msvc 560 fi 561 HOST_OS=windows 562 HOST_TAG=windows 563 HOST_EXE=.exe 564 fi 565 } 566 567 handle_host () 568 { 569 # For now, we only support building 32-bit binaries anyway 570 if [ "$TRY64" != "yes" ]; then 571 force_32bit_binaries # to modify HOST_TAG and others 572 HOST_BITS=32 573 fi 574 handle_mingw 575 } 576 577 setup_ccache () 578 { 579 # Support for ccache compilation 580 if [ "$NDK_CCACHE" ]; then 581 NDK_CCACHE_CC=$CC 582 NDK_CCACHE_CXX=$CXX 583 # Unfortunately, we can just do CC="$NDK_CCACHE $CC" because some 584 # configure scripts are not capable of dealing with this properly 585 # E.g. the ones used to rebuild the GCC toolchain from scratch. 586 # So instead, use a wrapper script 587 CC=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-gcc.sh 588 CXX=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-g++.sh 589 export NDK_CCACHE_CC NDK_CCACHE_CXX 590 log "Using ccache compilation" 591 log "NDK_CCACHE_CC=$NDK_CCACHE_CC" 592 log "NDK_CCACHE_CXX=$NDK_CCACHE_CXX" 593 fi 594 } 595 596 prepare_common_build () 597 { 598 # On Linux, detect our legacy-compatible toolchain when in the Android 599 # source tree, and use it to force the generation of glibc-2.7 compatible 600 # binaries. 601 # 602 # We only do this if the CC variable is not defined to a given value 603 # and the --mingw or --try-64 options are not used. 604 # 605 if [ "$HOST_OS" = "linux" -a -z "$CC" -a "$MINGW" != "yes" -a "$TRY64" != "yes" ]; then 606 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3" 607 if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then 608 log "Forcing generation of Linux binaries with legacy toolchain" 609 CC="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-gcc" 610 CXX="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-g++" 611 fi 612 fi 613 614 # Force generation of 32-bit binaries on 64-bit systems 615 CC=${CC:-gcc} 616 CXX=${CXX:-g++} 617 STRIP=${STRIP:-strip} 618 case $HOST_TAG in 619 darwin-*) 620 # Try to build with Tiger SDK if available 621 if check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku 10.4; then 622 log "Generating Tiger-compatible binaries!" 623 # Otherwise with Leopard SDK 624 elif check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk 10.5; then 625 log "Generating Leopard-compatible binaries!" 626 else 627 local version=`sw_vers -productVersion` 628 log "Generating $version-compatible binaries!" 629 fi 630 ;; 631 esac 632 633 # Force generation of 32-bit binaries on 64-bit systems. 634 # We used to test the value of $HOST_TAG for *-x86_64, but this is 635 # not sufficient on certain systems. 636 # 637 # For example, Snow Leopard can be booted with a 32-bit kernel, running 638 # a 64-bit userland, with a compiler that generates 64-bit binaries by 639 # default *even* though "gcc -v" will report --target=i686-apple-darwin10! 640 # 641 # So know, simply probe for the size of void* by performing a small runtime 642 # compilation test. 643 # 644 cat > $TMPC <<EOF 645 /* this test should fail if the compiler generates 64-bit machine code */ 646 int test_array[1-2*(sizeof(void*) != 4)]; 647 EOF 648 log -n "Checking whether the compiler generates 32-bit binaries..." 649 HOST_BITS=32 650 log2 $CC $HOST_CFLAGS -c -o $TMPO $TMPC 651 $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1 652 if [ $? != 0 ] ; then 653 log "no" 654 if [ "$TRY64" != "yes" ]; then 655 # NOTE: We need to modify the definitions of CC and CXX directly 656 # here. Just changing the value of CFLAGS / HOST_CFLAGS 657 # will not work well with the GCC toolchain scripts. 658 CC="$CC -m32" 659 CXX="$CXX -m32" 660 else 661 HOST_BITS=64 662 fi 663 else 664 log "yes" 665 fi 666 667 # For now, we only support building 32-bit binaries anyway 668 if [ "$TRY64" != "yes" ]; then 669 force_32bit_binaries # to modify HOST_TAG and others 670 HOST_BITS=32 671 fi 672 } 673 674 prepare_host_build () 675 { 676 prepare_common_build 677 678 # Now deal with mingw 679 if [ "$MINGW" = "yes" ]; then 680 handle_mingw 681 CC=$ABI_CONFIGURE_HOST-gcc 682 CXX=$ABI_CONFIGURE_HOST-g++ 683 LD=$ABI_CONFIGURE_HOST-ld 684 AR=$ABI_CONFIGURE_HOST-ar 685 AS=$ABI_CONFIGURE_HOST-as 686 RANLIB=$ABI_CONFIGURE_HOST-ranlib 687 STRIP=$ABI_CONFIGURE_HOST-strip 688 export CC CXX LD AR AS RANLIB STRIP 689 fi 690 691 setup_ccache 692 } 693 694 695 prepare_target_build () 696 { 697 # detect build tag 698 case $HOST_TAG in 699 linux-x86) 700 ABI_CONFIGURE_BUILD=i386-linux-gnu 701 ;; 702 linux-x86_64) 703 ABI_CONFIGURE_BUILD=x86_64-linux-gnu 704 ;; 705 darwin-x86) 706 ABI_CONFIGURE_BUILD=i686-apple-darwin 707 ;; 708 darwin-x86_64) 709 ABI_CONFIGURE_BUILD=x86_64-apple-darwin 710 ;; 711 windows) 712 ABI_CONFIGURE_BUILD=i686-pc-cygwin 713 ;; 714 *) 715 echo "ERROR: Unsupported HOST_TAG: $HOST_TAG" 716 echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh" 717 ;; 718 esac 719 720 # By default, assume host == build 721 ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD" 722 723 prepare_common_build 724 HOST_GMP_ABI=$HOST_BITS 725 726 # Now handle the --mingw flag 727 if [ "$MINGW" = "yes" ] ; then 728 handle_mingw 729 # It turns out that we need to undefine this to be able to 730 # perform a canadian-cross build with mingw. Otherwise, the 731 # GMP configure scripts will not be called with the right options 732 HOST_GMP_ABI= 733 fi 734 735 setup_ccache 736 } 737 738 parse_toolchain_name () 739 { 740 if [ -z "$TOOLCHAIN" ] ; then 741 echo "ERROR: Missing toolchain name!" 742 exit 1 743 fi 744 745 ABI_CFLAGS_FOR_TARGET= 746 ABI_CXXFLAGS_FOR_TARGET= 747 748 # Determine ABI based on toolchain name 749 # 750 case "$TOOLCHAIN" in 751 arm-linux-androideabi-*) 752 ARCH="arm" 753 ABI="armeabi" 754 ABI_CONFIGURE_TARGET="arm-linux-androideabi" 755 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te" 756 # Disable ARM Gold linker for now, it doesn't build on Windows, it 757 # crashes with SIGBUS on Darwin, and produces weird executables on 758 # linux that strip complains about... Sigh. 759 #ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --enable-gold=both/gold" 760 761 ;; 762 x86-*) 763 ARCH="x86" 764 ABI=$ARCH 765 ABI_INSTALL_NAME="x86" 766 ABI_CONFIGURE_TARGET="i686-android-linux" 767 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 768 # You can't really build these separately at the moment. 769 ABI_CFLAGS_FOR_TARGET="-fPIC" 770 ;; 771 * ) 772 echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|x86-*)" 773 echo "" 774 print_help 775 exit 1 776 ;; 777 esac 778 779 log "Targetting CPU: $ARCH" 780 781 GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'` 782 log "Using GCC version: $GCC_VERSION" 783 784 # Determine --host value when building gdbserver 785 case "$TOOLCHAIN" in 786 arm-*) 787 GDBSERVER_HOST=arm-eabi-linux 788 GDBSERVER_CFLAGS="-fno-short-enums" 789 ;; 790 x86-*) 791 GDBSERVER_HOST=i686-android-linux-gnu 792 GDBSERVER_CFLAGS= 793 ;; 794 esac 795 796 } 797 798 # Return the host "tag" used to identify prebuilt host binaries. 799 # NOTE: Handles the case where '$MINGW = true' 800 # For now, valid values are: linux-x86, darwin-x86 and windows 801 get_prebuilt_host_tag () 802 { 803 local RET=$HOST_TAG 804 if [ "$MINGW" = "yes" ]; then 805 RET=windows 806 fi 807 case $RET in 808 linux-x86_64) 809 if [ "$TRY64" = "no" ]; then 810 RET=linux-x86 811 fi 812 ;; 813 darwin_x86_64) 814 if [ "$TRY64" = "no" ]; then 815 RET=darwin-x86 816 fi 817 ;; 818 esac 819 echo $RET 820 } 821 822 # Return the executable suffix corresponding to host executables 823 get_prebuilt_host_exe_ext () 824 { 825 if [ "$MINGW" = "yes" ]; then 826 echo ".exe" 827 else 828 echo "" 829 fi 830 } 831 832 # Convert an ABI name into an Architecture name 833 # $1: ABI name 834 # Result: Arch name 835 convert_abi_to_arch () 836 { 837 local RET 838 case $1 in 839 armeabi|armeabi-v7a) 840 RET=arm 841 ;; 842 x86) 843 RET=x86 844 ;; 845 *) 846 2> echo "ERROR: Unsupported ABI name: $1, use one of: armeabi, armeabi-v7a or x86" 847 exit 1 848 ;; 849 esac 850 echo "$RET" 851 } 852 853 # Return the default binary path prefix for a given architecture 854 # For example: arm -> toolchains/arm-linux-androideabi-4.4.3/prebuilt/<system>/bin/arm-linux-androideabi- 855 # $1: Architecture name 856 # $2: optional, system name, defaults to $HOST_TAG 857 get_default_toolchain_binprefix_for_arch () 858 { 859 local NAME PREFIX DIR BINPREFIX 860 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 861 NAME=$(get_default_toolchain_name_for_arch $1) 862 PREFIX=$(get_default_toolchain_prefix_for_arch $1) 863 DIR=$(get_toolchain_install . $NAME $SYSTEM) 864 BINPREFIX=${DIR#./}/bin/$PREFIX- 865 echo "$BINPREFIX" 866 } 867 868 # Return default API level for a given arch 869 # This is the level used to build the toolchains. 870 # 871 # $1: Architecture name 872 get_default_api_level_for_arch () 873 { 874 # For now, always build the toolchain against API level 9 875 # (We have local toolchain patches under build/tools/toolchain-patches 876 # to ensure that the result works on previous platforms properly). 877 local LEVEL=9 878 echo $LEVEL 879 } 880 881 # Return the default platform sysroot corresponding to a given architecture 882 # This is the sysroot used to build the toolchain and other binaries like 883 # the STLport libraries. 884 # $1: Architecture name 885 get_default_platform_sysroot_for_arch () 886 { 887 local LEVEL=$(get_default_api_level_for_arch $1) 888 echo "platforms/android-$LEVEL/arch-$1" 889 } 890 891 # Guess what? 892 get_default_platform_sysroot_for_abi () 893 { 894 local ARCH=$(convert_abi_to_arch $1) 895 $(get_default_platform_sysroot_for_arch $ARCH) 896 } 897 898 899 900 # Return the host/build specific path for prebuilt toolchain binaries 901 # relative to $1. 902 # 903 # $1: target root NDK directory 904 # $2: toolchain name 905 # $3: optional, host system name 906 # 907 get_toolchain_install () 908 { 909 local NDK="$1" 910 shift 911 echo "$NDK/$(get_toolchain_install_subdir $@)" 912 } 913 914 # $1: toolchain name 915 # $2: optional, host system name 916 get_toolchain_install_subdir () 917 { 918 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 919 echo "toolchains/$1/prebuilt/$SYSTEM" 920 } 921 922 # Return the relative install prefix for prebuilt host 923 # executables (relative to the NDK top directory). 924 # NOTE: This deals with MINGW==yes appropriately 925 # 926 # $1: optional, system name 927 # Out: relative path to prebuilt install prefix 928 get_prebuilt_install_prefix () 929 { 930 local TAG=${1:-$(get_prebuilt_host_tag)} 931 echo "prebuilt/$TAG" 932 } 933 934 # Return the relative path of an installed prebuilt host 935 # executable 936 # NOTE: This deals with MINGW==yes appropriately. 937 # 938 # $1: executable name 939 # $2: optional, host system name 940 # Out: path to prebuilt host executable, relative 941 get_prebuilt_host_exec () 942 { 943 local PREFIX EXE 944 PREFIX=$(get_prebuilt_install_prefix $2) 945 EXE=$(get_prebuilt_host_exe_ext) 946 echo "$PREFIX/bin/$1$EXE" 947 } 948 949 # Return the name of a given host executable 950 # $1: executable base name 951 # Out: executable name, with optional suffix (e.g. .exe for windows) 952 get_host_exec_name () 953 { 954 local EXE=$(get_prebuilt_host_exe_ext) 955 echo "$1$EXE" 956 } 957 958 # Return the directory where host-specific binaries are installed. 959 # $1: target root NDK directory 960 get_host_install () 961 { 962 echo "$1/$(get_prebuilt_install_prefix)" 963 } 964 965 # Set the toolchain target NDK location. 966 # this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX 967 # $1: target NDK path 968 # $2: toolchain name 969 set_toolchain_ndk () 970 { 971 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 972 log "Using toolchain path: $TOOLCHAIN_PATH" 973 974 TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET 975 log "Using toolchain prefix: $TOOLCHAIN_PREFIX" 976 } 977 978 # Check that a toolchain is properly installed at a target NDK location 979 # 980 # $1: target root NDK directory 981 # $2: toolchain name 982 # 983 check_toolchain_install () 984 { 985 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 986 if [ ! -d "$TOOLCHAIN_PATH" ] ; then 987 echo "ERROR: Toolchain '$2' not installed in '$NDK_DIR'!" 988 echo " Ensure that the toolchain has been installed there before." 989 exit 1 990 fi 991 992 set_toolchain_ndk $1 $2 993 } 994 995 # $1: toolchain source directory 996 check_toolchain_src_dir () 997 { 998 local SRC_DIR="$1" 999 if [ -z "$SRC_DIR" ]; then 1000 echo "ERROR: Please provide the path to the toolchain source tree. See --help" 1001 exit 1 1002 fi 1003 1004 if [ ! -d "$SRC_DIR" ]; then 1005 echo "ERROR: Not a directory: '$SRC_DIR'" 1006 exit 1 1007 fi 1008 1009 if [ ! -f "$SRC_DIR/build/configure" -o ! -d "$SRC_DIR/gcc" ]; then 1010 echo "ERROR: This is not the top of a toolchain tree: $SRC_DIR" 1011 echo "You must give the path to a copy of the toolchain source directories" 1012 echo "created by 'download-toolchain-sources.sh." 1013 exit 1 1014 fi 1015 } 1016 1017 # 1018 # The NDK_TMPDIR variable is used to specify a root temporary directory 1019 # when invoking toolchain build scripts. If it is not defined, we will 1020 # create one here, and export the value to ensure that any scripts we 1021 # call after that use the same one. 1022 # 1023 if [ -z "$NDK_TMPDIR" ]; then 1024 NDK_TMPDIR=/tmp/ndk-$USER/tmp/build-$$ 1025 mkdir -p $NDK_TMPDIR 1026 if [ $? != 0 ]; then 1027 echo "ERROR: Could not create NDK_TMPDIR: $NDK_TMPDIR" 1028 exit 1 1029 fi 1030 export NDK_TMPDIR 1031 fi 1032 1033 # Define HOST_TAG32, as the 32-bit version of HOST_TAG 1034 # We do this by replacing an -x86_64 suffix by -x86 1035 HOST_TAG32=$HOST_TAG 1036 case $HOST_TAG32 in 1037 *-x86_64) 1038 HOST_TAG32=${HOST_TAG%%_64} 1039 ;; 1040 esac 1041