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 # Warn about /bin/sh ins't bash. 21 if [ -z "$BASH_VERSION" ] ; then 22 echo "WARNING: The shell running this script isn't bash. Although we try to avoid bashism in scripts, things can happen." 23 fi 24 25 NDK_BUILDTOOLS_ABSPATH=$(cd $NDK_BUILDTOOLS_PATH && pwd) 26 27 . $NDK_BUILDTOOLS_PATH/ndk-common.sh 28 . $NDK_BUILDTOOLS_PATH/dev-defaults.sh 29 30 # Binaries built by new linux host toolchain "prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" 31 # may contain functions missing from server runs very old libc.so. Define __USE_OLD_LINUX_HOST_GCC=yes 32 # to use the original "prebuilts/tools/gcc-sdk" with glibc2.7 sysroot 33 __USE_OLD_LINUX_HOST_GCC=yes 34 35 #==================================================== 36 # 37 # UTILITY FUNCTIONS 38 # 39 #==================================================== 40 41 # Return the maximum length of a series of strings 42 # 43 # Usage: len=`max_length <string1> <string2> ...` 44 # 45 max_length () 46 { 47 echo "$@" | tr ' ' '\n' | awk 'BEGIN {max=0} {len=length($1); if (len > max) max=len} END {print max}' 48 } 49 50 # Translate dashes to underscores 51 # Usage: str=`dashes_to_underscores <values>` 52 dashes_to_underscores () 53 { 54 echo "$@" | tr '-' '_' 55 } 56 57 # Translate underscores to dashes 58 # Usage: str=`underscores_to_dashes <values>` 59 underscores_to_dashes () 60 { 61 echo "$@" | tr '_' '-' 62 } 63 64 # Translate commas to spaces 65 # Usage: str=`commas_to_spaces <list>` 66 commas_to_spaces () 67 { 68 echo "$@" | tr ',' ' ' 69 } 70 71 # Translate spaces to commas 72 # Usage: list=`spaces_to_commas <string>` 73 spaces_to_commas () 74 { 75 echo "$@" | tr ' ' ',' 76 } 77 78 # Remove trailing path of a path 79 # $1: path 80 remove_trailing_slash () { 81 echo ${1%%/} 82 } 83 84 # Reverse a file path directory 85 # foo -> . 86 # foo/bar -> .. 87 # foo/bar/zoo -> ../.. 88 reverse_path () 89 { 90 local path cur item 91 path=${1%%/} # remove trailing slash 92 cur="." 93 if [ "$path" != "." ] ; then 94 for item in $(echo "$path" | tr '/' ' '); do 95 cur="../$cur" 96 done 97 fi 98 echo ${cur%%/.} 99 } 100 101 # test_reverse_path () 102 # { 103 # rr=`reverse_path $1` 104 # if [ "$rr" != "$2" ] ; then 105 # echo "ERROR: reverse_path '$1' -> '$rr' (expected '$2')" 106 # fi 107 # } 108 # 109 # test_reverse_path . . 110 # test_reverse_path ./ . 111 # test_reverse_path foo .. 112 # test_reverse_path foo/ .. 113 # test_reverse_path foo/bar ../.. 114 # test_reverse_path foo/bar/ ../.. 115 # test_reverse_path foo/bar/zoo ../../.. 116 # test_reverse_path foo/bar/zoo/ ../../.. 117 118 # Sort a space-separated list and remove duplicates 119 # $1+: slist 120 # Output: new slist 121 sort_uniq () 122 { 123 local RET 124 RET=$(echo "$@" | tr ' ' '\n' | sort -u) 125 echo $RET 126 } 127 128 # Return the list of all regular files under a given directory 129 # $1: Directory path 130 # Output: list of files, relative to $1 131 list_files_under () 132 { 133 if [ -d "$1" ]; then 134 (cd $1 && find . -type f | sed -e "s!./!!" | sort -u) 135 else 136 echo "" 137 fi 138 } 139 140 # Returns all words in text that do not match any of the pattern 141 # $1: pattern 142 # $2: text 143 filter_out () 144 { 145 local PATTERN="$1" 146 local TEXT="$2" 147 for pat in $PATTERN; do 148 pat=$"${pat/\//\\/}" 149 TEXT=$(echo $TEXT | sed -e 's/'$pat' //g' -e 's/'$pat'$//g') 150 done 151 echo $TEXT 152 } 153 154 # Assign a value to a variable 155 # $1: Variable name 156 # $2: Value 157 var_assign () 158 { 159 eval $1=\"$2\" 160 } 161 162 #==================================================== 163 # 164 # OPTION PROCESSING 165 # 166 #==================================================== 167 168 # We recognize the following option formats: 169 # 170 # -f 171 # --flag 172 # 173 # -s<value> 174 # --setting=<value> 175 # 176 177 # NOTE: We translate '-' into '_' when storing the options in global variables 178 # 179 180 OPTIONS="" 181 OPTION_FLAGS="" 182 OPTION_SETTINGS="" 183 184 # Set a given option attribute 185 # $1: option name 186 # $2: option attribute 187 # $3: attribute value 188 # 189 option_set_attr () 190 { 191 eval OPTIONS_$1_$2=\"$3\" 192 } 193 194 # Get a given option attribute 195 # $1: option name 196 # $2: option attribute 197 # 198 option_get_attr () 199 { 200 echo `var_value OPTIONS_$1_$2` 201 } 202 203 # Register a new option 204 # $1: option 205 # $2: small abstract for the option 206 # $3: optional. default value 207 # 208 register_option_internal () 209 { 210 optlabel= 211 optname= 212 optvalue= 213 opttype= 214 while [ -n "1" ] ; do 215 # Check for something like --setting=<value> 216 echo "$1" | grep -q -E -e '^--[^=]+=<.+>$' 217 if [ $? = 0 ] ; then 218 optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'` 219 optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'` 220 opttype="long_setting" 221 break 222 fi 223 224 # Check for something like --flag 225 echo "$1" | grep -q -E -e '^--[^=]+$' 226 if [ $? = 0 ] ; then 227 optlabel="$1" 228 opttype="long_flag" 229 break 230 fi 231 232 # Check for something like -f<value> 233 echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$' 234 if [ $? = 0 ] ; then 235 optlabel=`expr -- "$1" : '\(-.\).*'` 236 optvalue=`expr -- "$1" : '-.\(<.+>\)'` 237 opttype="short_setting" 238 break 239 fi 240 241 # Check for something like -f 242 echo "$1" | grep -q -E -e '^-.$' 243 if [ $? = 0 ] ; then 244 optlabel="$1" 245 opttype="short_flag" 246 break 247 fi 248 249 echo "ERROR: Invalid option format: $1" 250 echo " Check register_option call" 251 exit 1 252 done 253 254 log "new option: type='$opttype' name='$optlabel' value='$optvalue'" 255 256 optname=`dashes_to_underscores $optlabel` 257 OPTIONS="$OPTIONS $optname" 258 OPTIONS_TEXT="$OPTIONS_TEXT $1" 259 option_set_attr $optname label "$optlabel" 260 option_set_attr $optname otype "$opttype" 261 option_set_attr $optname value "$optvalue" 262 option_set_attr $optname text "$1" 263 option_set_attr $optname abstract "$2" 264 option_set_attr $optname default "$3" 265 } 266 267 # Register a new option with a function callback. 268 # 269 # $1: option 270 # $2: name of function that will be called when the option is parsed 271 # $3: small abstract for the option 272 # $4: optional. default value 273 # 274 register_option () 275 { 276 local optname optvalue opttype optlabel 277 register_option_internal "$1" "$3" "$4" 278 option_set_attr $optname funcname "$2" 279 } 280 281 # Register a new option with a variable store 282 # 283 # $1: option 284 # $2: name of variable that will be set by this option 285 # $3: small abstract for the option 286 # 287 # NOTE: The current value of $2 is used as the default 288 # 289 register_var_option () 290 { 291 local optname optvalue opttype optlabel 292 register_option_internal "$1" "$3" "`var_value $2`" 293 option_set_attr $optname varname "$2" 294 } 295 296 297 MINGW=no 298 DARWIN=no 299 do_mingw_option () 300 { 301 if [ "$DARWIN" = "yes" ]; then 302 echo "Can not have both --mingw and --darwin" 303 exit 1 304 fi 305 MINGW=yes; 306 } 307 do_darwin_option () 308 { 309 if [ "$MINGW" = "yes" ]; then 310 echo "Can not have both --mingw and --darwin" 311 exit 1 312 fi 313 DARWIN=yes; 314 } 315 316 register_canadian_option () 317 { 318 if [ "$HOST_OS" = "linux" ] ; then 319 register_option "--mingw" do_mingw_option "Generate windows binaries on Linux." 320 register_option "--darwin" do_darwin_option "Generate darwin binaries on Linux." 321 fi 322 } 323 324 TRY64=no 325 do_try64_option () { TRY64=yes; } 326 327 register_try64_option () 328 { 329 register_option "--try-64" do_try64_option "Generate 64-bit binaries." 330 } 331 332 333 register_jobs_option () 334 { 335 NUM_JOBS=$BUILD_NUM_CPUS 336 register_var_option "-j<number>" NUM_JOBS "Use <number> parallel build jobs" 337 } 338 339 # Print the help, including a list of registered options for this program 340 # Note: Assumes PROGRAM_PARAMETERS and PROGRAM_DESCRIPTION exist and 341 # correspond to the parameters list and the program description 342 # 343 print_help () 344 { 345 local opt text abstract default 346 347 echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS" 348 echo "" 349 if [ -n "$PROGRAM_DESCRIPTION" ] ; then 350 echo "$PROGRAM_DESCRIPTION" 351 echo "" 352 fi 353 echo "Valid options (defaults are in brackets):" 354 echo "" 355 356 maxw=`max_length "$OPTIONS_TEXT"` 357 AWK_SCRIPT=`echo "{ printf \"%-${maxw}s\", \\$1 }"` 358 for opt in $OPTIONS; do 359 text=`option_get_attr $opt text | awk "$AWK_SCRIPT"` 360 abstract=`option_get_attr $opt abstract` 361 default=`option_get_attr $opt default` 362 if [ -n "$default" ] ; then 363 echo " $text $abstract [$default]" 364 else 365 echo " $text $abstract" 366 fi 367 done 368 echo "" 369 } 370 371 option_panic_no_args () 372 { 373 echo "ERROR: Option '$1' does not take arguments. See --help for usage." 374 exit 1 375 } 376 377 option_panic_missing_arg () 378 { 379 echo "ERROR: Option '$1' requires an argument. See --help for usage." 380 exit 1 381 } 382 383 extract_parameters () 384 { 385 local opt optname otype value name fin funcname 386 PARAMETERS="" 387 while [ -n "$1" ] ; do 388 # If the parameter does not begin with a dash 389 # it is not an option. 390 param=`expr -- "$1" : '^\([^\-].*\)$'` 391 if [ -n "$param" ] ; then 392 if [ -z "$PARAMETERS" ] ; then 393 PARAMETERS="$1" 394 else 395 PARAMETERS="$PARAMETERS $1" 396 fi 397 shift 398 continue 399 fi 400 401 while [ -n "1" ] ; do 402 # Try to match a long setting, i.e. --option=value 403 opt=`expr -- "$1" : '^\(--[^=]*\)=.*$'` 404 if [ -n "$opt" ] ; then 405 otype="long_setting" 406 value=`expr -- "$1" : '^--[^=]*=\(.*\)$'` 407 break 408 fi 409 410 # Try to match a long flag, i.e. --option 411 opt=`expr -- "$1" : '^\(--.*\)$'` 412 if [ -n "$opt" ] ; then 413 otype="long_flag" 414 value="yes" 415 break 416 fi 417 418 # Try to match a short setting, i.e. -o<value> 419 opt=`expr -- "$1" : '^\(-[A-Za-z0-9]\)..*$'` 420 if [ -n "$opt" ] ; then 421 otype="short_setting" 422 value=`expr -- "$1" : '^-.\(.*\)$'` 423 break 424 fi 425 426 # Try to match a short flag, i.e. -o 427 opt=`expr -- "$1" : '^\(-.\)$'` 428 if [ -n "$opt" ] ; then 429 otype="short_flag" 430 value="yes" 431 break 432 fi 433 434 echo "ERROR: Unknown option '$1'. Use --help for list of valid values." 435 exit 1 436 done 437 438 #echo "Found opt='$opt' otype='$otype' value='$value'" 439 440 name=`dashes_to_underscores $opt` 441 found=0 442 for xopt in $OPTIONS; do 443 if [ "$name" != "$xopt" ] ; then 444 continue 445 fi 446 # Check that the type is correct here 447 # 448 # This also allows us to handle -o <value> as -o<value> 449 # 450 xotype=`option_get_attr $name otype` 451 if [ "$otype" != "$xotype" ] ; then 452 case "$xotype" in 453 "short_flag") 454 option_panic_no_args $opt 455 ;; 456 "short_setting") 457 if [ -z "$2" ] ; then 458 option_panic_missing_arg $opt 459 fi 460 value="$2" 461 shift 462 ;; 463 "long_flag") 464 option_panic_no_args $opt 465 ;; 466 "long_setting") 467 option_panic_missing_arg $opt 468 ;; 469 esac 470 fi 471 found=1 472 break 473 break 474 done 475 if [ "$found" = "0" ] ; then 476 echo "ERROR: Unknown option '$opt'. See --help for usage." 477 exit 1 478 fi 479 # Set variable or launch option-specific function. 480 varname=`option_get_attr $name varname` 481 if [ -n "$varname" ] ; then 482 eval ${varname}=\"$value\" 483 else 484 eval `option_get_attr $name funcname` \"$value\" 485 fi 486 shift 487 done 488 } 489 490 do_option_help () 491 { 492 print_help 493 exit 0 494 } 495 496 VERBOSE=no 497 VERBOSE2=no 498 do_option_verbose () 499 { 500 if [ $VERBOSE = "yes" ] ; then 501 VERBOSE2=yes 502 else 503 VERBOSE=yes 504 fi 505 } 506 507 register_option "--help" do_option_help "Print this help." 508 register_option "--verbose" do_option_verbose "Enable verbose mode." 509 510 #==================================================== 511 # 512 # TOOLCHAIN AND ABI PROCESSING 513 # 514 #==================================================== 515 516 # Determine optional variable value 517 # $1: final variable name 518 # $2: option variable name 519 # $3: small description for the option 520 fix_option () 521 { 522 if [ -n "$2" ] ; then 523 eval $1="$2" 524 log "Using specific $3: $2" 525 else 526 log "Using default $3: `var_value $1`" 527 fi 528 } 529 530 531 # If SYSROOT is empty, check that $1/$2 contains a sysroot 532 # and set the variable to it. 533 # 534 # $1: sysroot path 535 # $2: platform/arch suffix 536 check_sysroot () 537 { 538 if [ -z "$SYSROOT" ] ; then 539 log "Probing directory for sysroot: $1/$2" 540 if [ -d $1/$2 ] ; then 541 SYSROOT=$1/$2 542 fi 543 fi 544 } 545 546 # Determine sysroot 547 # $1: Option value (or empty) 548 # 549 fix_sysroot () 550 { 551 if [ -n "$1" ] ; then 552 eval SYSROOT="$1" 553 log "Using specified sysroot: $1" 554 else 555 SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH 556 SYSROOT= 557 check_sysroot $NDK_DIR/platforms $SYSROOT_SUFFIX 558 check_sysroot $ANDROID_NDK_ROOT/platforms $SYSROOT_SUFFIX 559 check_sysroot `dirname $ANDROID_NDK_ROOT`/development/ndk/platforms $SYSROOT_SUFFIX 560 561 if [ -z "$SYSROOT" ] ; then 562 echo "ERROR: Could not find NDK sysroot path for $SYSROOT_SUFFIX." 563 echo " Use --sysroot=<path> to specify one." 564 exit 1 565 fi 566 fi 567 568 if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then 569 echo "ERROR: Invalid sysroot path: $SYSROOT" 570 echo " Use --sysroot=<path> to indicate a valid one." 571 exit 1 572 fi 573 } 574 575 # Check for the availability of a compatibility SDK in Darwin 576 # this can be used to generate binaries compatible with either Tiger or 577 # Leopard. 578 # 579 # $1: SDK root path 580 # $2: Optional MacOS X minimum version (e.g. 10.5) 581 DARWIN_MINVER=10.6 582 check_darwin_sdk () 583 { 584 local MACSDK="$1" 585 local MINVER=$2 586 587 if [ -z "$MINVER" ] ; then 588 # expect SDK root path ended up with either MacOSX##.#.sdk or MacOSX##.#u.sdk 589 MINVER=${MACSDK##*MacOSX} 590 MINVER=${MINVER%%.sdk*} 591 if [ "$MINVER" = "10.4u" ]; then 592 MINVER=10.4 593 fi 594 fi 595 if [ -d "$MACSDK" ] ; then 596 HOST_CFLAGS=$HOST_CFLAGS" -isysroot $MACSDK -mmacosx-version-min=$MINVER -DMAXOSX_DEPLOYEMENT_TARGET=$MINVER" 597 HOST_LDFLAGS=$HOST_LDFLAGS" -Wl,-syslibroot,$MACSDK -mmacosx-version-min=$MINVER" 598 DARWIN_MINVER=$MINVER 599 return 0 # success 600 fi 601 return 1 602 } 603 604 # Probe Darwin SDK in specified diectory $DARWIN_SYSROOT, or 605 # /Developer/SDKs/MacOSX10.6.sdk 606 # 607 probe_darwin_sdk () 608 { 609 if [ -n "$DARWIN_SYSROOT" ]; then 610 if check_darwin_sdk "$DARWIN_SYSROOT"; then 611 log "Use darwin sysroot $DARWIN_SYSROOT" 612 else 613 echo "darwin sysroot $DARWIN_SYSROOT is not valid" 614 exit 1 615 fi 616 elif check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk 10.6; then 617 log "Generating Snow Leopard-compatible binaries!" 618 else 619 local version=`sw_vers -productVersion` 620 log "Generating $version-compatible binaries!" 621 fi 622 } 623 624 handle_canadian_build () 625 { 626 HOST_EXE= 627 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then 628 case $HOST_TAG in 629 linux-*) 630 ;; 631 *) 632 echo "ERROR: Can only enable --mingw or --darwin on Linux platforms !" 633 exit 1 634 ;; 635 esac 636 if [ "$MINGW" = "yes" ] ; then 637 # NOTE: Use x86_64-pc-mingw32msvc or i586-pc-mingw32msvc because wrappers are generated 638 # using these names 639 if [ "$TRY64" = "yes" ]; then 640 ABI_CONFIGURE_HOST=x86_64-pc-mingw32msvc 641 HOST_TAG=windows-x86_64 642 else 643 ABI_CONFIGURE_HOST=i586-pc-mingw32msvc 644 HOST_TAG=windows 645 fi 646 HOST_OS=windows 647 HOST_EXE=.exe 648 else 649 if [ "$TRY64" = "yes" ]; then 650 ABI_CONFIGURE_HOST=x86_64-apple-darwin 651 HOST_TAG=darwin-x86_64 652 else 653 ABI_CONFIGURE_HOST=i686-apple-darwin 654 HOST_TAG=darwin-x86 655 fi 656 HOST_OS=darwin 657 fi 658 fi 659 } 660 661 # Find mingw toolchain 662 # 663 # Set MINGW_GCC to the found mingw toolchain 664 # 665 find_mingw_toolchain () 666 { 667 # IMPORTANT NOTE: binutils 2.21 requires a cross toolchain named 668 # i585-pc-mingw32msvc-gcc, or it will fail its configure step late 669 # in the toolchain build. Note that binutils 2.19 can build properly 670 # with i585-mingw32mvsc-gcc, which is the name used by the 'mingw32' 671 # toolchain install on Debian/Ubuntu. 672 # 673 # To solve this dilemma, we create a wrapper toolchain named 674 # i586-pc-mingw32msvc-gcc that really calls i586-mingw32msvc-gcc, 675 # this works with all versions of binutils. 676 # 677 # We apply the same logic to the 64-bit Windows cross-toolchain 678 # 679 # Fedora note: On Fedora it's x86_64-w64-mingw32- or i686-w64-mingw32- 680 # On older Fedora it's 32-bit only and called i686-pc-mingw32- 681 # so we just add more prefixes to the list to check. 682 if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then 683 BINPREFIX=x86_64-pc-mingw32msvc- 684 BINPREFIXLST="x86_64-pc-mingw32msvc- x86_64-w64-mingw32- amd64-mingw32msvc-" 685 DEBIAN_NAME=mingw64 686 else 687 # we are trying 32 bit anyway, so forcing it to avoid build issues 688 force_32bit_binaries 689 BINPREFIX=i586-pc-mingw32msvc- 690 BINPREFIXLST="i586-pc-mingw32msvc- i686-pc-mingw32- i586-mingw32msvc- i686-w64-mingw32-" 691 DEBIAN_NAME=mingw32 692 fi 693 694 # Scan $BINPREFIXLST list to find installed mingw toolchain. It will be 695 # wrapped later with $BINPREFIX. 696 for i in $BINPREFIXLST; do 697 find_program MINGW_GCC ${i}gcc 698 if [ -n "$MINGW_GCC" ]; then 699 dump "Found mingw toolchain: $MINGW_GCC" 700 break 701 fi 702 done 703 } 704 705 # Check there is a working cross-toolchain installed. 706 # 707 # $1: install directory for mingw/darwin wrapper toolchain 708 # 709 prepare_canadian_toolchain () 710 { 711 if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then 712 return 713 fi 714 CROSS_GCC= 715 if [ "$MINGW" = "yes" ]; then 716 find_mingw_toolchain 717 if [ -z "$MINGW_GCC" ]; then 718 echo "ERROR: Could not find in your PATH any of:" 719 for i in $BINPREFIXLST; do echo " ${i}gcc"; done 720 echo "Please install the corresponding cross-toolchain and re-run this script" 721 echo "TIP: On Debian or Ubuntu, try: sudo apt-get install $DEBIAN_NAME" 722 exit 1 723 fi 724 CROSS_GCC=$MINGW_GCC 725 else 726 if [ -z "$DARWIN_TOOLCHAIN" ]; then 727 echo "Please set DARWIN_TOOLCHAIN to darwin cross-toolchain" 728 exit 1 729 fi 730 if [ ! -f "${DARWIN_TOOLCHAIN}-gcc" ]; then 731 echo "darwin cross-toolchain $DARWIN_TOOLCHAIN-gcc doesn't exist" 732 exit 1 733 fi 734 if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then 735 BINPREFIX=x86_64-apple-darwin- 736 DEBIAN_NAME=darwin64 737 HOST_CFLAGS=$HOST_CFLAGS" -m64" 738 else 739 force_32bit_binaries 740 BINPREFIX=i686-apple-darwin- 741 DEBIAN_NAME=darwin32 742 HOST_CFLAGS=$HOST_CFLAGS" -m32" 743 fi 744 CROSS_GCC=${DARWIN_TOOLCHAIN}-gcc 745 probe_darwin_sdk 746 fi 747 748 # Create a wrapper toolchain, and prepend its dir to our PATH 749 CROSS_WRAP_DIR="$1"/$DEBIAN_NAME-wrapper 750 rm -rf "$CROSS_WRAP_DIR" 751 mkdir -p "$CROSS_WRAP_DIR" 752 753 if [ "$DARWIN" = "yes" ] ; then 754 cat > "$CROSS_WRAP_DIR/sw_vers" <<EOF 755 #!/bin/sh 756 # Tiny utility for the real sw_vers some Makefiles need 757 case \$1 in 758 -productVersion) 759 echo $DARWIN_MINVER 760 ;; 761 *) 762 echo "ERROR: Unknown switch \$1" 763 exit 1 764 esac 765 EOF 766 chmod 0755 "$CROSS_WRAP_DIR/sw_vers" 767 fi 768 769 DST_PREFIX=${CROSS_GCC%gcc} 770 if [ "$NDK_CCACHE" ]; then 771 DST_PREFIX="$NDK_CCACHE $DST_PREFIX" 772 fi 773 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=$BINPREFIX --dst-prefix="$DST_PREFIX" "$CROSS_WRAP_DIR" \ 774 --cflags="$HOST_CFLAGS" --cxxflags="$HOST_CFLAGS" --ldflags="$HOST_LDFLAGS" 775 # generate wrappers for BUILD toolchain 776 # this is required for mingw/darwin build to avoid tools canadian cross configuration issues 777 # 32-bit BUILD toolchain 778 if [ "$__USE_OLD_LINUX_HOST_GCC" = "yes" ]; then 779 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" 780 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-linux-gnu- \ 781 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-" "$CROSS_WRAP_DIR" 782 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-pc-linux-gnu- \ 783 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-" "$CROSS_WRAP_DIR" 784 # 64-bit BUILD toolchain. libbfd is still built in 32-bit. Use gcc-sdk instead 785 # of x86_64-linux-glibc2.7-4.6 which is a 64-bit-only tool 786 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/tools/gcc-sdk" 787 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-linux-gnu- \ 788 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/" "$CROSS_WRAP_DIR" 789 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-pc-linux-gnu- \ 790 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/" "$CROSS_WRAP_DIR" 791 fail_panic "Could not create $DEBIAN_NAME wrapper toolchain in $CROSS_WRAP_DIR" 792 else 793 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" 794 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-linux-gnu- \ 795 --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \ 796 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 797 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-pc-linux-gnu- \ 798 --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \ 799 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 800 # 64-bit BUILD toolchain. libbfd is still built in 32-bit. 801 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-linux-gnu- \ 802 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 803 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-pc-linux-gnu- \ 804 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 805 fail_panic "Could not create $DEBIAN_NAME wrapper toolchain in $CROSS_WRAP_DIR" 806 fi 807 808 export PATH=$CROSS_WRAP_DIR:$PATH 809 dump "Using $DEBIAN_NAME wrapper: $CROSS_WRAP_DIR/${BINPREFIX}gcc" 810 } 811 812 handle_host () 813 { 814 if [ "$TRY64" != "yes" ]; then 815 force_32bit_binaries # to modify HOST_TAG and others 816 HOST_BITS=32 817 fi 818 handle_canadian_build 819 } 820 821 setup_ccache () 822 { 823 # Support for ccache compilation 824 # We can't use this here when building Windows/darwin binaries on Linux with 825 # binutils 2.21, because defining CC/CXX in the environment makes the 826 # configure script fail later 827 # 828 if [ "$NDK_CCACHE" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then 829 NDK_CCACHE_CC=$CC 830 NDK_CCACHE_CXX=$CXX 831 # Unfortunately, we can just do CC="$NDK_CCACHE $CC" because some 832 # configure scripts are not capable of dealing with this properly 833 # E.g. the ones used to rebuild the GCC toolchain from scratch. 834 # So instead, use a wrapper script 835 CC=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-gcc.sh 836 CXX=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-g++.sh 837 export NDK_CCACHE_CC NDK_CCACHE_CXX 838 log "Using ccache compilation" 839 log "NDK_CCACHE_CC=$NDK_CCACHE_CC" 840 log "NDK_CCACHE_CXX=$NDK_CCACHE_CXX" 841 fi 842 } 843 844 prepare_common_build () 845 { 846 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then 847 if [ "$TRY64" = "yes" ]; then 848 HOST_BITS=64 849 else 850 HOST_BITS=32 851 fi 852 if [ "$MINGW" = "yes" ]; then 853 log "Generating $HOST_BITS-bit Windows binaries" 854 else 855 log "Generating $HOST_BITS-bit Darwin binaries" 856 fi 857 # Do *not* set CC and CXX when building the Windows/Darwin binaries in canadian build. 858 # Otherwise, the GCC configure/build script will mess that Canadian cross 859 # build in weird ways. Instead we rely on the toolchain detected or generated 860 # previously in prepare_canadian_toolchain. 861 unset CC CXX 862 return 863 fi 864 865 # On Linux, detect our legacy-compatible toolchain when in the Android 866 # source tree, and use it to force the generation of glibc-2.7 compatible 867 # binaries. 868 # 869 # We only do this if the CC variable is not defined to a given value 870 if [ -z "$CC" ]; then 871 LEGACY_TOOLCHAIN_DIR= 872 if [ "$HOST_OS" = "linux" ]; then 873 if [ "$__USE_OLD_LINUX_HOST_GCC" = "yes" ]; then 874 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/tools/gcc-sdk" 875 LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/" 876 else 877 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/bin" 878 LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/x86_64-linux-" 879 fi 880 elif [ "$HOST_OS" = "darwin" ]; then 881 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1/bin" 882 LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/i686-apple-darwin10-" 883 fi 884 if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then 885 log "Forcing generation of $HOST_OS binaries with legacy toolchain" 886 CC="${LEGACY_TOOLCHAIN_PREFIX}gcc" 887 CXX="${LEGACY_TOOLCHAIN_PREFIX}g++" 888 fi 889 fi 890 891 CC=${CC:-gcc} 892 CXX=${CXX:-g++} 893 STRIP=${STRIP:-strip} 894 case $HOST_TAG in 895 darwin-*) 896 probe_darwin_sdk 897 ;; 898 esac 899 900 # Force generation of 32-bit binaries on 64-bit systems. 901 # We used to test the value of $HOST_TAG for *-x86_64, but this is 902 # not sufficient on certain systems. 903 # 904 # For example, Snow Leopard can be booted with a 32-bit kernel, running 905 # a 64-bit userland, with a compiler that generates 64-bit binaries by 906 # default *even* though "gcc -v" will report --target=i686-apple-darwin10! 907 # 908 # So know, simply probe for the size of void* by performing a small runtime 909 # compilation test. 910 # 911 cat > $TMPC <<EOF 912 /* this test should fail if the compiler generates 64-bit machine code */ 913 int test_array[1-2*(sizeof(void*) != 4)]; 914 EOF 915 log_n "Checking whether the compiler generates 32-bit binaries..." 916 log2 $CC $HOST_CFLAGS -c -o $TMPO $TMPC 917 $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1 918 if [ $? != 0 ] ; then 919 log "no" 920 if [ "$TRY64" != "yes" ]; then 921 # NOTE: We need to modify the definitions of CC and CXX directly 922 # here. Just changing the value of CFLAGS / HOST_CFLAGS 923 # will not work well with the GCC toolchain scripts. 924 CC="$CC -m32" 925 CXX="$CXX -m32" 926 fi 927 else 928 log "yes" 929 if [ "$TRY64" = "yes" ]; then 930 CC="$CC -m64" 931 CXX="$CXX -m64" 932 fi 933 fi 934 935 if [ "$TRY64" = "yes" ]; then 936 HOST_BITS=64 937 else 938 force_32bit_binaries # to modify HOST_TAG and others 939 HOST_BITS=32 940 fi 941 } 942 943 prepare_host_build () 944 { 945 prepare_common_build 946 947 # Now deal with mingw or darwin 948 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then 949 handle_canadian_build 950 CC=$ABI_CONFIGURE_HOST-gcc 951 CXX=$ABI_CONFIGURE_HOST-g++ 952 CPP=$ABI_CONFIGURE_HOST-cpp 953 LD=$ABI_CONFIGURE_HOST-ld 954 AR=$ABI_CONFIGURE_HOST-ar 955 AS=$ABI_CONFIGURE_HOST-as 956 RANLIB=$ABI_CONFIGURE_HOST-ranlib 957 STRIP=$ABI_CONFIGURE_HOST-strip 958 export CC CXX CPP LD AR AS RANLIB STRIP 959 fi 960 961 setup_ccache 962 } 963 964 prepare_abi_configure_build () 965 { 966 # detect build tag 967 case $HOST_TAG in 968 linux-x86) 969 ABI_CONFIGURE_BUILD=i386-linux-gnu 970 ;; 971 linux-x86_64) 972 ABI_CONFIGURE_BUILD=x86_64-linux-gnu 973 ;; 974 darwin-x86) 975 ABI_CONFIGURE_BUILD=i686-apple-darwin 976 ;; 977 darwin-x86_64) 978 ABI_CONFIGURE_BUILD=x86_64-apple-darwin 979 ;; 980 windows) 981 ABI_CONFIGURE_BUILD=i686-pc-cygwin 982 ;; 983 *) 984 echo "ERROR: Unsupported HOST_TAG: $HOST_TAG" 985 echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh" 986 ;; 987 esac 988 } 989 990 prepare_target_build () 991 { 992 prepare_abi_configure_build 993 994 # By default, assume host == build 995 ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD" 996 997 prepare_common_build 998 HOST_GMP_ABI=$HOST_BITS 999 1000 # Now handle the --mingw/--darwin flag 1001 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then 1002 handle_canadian_build 1003 STRIP=$ABI_CONFIGURE_HOST-strip 1004 if [ "$MINGW" = "yes" ] ; then 1005 # It turns out that we need to undefine this to be able to 1006 # perform a canadian-cross build with mingw. Otherwise, the 1007 # GMP configure scripts will not be called with the right options 1008 HOST_GMP_ABI= 1009 fi 1010 fi 1011 1012 setup_ccache 1013 } 1014 1015 # $1: Toolchain name 1016 # 1017 parse_toolchain_name () 1018 { 1019 TOOLCHAIN=$1 1020 if [ -z "$TOOLCHAIN" ] ; then 1021 echo "ERROR: Missing toolchain name!" 1022 exit 1 1023 fi 1024 1025 ABI_CFLAGS_FOR_TARGET= 1026 ABI_CXXFLAGS_FOR_TARGET= 1027 1028 # Determine ABI based on toolchain name 1029 # 1030 case "$TOOLCHAIN" in 1031 arm-linux-androideabi-*) 1032 ARCH="arm" 1033 ABI="armeabi" 1034 ABI_CONFIGURE_TARGET="arm-linux-androideabi" 1035 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te" 1036 ;; 1037 arm-eabi-*) 1038 ARCH="arm" 1039 ABI="armeabi" 1040 ABI_CONFIGURE_TARGET="arm-eabi" 1041 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te --disable-gold --disable-libgomp" 1042 ;; 1043 aarch64-linux-android-*) 1044 ARCH="arm64" 1045 ABI="arm64-v8a" 1046 ABI_CONFIGURE_TARGET="aarch64-linux-android" 1047 # Note: --disable-gold because gold doesn't support aarch64 yet 1048 ABI_CONFIGURE_EXTRA_FLAGS="--disable-gold" 1049 ;; 1050 x86-*) 1051 ARCH="x86" 1052 ABI=$ARCH 1053 ABI_INSTALL_NAME="x86" 1054 ABI_CONFIGURE_TARGET="i686-linux-android" 1055 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1056 # You can't really build these separately at the moment. 1057 ABI_CFLAGS_FOR_TARGET="-fPIC" 1058 ;; 1059 x86_64-*) 1060 ARCH="x86_64" 1061 ABI=$ARCH 1062 ABI_INSTALL_NAME="x86_64" 1063 ABI_CONFIGURE_TARGET="x86_64-linux-android" 1064 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1065 # You can't really build these separately at the moment. 1066 ABI_CFLAGS_FOR_TARGET="-fPIC" 1067 ;; 1068 mipsel*) 1069 ARCH="mips" 1070 ABI=$ARCH 1071 ABI_INSTALL_NAME="mips" 1072 ABI_CONFIGURE_TARGET="mipsel-linux-android" 1073 # Set default to mips32 1074 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips32 -with-fp-32=xx --with-odd-spreg-32=no" 1075 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1076 # You can't really build these separately at the moment. 1077 # Add -fpic, because MIPS NDK will need to link .a into .so. 1078 ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic" 1079 ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic" 1080 # Add --disable-fixed-point to disable fixed-point support 1081 ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point" 1082 ;; 1083 mips64el*) 1084 ARCH="mips64" 1085 ABI=$ARCH 1086 ABI_INSTALL_NAME="mips64" 1087 ABI_CONFIGURE_TARGET="mips64el-linux-android" 1088 # Set default to mips64r6 1089 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips64r6" 1090 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1091 # You can't really build these separately at the moment. 1092 # Add -fpic, because MIPS NDK will need to link .a into .so. 1093 ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic" 1094 ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic" 1095 # Add --disable-fixed-point to disable fixed-point support 1096 ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point" 1097 ;; 1098 * ) 1099 echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|arm-eabi-*|x86-*|mipsel*|mips64el*)" 1100 echo "" 1101 print_help 1102 exit 1 1103 ;; 1104 esac 1105 1106 log "Targetting CPU: $ARCH" 1107 1108 GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'` 1109 log "Using GCC version: $GCC_VERSION" 1110 1111 # Determine --host value when building gdbserver 1112 1113 case "$TOOLCHAIN" in 1114 arm-*) 1115 GDBSERVER_HOST=arm-eabi-linux 1116 GDBSERVER_CFLAGS="-fno-short-enums" 1117 GDBSERVER_LDFLAGS= 1118 ;; 1119 aarch64-*) 1120 GDBSERVER_HOST=aarch64-eabi-linux 1121 GDBSERVER_CFLAGS="-fno-short-enums -DUAPI_HEADERS" 1122 GDBSERVER_LDFLAGS= 1123 ;; 1124 x86-*) 1125 GDBSERVER_HOST=i686-linux-android 1126 GDBSERVER_CFLAGS= 1127 GDBSERVER_LDFLAGS= 1128 ;; 1129 x86_64-*) 1130 GDBSERVER_HOST=x86_64-linux-android 1131 GDBSERVER_CFLAGS=-DUAPI_HEADERS 1132 GDBSERVER_LDFLAGS= 1133 ;; 1134 mipsel-*) 1135 GDBSERVER_HOST=mipsel-linux-android 1136 GDBSERVER_CFLAGS= 1137 GDBSERVER_LDFLAGS= 1138 ;; 1139 mips64el-*) 1140 GDBSERVER_HOST=mips64el-linux-android 1141 GDBSERVER_CFLAGS=-DUAPI_HEADERS 1142 GDBSERVER_LDFLAGS= 1143 ;; 1144 *) 1145 echo "Unknown TOOLCHAIN=$TOOLCHAIN" 1146 exit 1147 esac 1148 } 1149 1150 # Return the host "tag" used to identify prebuilt host binaries. 1151 # NOTE: Handles the case where '$MINGW = true' or '$DARWIN = true' 1152 # For now, valid values are: linux-x86, darwin-x86 and windows 1153 get_prebuilt_host_tag () 1154 { 1155 local RET=$HOST_TAG 1156 if [ "$MINGW" = "yes" ]; then 1157 if [ "$TRY64" = "no" ]; then 1158 RET=windows 1159 else 1160 RET=windows-x86_64 1161 fi 1162 fi 1163 if [ "$DARWIN" = "yes" ]; then 1164 RET=darwin-x86_64 # let the following handles 32-bit case 1165 fi 1166 case $RET in 1167 linux-x86_64) 1168 if [ "$TRY64" = "no" ]; then 1169 RET=linux-x86 1170 fi 1171 ;; 1172 darwin-x86_64) 1173 if [ "$TRY64" = "no" ]; then 1174 RET=darwin-x86 1175 fi 1176 ;; 1177 esac 1178 echo $RET 1179 } 1180 1181 # Return the executable suffix corresponding to host executables 1182 get_prebuilt_host_exe_ext () 1183 { 1184 if [ "$MINGW" = "yes" ]; then 1185 echo ".exe" 1186 else 1187 echo "" 1188 fi 1189 } 1190 1191 # Find all archs from $DEV_DIR/platforms or $NDK_DIR/platforms 1192 # Return: the list of found arch name 1193 find_ndk_archs () 1194 { 1195 local NDK_ROOT_DIR DEVDIR 1196 local RESULT FOUND_ARCHS 1197 1198 if [ ! -z "$NDK_DIR" ]; then 1199 NDK_ROOT_DIR=$NDK_DIR 1200 else 1201 NDK_ROOT_DIR=$ANDROID_NDK_ROOT 1202 fi 1203 1204 DEVDIR="$ANDROID_NDK_ROOT/../development/ndk" 1205 1206 # Check development directory first 1207 if [ -d $DEVDIR/platforms ]; then 1208 RESULT=$(ls $DEVDIR/platforms/android-* | grep "arch-") 1209 for arch in $RESULT; do 1210 arch=$(basename $arch | sed -e 's/^arch-//') 1211 FOUND_ARCHS="$FOUND_ARCHS $arch" 1212 done 1213 fi 1214 1215 # Check ndk directory 1216 if [ -z "$FOUND_ARCHS" ] && [ -d $NDK_ROOT_DIR/platforms ]; then 1217 RESULT=$(ls $NDK_ROOT_DIR/platforms/android-* | grep "arch-") 1218 for arch in $RESULT; do 1219 arch=$(basename $arch | sed -e 's/^arch-//') 1220 FOUND_ARCHS="$FOUND_ARCHS $arch" 1221 done 1222 fi 1223 1224 # If we cannot find any arch, set to default archs 1225 if [ -z "$FOUND_ARCHS" ]; then 1226 FOUND_ARCHS=$DEFAULT_ARCHS 1227 fi 1228 1229 echo "$(sort_uniq $FOUND_ARCHS)" 1230 } 1231 1232 # Find unknown archs from $NDK_DIR/platforms 1233 # Return: arch names not in ndk default archs 1234 find_ndk_unknown_archs() 1235 { 1236 local FOUND_ARCHS=$(find_ndk_archs) 1237 # TODO: arm64, x86_64 is here just to be found as known arch. 1238 # It can be removed as soon as it is added into $DEFAULT_ARCHS 1239 echo "$(filter_out "$DEFAULT_ARCHS arm64 x86_64 mips64" "$FOUND_ARCHS")" 1240 } 1241 1242 # Determine whether given arch is in unknown archs list 1243 # $1: arch 1244 # Return: yes or no 1245 arch_in_unknown_archs() 1246 { 1247 local UNKNOWN_ARCH=$(find_ndk_unknown_archs | grep $1) 1248 if [ -z "$UNKNOWN_ARCH" ]; then 1249 echo "no" 1250 else 1251 echo "yes" 1252 fi 1253 } 1254 1255 # Get library suffix for given ABI 1256 # $1: ABI 1257 # Return: .so or .bc 1258 get_lib_suffix_for_abi () 1259 { 1260 local ABI=$1 1261 if [ $(arch_in_unknown_archs $ABI) = "yes" ]; then 1262 echo ".bc" 1263 else 1264 echo ".so" 1265 fi 1266 } 1267 1268 # Convert an ABI name into an Architecture name 1269 # $1: ABI name 1270 # Result: Arch name 1271 convert_abi_to_arch () 1272 { 1273 local RET 1274 local ABI=$1 1275 case $ABI in 1276 armeabi|armeabi-v7a|armeabi-v7a-hard) 1277 RET=arm 1278 ;; 1279 x86|mips|x86_64|mips64) 1280 RET=$ABI 1281 ;; 1282 arm64-v8a) 1283 RET=arm64 1284 ;; 1285 *) 1286 if [ "$(arch_in_unknown_archs $ABI)" = "yes" ]; then 1287 RET=$ABI 1288 else 1289 >&2 echo "ERROR: Unsupported ABI name: $ABI, use one of: armeabi, armeabi-v7a, x86, mips, armeabi-v7a-hard, arm64-v8a, x86_64 or mips64" 1290 exit 1 1291 fi 1292 ;; 1293 esac 1294 echo "$RET" 1295 } 1296 1297 # Take architecture name as input, and output the list of corresponding ABIs 1298 # Inverse for convert_abi_to_arch 1299 # $1: ARCH name 1300 # Out: ABI names list (comma-separated) 1301 convert_arch_to_abi () 1302 { 1303 local RET 1304 local ARCH=$1 1305 case $ARCH in 1306 arm) 1307 RET=armeabi,armeabi-v7a,armeabi-v7a-hard 1308 ;; 1309 x86|x86_64|mips|mips64) 1310 RET=$ARCH 1311 ;; 1312 arm64) 1313 RET=arm64-v8a 1314 ;; 1315 *) 1316 if [ "$(arch_in_unknown_archs $ARCH)" = "yes" ]; then 1317 RET=$ARCH 1318 else 1319 >&2 echo "ERROR: Unsupported ARCH name: $ARCH, use one of: arm, x86, mips" 1320 exit 1 1321 fi 1322 ;; 1323 esac 1324 echo "$RET" 1325 } 1326 1327 # Take a list of architecture names as input, and output the list of corresponding ABIs 1328 # $1: ARCH names list (separated by spaces or commas) 1329 # Out: ABI names list (comma-separated) 1330 convert_archs_to_abis () 1331 { 1332 local RET 1333 for ARCH in $(commas_to_spaces $@); do 1334 ABI=$(convert_arch_to_abi $ARCH) 1335 if [ -n "$ABI" ]; then 1336 if [ -n "$RET" ]; then 1337 RET=$RET",$ABI" 1338 else 1339 RET=$ABI 1340 fi 1341 else # Error message is printed by convert_arch_to_abi 1342 exit 1 1343 fi 1344 done 1345 echo "$RET" 1346 } 1347 1348 # Return the default toolchain binary path prefix for given architecture and gcc version 1349 # For example: arm 4.6 -> toolchains/arm-linux-androideabi-4.6/prebuilt/<system>/bin/arm-linux-androideabi- 1350 # $1: Architecture name 1351 # $2: GCC version 1352 # $3: optional, system name, defaults to $HOST_TAG 1353 get_toolchain_binprefix_for_arch () 1354 { 1355 local NAME PREFIX DIR BINPREFIX 1356 local SYSTEM=${3:-$(get_prebuilt_host_tag)} 1357 NAME=$(get_toolchain_name_for_arch $1 $2) 1358 PREFIX=$(get_default_toolchain_prefix_for_arch $1) 1359 DIR=$(get_toolchain_install . $NAME $SYSTEM) 1360 BINPREFIX=${DIR#./}/bin/$PREFIX- 1361 echo "$BINPREFIX" 1362 } 1363 1364 # Return llvm toolchain binary path prefix for given llvm version 1365 # $1: llvm version 1366 # $2: optional, system name, defaults to $HOST_TAG 1367 get_llvm_toolchain_binprefix () 1368 { 1369 local NAME DIR BINPREFIX 1370 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 1371 NAME=llvm-$1 1372 DIR=$(get_toolchain_install . $NAME $SYSTEM) 1373 BINPREFIX=${DIR#./}/bin/ 1374 echo "$BINPREFIX" 1375 } 1376 1377 # Return the default toochain binary path prefix for a given architecture 1378 # For example: arm -> toolchains/arm-linux-androideabi-4.6/prebuilt/<system>/bin/arm-linux-androideabi- 1379 # $1: Architecture name 1380 # $2: optional, system name, defaults to $HOST_TAG 1381 get_default_toolchain_binprefix_for_arch () 1382 { 1383 local GCCVER=$(get_default_gcc_version_for_arch $ARCH) 1384 get_toolchain_binprefix_for_arch $1 $GCCVER $2 1385 } 1386 1387 # Return default API level for a given arch 1388 # This is the level used to build the toolchains. 1389 # 1390 # $1: Architecture name 1391 get_default_api_level_for_arch () 1392 { 1393 # For now, always build the toolchain against API level 9 for 32-bit arch 1394 # and API level $FIRST_API64_LEVEL for 64-bit arch 1395 case $1 in 1396 *64) echo $FIRST_API64_LEVEL ;; 1397 *) echo 9 ;; 1398 esac 1399 } 1400 1401 # Return the default platform sysroot corresponding to a given architecture 1402 # This is the sysroot used to build the toolchain and other binaries like 1403 # the STLport libraries. 1404 # $1: Architecture name 1405 get_default_platform_sysroot_for_arch () 1406 { 1407 local ARCH=$1 1408 local LEVEL=$(get_default_api_level_for_arch $ARCH) 1409 1410 if [ "$ARCH" != "${ARCH%%64*}" ] ; then 1411 LEVEL=$FIRST_API64_LEVEL 1412 fi 1413 echo "platforms/android-$LEVEL/arch-$ARCH" 1414 } 1415 1416 # Return the default libs dir corresponding to a given architecture 1417 # $1: Architecture name 1418 get_default_libdir_for_arch () 1419 { 1420 case $1 in 1421 x86_64|mips64) echo "lib64" ;; 1422 arm64) echo "lib" ;; # return "lib" until aarch64 is built to look for sysroot/usr/lib64 1423 *) echo "lib" ;; 1424 esac 1425 } 1426 1427 # Guess what? 1428 get_default_platform_sysroot_for_abi () 1429 { 1430 local ARCH=$(convert_abi_to_arch $1) 1431 $(get_default_platform_sysroot_for_arch $ARCH) 1432 } 1433 1434 1435 1436 # Return the host/build specific path for prebuilt toolchain binaries 1437 # relative to $1. 1438 # 1439 # $1: target root NDK directory 1440 # $2: toolchain name 1441 # $3: optional, host system name 1442 # 1443 get_toolchain_install () 1444 { 1445 local NDK="$1" 1446 shift 1447 echo "$NDK/$(get_toolchain_install_subdir "$@")" 1448 } 1449 1450 # $1: toolchain name 1451 # $2: optional, host system name 1452 get_toolchain_install_subdir () 1453 { 1454 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 1455 echo "toolchains/$1/prebuilt/$SYSTEM" 1456 } 1457 1458 # Return the relative install prefix for prebuilt host 1459 # executables (relative to the NDK top directory). 1460 # NOTE: This deals with MINGW==yes or DARWIN==yes appropriately 1461 # 1462 # $1: optional, system name 1463 # Out: relative path to prebuilt install prefix 1464 get_prebuilt_install_prefix () 1465 { 1466 local TAG=${1:-$(get_prebuilt_host_tag)} 1467 echo "prebuilt/$TAG" 1468 } 1469 1470 # Return the relative path of an installed prebuilt host 1471 # executable 1472 # NOTE: This deals with MINGW==yes or DARWIN==yes appropriately. 1473 # 1474 # $1: executable name 1475 # $2: optional, host system name 1476 # Out: path to prebuilt host executable, relative 1477 get_prebuilt_host_exec () 1478 { 1479 local PREFIX EXE 1480 PREFIX=$(get_prebuilt_install_prefix $2) 1481 EXE=$(get_prebuilt_host_exe_ext) 1482 echo "$PREFIX/bin/$1$EXE" 1483 } 1484 1485 # Return the name of a given host executable 1486 # $1: executable base name 1487 # Out: executable name, with optional suffix (e.g. .exe for windows) 1488 get_host_exec_name () 1489 { 1490 local EXE=$(get_prebuilt_host_exe_ext) 1491 echo "$1$EXE" 1492 } 1493 1494 # Return the directory where host-specific binaries are installed. 1495 # $1: target root NDK directory 1496 get_host_install () 1497 { 1498 echo "$1/$(get_prebuilt_install_prefix)" 1499 } 1500 1501 # Set the toolchain target NDK location. 1502 # this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX 1503 # $1: target NDK path 1504 # $2: toolchain name 1505 set_toolchain_ndk () 1506 { 1507 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 1508 log "Using toolchain path: $TOOLCHAIN_PATH" 1509 1510 TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET 1511 log "Using toolchain prefix: $TOOLCHAIN_PREFIX" 1512 } 1513 1514 # Check that a toolchain is properly installed at a target NDK location 1515 # 1516 # $1: target root NDK directory 1517 # $2: toolchain name 1518 # 1519 check_toolchain_install () 1520 { 1521 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 1522 if [ ! -d "$TOOLCHAIN_PATH" ] ; then 1523 echo "ERROR: Cannot find directory '$TOOLCHAIN_PATH'!" 1524 echo " Toolchain '$2' not installed in '$NDK_DIR'!" 1525 echo " Ensure that the toolchain has been installed there before." 1526 exit 1 1527 fi 1528 1529 set_toolchain_ndk $1 $2 1530 } 1531 1532 # $1: toolchain source directory 1533 check_toolchain_src_dir () 1534 { 1535 local SRC_DIR="$1" 1536 if [ -z "$SRC_DIR" ]; then 1537 echo "ERROR: Please provide the path to the toolchain source tree. See --help" 1538 exit 1 1539 fi 1540 1541 if [ ! -d "$SRC_DIR" ]; then 1542 echo "ERROR: Not a directory: '$SRC_DIR'" 1543 exit 1 1544 fi 1545 1546 if [ ! -f "$SRC_DIR/build/configure" -o ! -d "$SRC_DIR/gcc" ]; then 1547 echo "ERROR: Either the file $SRC_DIR/build/configure or" 1548 echo " the directory $SRC_DIR/gcc does not exist." 1549 echo "This is not the top of a toolchain tree: $SRC_DIR" 1550 echo "You must give the path to a copy of the toolchain source directories" 1551 echo "created by 'download-toolchain-sources.sh." 1552 exit 1 1553 fi 1554 } 1555 1556 # 1557 # The NDK_TMPDIR variable is used to specify a root temporary directory 1558 # when invoking toolchain build scripts. If it is not defined, we will 1559 # create one here, and export the value to ensure that any scripts we 1560 # call after that use the same one. 1561 # 1562 if [ -z "$NDK_TMPDIR" ]; then 1563 NDK_TMPDIR=/tmp/ndk-$USER/tmp/build-$$ 1564 mkdir -p $NDK_TMPDIR 1565 if [ $? != 0 ]; then 1566 echo "ERROR: Could not create NDK_TMPDIR: $NDK_TMPDIR" 1567 exit 1 1568 fi 1569 export NDK_TMPDIR 1570 fi 1571 1572 # Define HOST_TAG32, as the 32-bit version of HOST_TAG 1573 # We do this by replacing an -x86_64 suffix by -x86 1574 HOST_TAG32=$HOST_TAG 1575 case $HOST_TAG32 in 1576 *-x86_64) 1577 HOST_TAG32=${HOST_TAG%%_64} 1578 ;; 1579 esac 1580