prebuilt-common.sh revision ad1afc5e66ab40201947a3178eba975515b0d73c
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 738parse_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 801get_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 823get_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 835convert_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 857get_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 872get_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 885get_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? 892get_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# 907get_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 916get_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 928get_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 941get_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) 952get_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 960get_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 969set_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# 983check_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 996check_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# 1023if [ -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 1031fi 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 1035HOST_TAG32=$HOST_TAG 1036case $HOST_TAG32 in 1037 *-x86_64) 1038 HOST_TAG32=${HOST_TAG%%_64} 1039 ;; 1040esac 1041