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