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