prebuilt-common.sh revision 66850386d842e890ae22c5f220a2a24a167602cd
1# Common functions for all prebuilt-related scripts 2# This is included/sourced by other scripts 3# 4 5# ensure stable sort order 6export 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# 12if [ -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 18fi 19 20NDK_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# 35max_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>` 42dashes_to_underscores () 43{ 44 echo "$@" | tr '-' '_' 45} 46 47# Translate underscores to dashes 48# Usage: str=`underscores_to_dashes <values>` 49underscores_to_dashes () 50{ 51 echo "$@" | tr '_' '-' 52} 53 54# Translate commas to spaces 55# Usage: str=`commas_to_spaces <list>` 56commas_to_spaces () 57{ 58 echo "$@" | tr ',' ' ' 59} 60 61# Translate spaces to commas 62# Usage: list=`spaces_to_commas <string>` 63spaces_to_commas () 64{ 65 echo "$@" | tr ' ' ',' 66} 67 68# Remove trailing path of a path 69# $1: path 70remove_trailing_slash () { 71 echo ${1%%/} 72} 73 74# Reverse a file path directory 75# foo -> . 76# foo/bar -> .. 77# foo/bar/zoo -> ../.. 78reverse_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 111sort_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 121list_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 148OPTIONS="" 149OPTION_FLAGS="" 150OPTION_SETTINGS="" 151 152# Set a given option attribute 153# $1: option name 154# $2: option attribute 155# $3: attribute value 156# 157option_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# 166option_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# 176register_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# 242register_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# 257register_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 265MINGW=no 266do_mingw_option () { MINGW=yes; } 267 268register_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 275TRY64=no 276do_try64_option () { TRY64=yes; } 277 278register_try64_option () 279{ 280 register_option "--try-64" do_try64_option "Generate 64-bit binaries." 281} 282 283 284register_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# 294print_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 322option_panic_no_args () 323{ 324 echo "ERROR: Option '$1' does not take arguments. See --help for usage." 325 exit 1 326} 327 328option_panic_missing_arg () 329{ 330 echo "ERROR: Option '$1' requires an argument. See --help for usage." 331 exit 1 332} 333 334extract_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 441do_option_help () 442{ 443 print_help 444 exit 0 445} 446 447VERBOSE=no 448VERBOSE2=no 449do_option_verbose () 450{ 451 if [ $VERBOSE = "yes" ] ; then 452 VERBOSE2=yes 453 else 454 VERBOSE=yes 455 fi 456} 457 458register_option "--help" do_option_help "Print this help." 459register_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 471fix_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 487check_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# 500fix_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) 532check_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 543handle_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 567handle_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 577setup_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 596prepare_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)]; 647EOF 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 674prepare_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 695prepare_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# $1: Optional toolchain name (uses $TOOLCHAIN otherwise) 739# 740parse_toolchain_name () 741{ 742 if [ -n "$1" ]; then 743 TOOLCHAIN=$1 744 fi 745 if [ -z "$TOOLCHAIN" ] ; then 746 echo "ERROR: Missing toolchain name!" 747 exit 1 748 fi 749 750 ABI_CFLAGS_FOR_TARGET= 751 ABI_CXXFLAGS_FOR_TARGET= 752 753 # Determine ABI based on toolchain name 754 # 755 case "$TOOLCHAIN" in 756 arm-linux-androideabi-*) 757 ARCH="arm" 758 ABI="armeabi" 759 ABI_CONFIGURE_TARGET="arm-linux-androideabi" 760 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te" 761 # Disable ARM Gold linker for now, it doesn't build on Windows, it 762 # crashes with SIGBUS on Darwin, and produces weird executables on 763 # linux that strip complains about... Sigh. 764 #ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --enable-gold=both/gold" 765 766 ;; 767 x86-*) 768 ARCH="x86" 769 ABI=$ARCH 770 ABI_INSTALL_NAME="x86" 771 ABI_CONFIGURE_TARGET="i686-android-linux" 772 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 773 # You can't really build these separately at the moment. 774 ABI_CFLAGS_FOR_TARGET="-fPIC" 775 ;; 776 * ) 777 echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|x86-*)" 778 echo "" 779 print_help 780 exit 1 781 ;; 782 esac 783 784 log "Targetting CPU: $ARCH" 785 786 GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'` 787 log "Using GCC version: $GCC_VERSION" 788 789 # Determine --host value when building gdbserver 790 case "$TOOLCHAIN" in 791 arm-*) 792 GDBSERVER_HOST=arm-eabi-linux 793 GDBSERVER_CFLAGS="-fno-short-enums" 794 ;; 795 x86-*) 796 GDBSERVER_HOST=i686-android-linux-gnu 797 GDBSERVER_CFLAGS= 798 ;; 799 esac 800 801} 802 803# Return the host "tag" used to identify prebuilt host binaries. 804# NOTE: Handles the case where '$MINGW = true' 805# For now, valid values are: linux-x86, darwin-x86 and windows 806get_prebuilt_host_tag () 807{ 808 local RET=$HOST_TAG 809 if [ "$MINGW" = "yes" ]; then 810 RET=windows 811 fi 812 case $RET in 813 linux-x86_64) 814 if [ "$TRY64" = "no" ]; then 815 RET=linux-x86 816 fi 817 ;; 818 darwin_x86_64) 819 if [ "$TRY64" = "no" ]; then 820 RET=darwin-x86 821 fi 822 ;; 823 esac 824 echo $RET 825} 826 827# Return the executable suffix corresponding to host executables 828get_prebuilt_host_exe_ext () 829{ 830 if [ "$MINGW" = "yes" ]; then 831 echo ".exe" 832 else 833 echo "" 834 fi 835} 836 837# Convert an ABI name into an Architecture name 838# $1: ABI name 839# Result: Arch name 840convert_abi_to_arch () 841{ 842 local RET 843 case $1 in 844 armeabi|armeabi-v7a) 845 RET=arm 846 ;; 847 x86) 848 RET=x86 849 ;; 850 *) 851 2> echo "ERROR: Unsupported ABI name: $1, use one of: armeabi, armeabi-v7a or x86" 852 exit 1 853 ;; 854 esac 855 echo "$RET" 856} 857 858# Return the default binary path prefix for a given architecture 859# For example: arm -> toolchains/arm-linux-androideabi-4.4.3/prebuilt/<system>/bin/arm-linux-androideabi- 860# $1: Architecture name 861# $2: optional, system name, defaults to $HOST_TAG 862get_default_toolchain_binprefix_for_arch () 863{ 864 local NAME PREFIX DIR BINPREFIX 865 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 866 NAME=$(get_default_toolchain_name_for_arch $1) 867 PREFIX=$(get_default_toolchain_prefix_for_arch $1) 868 DIR=$(get_toolchain_install . $NAME $SYSTEM) 869 BINPREFIX=${DIR#./}/bin/$PREFIX- 870 echo "$BINPREFIX" 871} 872 873# Return default API level for a given arch 874# This is the level used to build the toolchains. 875# 876# $1: Architecture name 877get_default_api_level_for_arch () 878{ 879 # For now, always build the toolchain against API level 9 880 # (We have local toolchain patches under build/tools/toolchain-patches 881 # to ensure that the result works on previous platforms properly). 882 local LEVEL=9 883 echo $LEVEL 884} 885 886# Return the default platform sysroot corresponding to a given architecture 887# This is the sysroot used to build the toolchain and other binaries like 888# the STLport libraries. 889# $1: Architecture name 890get_default_platform_sysroot_for_arch () 891{ 892 local LEVEL=$(get_default_api_level_for_arch $1) 893 echo "platforms/android-$LEVEL/arch-$1" 894} 895 896# Guess what? 897get_default_platform_sysroot_for_abi () 898{ 899 local ARCH=$(convert_abi_to_arch $1) 900 $(get_default_platform_sysroot_for_arch $ARCH) 901} 902 903 904 905# Return the host/build specific path for prebuilt toolchain binaries 906# relative to $1. 907# 908# $1: target root NDK directory 909# $2: toolchain name 910# $3: optional, host system name 911# 912get_toolchain_install () 913{ 914 local NDK="$1" 915 shift 916 echo "$NDK/$(get_toolchain_install_subdir "$@")" 917} 918 919# $1: toolchain name 920# $2: optional, host system name 921get_toolchain_install_subdir () 922{ 923 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 924 echo "toolchains/$1/prebuilt/$SYSTEM" 925} 926 927# Return the relative install prefix for prebuilt host 928# executables (relative to the NDK top directory). 929# NOTE: This deals with MINGW==yes appropriately 930# 931# $1: optional, system name 932# Out: relative path to prebuilt install prefix 933get_prebuilt_install_prefix () 934{ 935 local TAG=${1:-$(get_prebuilt_host_tag)} 936 echo "prebuilt/$TAG" 937} 938 939# Return the relative path of an installed prebuilt host 940# executable 941# NOTE: This deals with MINGW==yes appropriately. 942# 943# $1: executable name 944# $2: optional, host system name 945# Out: path to prebuilt host executable, relative 946get_prebuilt_host_exec () 947{ 948 local PREFIX EXE 949 PREFIX=$(get_prebuilt_install_prefix $2) 950 EXE=$(get_prebuilt_host_exe_ext) 951 echo "$PREFIX/bin/$1$EXE" 952} 953 954# Return the name of a given host executable 955# $1: executable base name 956# Out: executable name, with optional suffix (e.g. .exe for windows) 957get_host_exec_name () 958{ 959 local EXE=$(get_prebuilt_host_exe_ext) 960 echo "$1$EXE" 961} 962 963# Return the directory where host-specific binaries are installed. 964# $1: target root NDK directory 965get_host_install () 966{ 967 echo "$1/$(get_prebuilt_install_prefix)" 968} 969 970# Set the toolchain target NDK location. 971# this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX 972# $1: target NDK path 973# $2: toolchain name 974set_toolchain_ndk () 975{ 976 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 977 log "Using toolchain path: $TOOLCHAIN_PATH" 978 979 TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET 980 log "Using toolchain prefix: $TOOLCHAIN_PREFIX" 981} 982 983# Check that a toolchain is properly installed at a target NDK location 984# 985# $1: target root NDK directory 986# $2: toolchain name 987# 988check_toolchain_install () 989{ 990 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 991 if [ ! -d "$TOOLCHAIN_PATH" ] ; then 992 echo "ERROR: Cannot find directory '$TOOLCHAIN_PATH'!" 993 echo " Toolchain '$2' not installed in '$NDK_DIR'!" 994 echo " Ensure that the toolchain has been installed there before." 995 exit 1 996 fi 997 998 set_toolchain_ndk $1 $2 999} 1000 1001# $1: toolchain source directory 1002check_toolchain_src_dir () 1003{ 1004 local SRC_DIR="$1" 1005 if [ -z "$SRC_DIR" ]; then 1006 echo "ERROR: Please provide the path to the toolchain source tree. See --help" 1007 exit 1 1008 fi 1009 1010 if [ ! -d "$SRC_DIR" ]; then 1011 echo "ERROR: Not a directory: '$SRC_DIR'" 1012 exit 1 1013 fi 1014 1015 if [ ! -f "$SRC_DIR/build/configure" -o ! -d "$SRC_DIR/gcc" ]; then 1016 echo "ERROR: Either the file $SRC_DIR/build/configure or" 1017 echo " the directory $SRC_DIR/gcc does not exist." 1018 echo "This is not the top of a toolchain tree: $SRC_DIR" 1019 echo "You must give the path to a copy of the toolchain source directories" 1020 echo "created by 'download-toolchain-sources.sh." 1021 exit 1 1022 fi 1023} 1024 1025# 1026# The NDK_TMPDIR variable is used to specify a root temporary directory 1027# when invoking toolchain build scripts. If it is not defined, we will 1028# create one here, and export the value to ensure that any scripts we 1029# call after that use the same one. 1030# 1031if [ -z "$NDK_TMPDIR" ]; then 1032 NDK_TMPDIR=/tmp/ndk-$USER/tmp/build-$$ 1033 mkdir -p $NDK_TMPDIR 1034 if [ $? != 0 ]; then 1035 echo "ERROR: Could not create NDK_TMPDIR: $NDK_TMPDIR" 1036 exit 1 1037 fi 1038 export NDK_TMPDIR 1039fi 1040 1041# Define HOST_TAG32, as the 32-bit version of HOST_TAG 1042# We do this by replacing an -x86_64 suffix by -x86 1043HOST_TAG32=$HOST_TAG 1044case $HOST_TAG32 in 1045 *-x86_64) 1046 HOST_TAG32=${HOST_TAG%%_64} 1047 ;; 1048esac 1049