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 20# Warn about /bin/sh ins't bash. 21if [ -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." 23fi 24 25NDK_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> 33extract_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# 44extract_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# 55extract_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# greather or equal than 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# 70version_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# 104max_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>` 111dashes_to_underscores () 112{ 113 echo "$@" | tr '-' '_' 114} 115 116# Translate underscores to dashes 117# Usage: str=`underscores_to_dashes <values>` 118underscores_to_dashes () 119{ 120 echo "$@" | tr '_' '-' 121} 122 123# Translate commas to spaces 124# Usage: str=`commas_to_spaces <list>` 125commas_to_spaces () 126{ 127 echo "$@" | tr ',' ' ' 128} 129 130# Translate spaces to commas 131# Usage: list=`spaces_to_commas <string>` 132spaces_to_commas () 133{ 134 echo "$@" | tr ' ' ',' 135} 136 137# Remove trailing path of a path 138# $1: path 139remove_trailing_slash () { 140 echo ${1%%/} 141} 142 143# Reverse a file path directory 144# foo -> . 145# foo/bar -> .. 146# foo/bar/zoo -> ../.. 147reverse_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 180sort_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 190list_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 202filter_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 216var_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 239OPTIONS="" 240OPTION_FLAGS="" 241OPTION_SETTINGS="" 242 243# Set a given option attribute 244# $1: option name 245# $2: option attribute 246# $3: attribute value 247# 248option_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# 257option_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# 267register_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# 333register_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# 348register_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 356MINGW=no 357DARWIN=no 358do_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} 366do_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 375register_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 383TRY64=no 384do_try64_option () { TRY64=yes; } 385 386register_try64_option () 387{ 388 register_option "--try-64" do_try64_option "Generate 64-bit binaries." 389} 390 391 392register_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# 402print_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 430option_panic_no_args () 431{ 432 echo "ERROR: Option '$1' does not take arguments. See --help for usage." 433 exit 1 434} 435 436option_panic_missing_arg () 437{ 438 echo "ERROR: Option '$1' requires an argument. See --help for usage." 439 exit 1 440} 441 442extract_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 549do_option_help () 550{ 551 print_help 552 exit 0 553} 554 555VERBOSE=no 556VERBOSE2=no 557do_option_verbose () 558{ 559 if [ $VERBOSE = "yes" ] ; then 560 VERBOSE2=yes 561 else 562 VERBOSE=yes 563 fi 564} 565 566DRYRUN=no 567do_option_dryrun () 568{ 569 DRYRUN=yes 570} 571 572register_option "--help" do_option_help "Print this help." 573register_option "--verbose" do_option_verbose "Enable verbose mode." 574register_option "--dryrun" do_option_dryrun "Set to dryrun mode." 575 576#==================================================== 577# 578# TOOLCHAIN AND ABI PROCESSING 579# 580#==================================================== 581 582# Determine optional variable value 583# $1: final variable name 584# $2: option variable name 585# $3: small description for the option 586fix_option () 587{ 588 if [ -n "$2" ] ; then 589 eval $1="$2" 590 log "Using specific $3: $2" 591 else 592 log "Using default $3: `var_value $1`" 593 fi 594} 595 596 597# If SYSROOT is empty, check that $1/$2 contains a sysroot 598# and set the variable to it. 599# 600# $1: sysroot path 601# $2: platform/arch suffix 602check_sysroot () 603{ 604 if [ -z "$SYSROOT" ] ; then 605 log "Probing directory for sysroot: $1/$2" 606 if [ -d $1/$2 ] ; then 607 SYSROOT=$1/$2 608 fi 609 fi 610} 611 612# Determine sysroot 613# $1: Option value (or empty) 614# 615fix_sysroot () 616{ 617 if [ -n "$1" ] ; then 618 eval SYSROOT="$1" 619 log "Using specified sysroot: $1" 620 else 621 SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH 622 SYSROOT= 623 check_sysroot $NDK_DIR/platforms $SYSROOT_SUFFIX 624 check_sysroot $ANDROID_NDK_ROOT/platforms $SYSROOT_SUFFIX 625 check_sysroot `dirname $ANDROID_NDK_ROOT`/development/ndk/platforms $SYSROOT_SUFFIX 626 627 if [ -z "$SYSROOT" ] ; then 628 echo "ERROR: Could not find NDK sysroot path for $SYSROOT_SUFFIX." 629 echo " Use --sysroot=<path> to specify one." 630 exit 1 631 fi 632 fi 633 634 if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then 635 echo "ERROR: Invalid sysroot path: $SYSROOT" 636 echo " Use --sysroot=<path> to indicate a valid one." 637 exit 1 638 fi 639} 640 641# Check for the availability of a compatibility SDK in Darwin 642# this can be used to generate binaries compatible with either Tiger or 643# Leopard. 644# 645# $1: SDK root path 646# $2: Optional MacOS X minimum version (e.g. 10.5) 647DARWIN_MINVER=10.6 648check_darwin_sdk () 649{ 650 local MACSDK="$1" 651 local MINVER=$2 652 653 if [ -z "$MINVER" ] ; then 654 # expect SDK root path ended up with either MacOSX##.#.sdk or MacOSX##.#u.sdk 655 MINVER=${MACSDK##*MacOSX} 656 MINVER=${MINVER%%.sdk*} 657 if [ "$MINVER" = "10.4u" ]; then 658 MINVER=10.4 659 fi 660 fi 661 if [ -d "$MACSDK" ] ; then 662 HOST_CFLAGS=$HOST_CFLAGS" -isysroot $MACSDK -mmacosx-version-min=$MINVER -DMAXOSX_DEPLOYEMENT_TARGET=$MINVER" 663 HOST_LDFLAGS=$HOST_LDFLAGS" -Wl,-syslibroot,$MACSDK -mmacosx-version-min=$MINVER" 664 DARWIN_MINVER=$MINVER 665 return 0 # success 666 fi 667 return 1 668} 669 670# Probe Darwin SDK in specified diectory $DARWIN_SYSROOT, or 671# /Developer/SDKs/MacOSX10.6.sdk 672# 673probe_darwin_sdk () 674{ 675 if [ -n "$DARWIN_SYSROOT" ]; then 676 if check_darwin_sdk "$DARWIN_SYSROOT"; then 677 log "Use darwin sysroot $DARWIN_SYSROOT" 678 else 679 echo "darwin sysroot $DARWIN_SYSROOT is not valid" 680 exit 1 681 fi 682 elif check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk 10.6; then 683 log "Generating Snow Leopard-compatible binaries!" 684 else 685 local version=`sw_vers -productVersion` 686 log "Generating $version-compatible binaries!" 687 fi 688} 689 690handle_canadian_build () 691{ 692 HOST_EXE= 693 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then 694 case $HOST_TAG in 695 linux-*) 696 ;; 697 *) 698 echo "ERROR: Can only enable --mingw or --darwin on Linux platforms !" 699 exit 1 700 ;; 701 esac 702 if [ "$MINGW" = "yes" ] ; then 703 # NOTE: Use x86_64-pc-mingw32msvc or i586-pc-mingw32msvc because wrappers are generated 704 # using these names 705 if [ "$TRY64" = "yes" ]; then 706 ABI_CONFIGURE_HOST=x86_64-pc-mingw32msvc 707 HOST_TAG=windows-x86_64 708 else 709 ABI_CONFIGURE_HOST=i586-pc-mingw32msvc 710 HOST_TAG=windows 711 fi 712 HOST_OS=windows 713 HOST_EXE=.exe 714 else 715 if [ "$TRY64" = "yes" ]; then 716 ABI_CONFIGURE_HOST=x86_64-apple-darwin 717 HOST_TAG=darwin-x86_64 718 else 719 ABI_CONFIGURE_HOST=i686-apple-darwin 720 HOST_TAG=darwin-x86 721 fi 722 HOST_OS=darwin 723 fi 724 fi 725} 726 727# Find mingw toolchain 728# 729# Set MINGW_GCC to the found mingw toolchain 730# 731find_mingw_toolchain () 732{ 733 if [ "$DEBIAN_NAME" -a "$BINPREFIX" -a "$MINGW_GCC" ]; then 734 return 735 fi 736 # IMPORTANT NOTE: binutils 2.21 requires a cross toolchain named 737 # i585-pc-mingw32msvc-gcc, or it will fail its configure step late 738 # in the toolchain build. Note that binutils 2.19 can build properly 739 # with i585-mingw32mvsc-gcc, which is the name used by the 'mingw32' 740 # toolchain install on Debian/Ubuntu. 741 # 742 # To solve this dilemma, we create a wrapper toolchain named 743 # i586-pc-mingw32msvc-gcc that really calls i586-mingw32msvc-gcc, 744 # this works with all versions of binutils. 745 # 746 # We apply the same logic to the 64-bit Windows cross-toolchain 747 # 748 # Fedora note: On Fedora it's x86_64-w64-mingw32- or i686-w64-mingw32- 749 # On older Fedora it's 32-bit only and called i686-pc-mingw32- 750 # so we just add more prefixes to the list to check. 751 if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then 752 BINPREFIX=x86_64-pc-mingw32msvc- 753 BINPREFIXLST="x86_64-pc-mingw32msvc- x86_64-w64-mingw32- amd64-mingw32msvc-" 754 DEBIAN_NAME=mingw64 755 else 756 # we are trying 32 bit anyway, so forcing it to avoid build issues 757 force_32bit_binaries 758 BINPREFIX=i586-pc-mingw32msvc- 759 BINPREFIXLST="i586-pc-mingw32msvc- i686-pc-mingw32- i586-mingw32msvc- i686-w64-mingw32-" 760 DEBIAN_NAME=mingw32 761 fi 762 763 # Scan $BINPREFIXLST list to find installed mingw toolchain. It will be 764 # wrapped later with $BINPREFIX. 765 for i in $BINPREFIXLST; do 766 find_program MINGW_GCC ${i}gcc 767 if [ -n "$MINGW_GCC" ]; then 768 dump "Found mingw toolchain: $MINGW_GCC" 769 break 770 fi 771 done 772} 773 774# Check there is a working cross-toolchain installed. 775# 776# $1: install directory for mingw/darwin wrapper toolchain 777# 778prepare_canadian_toolchain () 779{ 780 if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then 781 return 782 fi 783 CROSS_GCC= 784 if [ "$MINGW" = "yes" ]; then 785 find_mingw_toolchain 786 if [ -z "$MINGW_GCC" ]; then 787 echo "ERROR: Could not find in your PATH any of:" 788 for i in $BINPREFIXLST; do echo " ${i}gcc"; done 789 echo "Please install the corresponding cross-toolchain and re-run this script" 790 echo "TIP: On Debian or Ubuntu, try: sudo apt-get install $DEBIAN_NAME" 791 exit 1 792 fi 793 CROSS_GCC=$MINGW_GCC 794 else 795 if [ -z "$DARWIN_TOOLCHAIN" ]; then 796 echo "Please set DARWIN_TOOLCHAIN to darwin cross-toolchain" 797 exit 1 798 fi 799 if [ ! -f "${DARWIN_TOOLCHAIN}-gcc" ]; then 800 echo "darwin cross-toolchain $DARWIN_TOOLCHAIN-gcc doesn't exist" 801 exit 1 802 fi 803 if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then 804 BINPREFIX=x86_64-apple-darwin- 805 DEBIAN_NAME=darwin64 806 HOST_CFLAGS=$HOST_CFLAGS" -m64" 807 else 808 force_32bit_binaries 809 BINPREFIX=i686-apple-darwin- 810 DEBIAN_NAME=darwin32 811 HOST_CFLAGS=$HOST_CFLAGS" -m32" 812 fi 813 CROSS_GCC=${DARWIN_TOOLCHAIN}-gcc 814 probe_darwin_sdk 815 fi 816 817 # Create a wrapper toolchain, and prepend its dir to our PATH 818 CROSS_WRAP_DIR="$1"/$DEBIAN_NAME-wrapper 819 rm -rf "$CROSS_WRAP_DIR" 820 mkdir -p "$CROSS_WRAP_DIR" 821 822 if [ "$DARWIN" = "yes" ] ; then 823 cat > "$CROSS_WRAP_DIR/sw_vers" <<EOF 824#!/bin/sh 825# Tiny utility for the real sw_vers some Makefiles need 826case \$1 in 827 -productVersion) 828 echo $DARWIN_MINVER 829 ;; 830 *) 831 echo "ERROR: Unknown switch \$1" 832 exit 1 833esac 834EOF 835 chmod 0755 "$CROSS_WRAP_DIR/sw_vers" 836 fi 837 838 DST_PREFIX=${CROSS_GCC%gcc} 839 if [ "$NDK_CCACHE" ]; then 840 DST_PREFIX="$NDK_CCACHE $DST_PREFIX" 841 fi 842 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=$BINPREFIX --dst-prefix="$DST_PREFIX" "$CROSS_WRAP_DIR" \ 843 --cflags="$HOST_CFLAGS" --cxxflags="$HOST_CFLAGS" --ldflags="$HOST_LDFLAGS" 844 # generate wrappers for BUILD toolchain 845 # this is required for mingw/darwin build to avoid tools canadian cross configuration issues 846 # 32-bit BUILD toolchain 847 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" 848 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-linux-gnu- \ 849 --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \ 850 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 851 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-pc-linux-gnu- \ 852 --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \ 853 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 854 # 64-bit BUILD toolchain. libbfd is still built in 32-bit. 855 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-linux-gnu- \ 856 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 857 $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-pc-linux-gnu- \ 858 --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR" 859 fail_panic "Could not create $DEBIAN_NAME wrapper toolchain in $CROSS_WRAP_DIR" 860 861 export PATH=$CROSS_WRAP_DIR:$PATH 862 dump "Using $DEBIAN_NAME wrapper: $CROSS_WRAP_DIR/${BINPREFIX}gcc" 863} 864 865handle_host () 866{ 867 if [ "$TRY64" != "yes" ]; then 868 force_32bit_binaries # to modify HOST_TAG and others 869 HOST_BITS=32 870 fi 871 handle_canadian_build 872} 873 874setup_ccache () 875{ 876 # Support for ccache compilation 877 # We can't use this here when building Windows/darwin binaries on Linux with 878 # binutils 2.21, because defining CC/CXX in the environment makes the 879 # configure script fail later 880 # 881 if [ "$NDK_CCACHE" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then 882 NDK_CCACHE_CC=$CC 883 NDK_CCACHE_CXX=$CXX 884 # Unfortunately, we can just do CC="$NDK_CCACHE $CC" because some 885 # configure scripts are not capable of dealing with this properly 886 # E.g. the ones used to rebuild the GCC toolchain from scratch. 887 # So instead, use a wrapper script 888 CC=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-gcc.sh 889 CXX=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-g++.sh 890 export NDK_CCACHE_CC NDK_CCACHE_CXX 891 log "Using ccache compilation" 892 log "NDK_CCACHE_CC=$NDK_CCACHE_CC" 893 log "NDK_CCACHE_CXX=$NDK_CCACHE_CXX" 894 fi 895} 896 897prepare_common_build () 898{ 899 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then 900 if [ "$TRY64" = "yes" ]; then 901 HOST_BITS=64 902 else 903 HOST_BITS=32 904 fi 905 if [ "$MINGW" = "yes" ]; then 906 log "Generating $HOST_BITS-bit Windows binaries" 907 else 908 log "Generating $HOST_BITS-bit Darwin binaries" 909 fi 910 # Do *not* set CC and CXX when building the Windows/Darwin binaries in canadian build. 911 # Otherwise, the GCC configure/build script will mess that Canadian cross 912 # build in weird ways. Instead we rely on the toolchain detected or generated 913 # previously in prepare_canadian_toolchain. 914 unset CC CXX 915 return 916 fi 917 918 # On Linux, detect our legacy-compatible toolchain when in the Android 919 # source tree, and use it to force the generation of glibc-2.7 compatible 920 # binaries. 921 # 922 # We only do this if the CC variable is not defined to a given value 923 if [ -z "$CC" ]; then 924 LEGACY_TOOLCHAIN_DIR= 925 if [ "$HOST_OS" = "linux" ]; then 926 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8/bin" 927 LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/x86_64-linux-" 928 elif [ "$HOST_OS" = "darwin" ]; then 929 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1/bin" 930 LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/i686-apple-darwin10-" 931 fi 932 if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then 933 log "Forcing generation of $HOST_OS binaries with legacy toolchain" 934 CC="${LEGACY_TOOLCHAIN_PREFIX}gcc" 935 CXX="${LEGACY_TOOLCHAIN_PREFIX}g++" 936 fi 937 fi 938 939 CC=${CC:-gcc} 940 CXX=${CXX:-g++} 941 STRIP=${STRIP:-strip} 942 case $HOST_TAG in 943 darwin-*) 944 probe_darwin_sdk 945 ;; 946 esac 947 948 # Force generation of 32-bit binaries on 64-bit systems. 949 # We used to test the value of $HOST_TAG for *-x86_64, but this is 950 # not sufficient on certain systems. 951 # 952 # For example, Snow Leopard can be booted with a 32-bit kernel, running 953 # a 64-bit userland, with a compiler that generates 64-bit binaries by 954 # default *even* though "gcc -v" will report --target=i686-apple-darwin10! 955 # 956 # So know, simply probe for the size of void* by performing a small runtime 957 # compilation test. 958 # 959 cat > $TMPC <<EOF 960 /* this test should fail if the compiler generates 64-bit machine code */ 961 int test_array[1-2*(sizeof(void*) != 4)]; 962EOF 963 log_n "Checking whether the compiler generates 32-bit binaries..." 964 log2 $CC $HOST_CFLAGS -c -o $TMPO $TMPC 965 $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1 966 if [ $? != 0 ] ; then 967 log "no" 968 if [ "$TRY64" != "yes" ]; then 969 # NOTE: We need to modify the definitions of CC and CXX directly 970 # here. Just changing the value of CFLAGS / HOST_CFLAGS 971 # will not work well with the GCC toolchain scripts. 972 CC="$CC -m32" 973 CXX="$CXX -m32" 974 fi 975 else 976 log "yes" 977 if [ "$TRY64" = "yes" ]; then 978 CC="$CC -m64" 979 CXX="$CXX -m64" 980 fi 981 fi 982 983 if [ "$TRY64" = "yes" ]; then 984 HOST_BITS=64 985 else 986 force_32bit_binaries # to modify HOST_TAG and others 987 HOST_BITS=32 988 fi 989} 990 991prepare_host_build () 992{ 993 prepare_common_build 994 995 # Now deal with mingw or darwin 996 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then 997 handle_canadian_build 998 CC=$ABI_CONFIGURE_HOST-gcc 999 CXX=$ABI_CONFIGURE_HOST-g++ 1000 CPP=$ABI_CONFIGURE_HOST-cpp 1001 LD=$ABI_CONFIGURE_HOST-ld 1002 AR=$ABI_CONFIGURE_HOST-ar 1003 AS=$ABI_CONFIGURE_HOST-as 1004 RANLIB=$ABI_CONFIGURE_HOST-ranlib 1005 STRIP=$ABI_CONFIGURE_HOST-strip 1006 export CC CXX CPP LD AR AS RANLIB STRIP 1007 fi 1008 1009 setup_ccache 1010} 1011 1012prepare_abi_configure_build () 1013{ 1014 # detect build tag 1015 case $HOST_TAG in 1016 linux-x86) 1017 ABI_CONFIGURE_BUILD=i386-linux-gnu 1018 ;; 1019 linux-x86_64) 1020 ABI_CONFIGURE_BUILD=x86_64-linux-gnu 1021 ;; 1022 darwin-x86) 1023 ABI_CONFIGURE_BUILD=i686-apple-darwin 1024 ;; 1025 darwin-x86_64) 1026 ABI_CONFIGURE_BUILD=x86_64-apple-darwin 1027 ;; 1028 windows) 1029 ABI_CONFIGURE_BUILD=i686-pc-cygwin 1030 ;; 1031 *) 1032 echo "ERROR: Unsupported HOST_TAG: $HOST_TAG" 1033 echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh" 1034 ;; 1035 esac 1036} 1037 1038prepare_target_build () 1039{ 1040 prepare_abi_configure_build 1041 1042 # By default, assume host == build 1043 ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD" 1044 1045 prepare_common_build 1046 HOST_GMP_ABI=$HOST_BITS 1047 1048 # Now handle the --mingw/--darwin flag 1049 if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then 1050 handle_canadian_build 1051 STRIP=$ABI_CONFIGURE_HOST-strip 1052 if [ "$MINGW" = "yes" ] ; then 1053 # It turns out that we need to undefine this to be able to 1054 # perform a canadian-cross build with mingw. Otherwise, the 1055 # GMP configure scripts will not be called with the right options 1056 HOST_GMP_ABI= 1057 fi 1058 fi 1059 1060 setup_ccache 1061} 1062 1063# $1: Toolchain name 1064# 1065parse_toolchain_name () 1066{ 1067 TOOLCHAIN=$1 1068 if [ -z "$TOOLCHAIN" ] ; then 1069 echo "ERROR: Missing toolchain name!" 1070 exit 1 1071 fi 1072 1073 ABI_CFLAGS_FOR_TARGET= 1074 ABI_CXXFLAGS_FOR_TARGET= 1075 1076 # Determine ABI based on toolchain name 1077 # 1078 case "$TOOLCHAIN" in 1079 arm-linux-androideabi-*) 1080 ARCH="arm" 1081 ABI="armeabi" 1082 ABI_CONFIGURE_TARGET="arm-linux-androideabi" 1083 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te" 1084 ;; 1085 arm-eabi-*) 1086 ARCH="arm" 1087 ABI="armeabi" 1088 ABI_CONFIGURE_TARGET="arm-eabi" 1089 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te --disable-gold --disable-libgomp" 1090 ;; 1091 aarch64-linux-android-*) 1092 ARCH="arm64" 1093 ABI="arm64-v8a" 1094 ABI_CONFIGURE_TARGET="aarch64-linux-android" 1095 ;; 1096 x86-*) 1097 ARCH="x86" 1098 ABI=$ARCH 1099 ABI_INSTALL_NAME="x86" 1100 ABI_CONFIGURE_TARGET="i686-linux-android" 1101 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1102 # You can't really build these separately at the moment. 1103 ABI_CFLAGS_FOR_TARGET="-fPIC" 1104 ;; 1105 x86_64-*) 1106 ARCH="x86_64" 1107 ABI=$ARCH 1108 ABI_INSTALL_NAME="x86_64" 1109 ABI_CONFIGURE_TARGET="x86_64-linux-android" 1110 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1111 # You can't really build these separately at the moment. 1112 ABI_CFLAGS_FOR_TARGET="-fPIC" 1113 ;; 1114 mipsel*) 1115 ARCH="mips" 1116 ABI=$ARCH 1117 ABI_INSTALL_NAME="mips" 1118 ABI_CONFIGURE_TARGET="mipsel-linux-android" 1119 # Set default to mips32 1120 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips32" 1121 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1122 # You can't really build these separately at the moment. 1123 # Add -fpic, because MIPS NDK will need to link .a into .so. 1124 ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic" 1125 ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic" 1126 # Add --disable-fixed-point to disable fixed-point support 1127 ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point" 1128 ;; 1129 mips64el*) 1130 ARCH="mips64" 1131 ABI=$ARCH 1132 ABI_INSTALL_NAME="mips64" 1133 ABI_CONFIGURE_TARGET="mips64el-linux-android" 1134 # Set default to mips64r6 1135 ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips64r6" 1136 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time 1137 # You can't really build these separately at the moment. 1138 # Add -fpic, because MIPS NDK will need to link .a into .so. 1139 ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic" 1140 ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic" 1141 # Add --disable-fixed-point to disable fixed-point support 1142 ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point" 1143 ;; 1144 * ) 1145 echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|arm-eabi-*|x86-*|mipsel*|mips64el*)" 1146 echo "" 1147 print_help 1148 exit 1 1149 ;; 1150 esac 1151 1152 log "Targetting CPU: $ARCH" 1153 1154 GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'` 1155 log "Using GCC version: $GCC_VERSION" 1156 1157 # Determine --host value when building gdbserver 1158 1159 case "$TOOLCHAIN" in 1160 arm-*) 1161 GDBSERVER_HOST=arm-eabi-linux 1162 GDBSERVER_CFLAGS="-fno-short-enums" 1163 GDBSERVER_LDFLAGS= 1164 ;; 1165 aarch64-*) 1166 GDBSERVER_HOST=aarch64-eabi-linux 1167 GDBSERVER_CFLAGS="-fno-short-enums -DUAPI_HEADERS" 1168 GDBSERVER_LDFLAGS= 1169 ;; 1170 x86-*) 1171 GDBSERVER_HOST=i686-linux-android 1172 GDBSERVER_CFLAGS= 1173 GDBSERVER_LDFLAGS= 1174 ;; 1175 x86_64-*) 1176 GDBSERVER_HOST=x86_64-linux-android 1177 GDBSERVER_CFLAGS=-DUAPI_HEADERS 1178 GDBSERVER_LDFLAGS= 1179 ;; 1180 mipsel-*) 1181 GDBSERVER_HOST=mipsel-linux-android 1182 GDBSERVER_CFLAGS= 1183 GDBSERVER_LDFLAGS= 1184 ;; 1185 mips64el-*) 1186 GDBSERVER_HOST=mips64el-linux-android 1187 GDBSERVER_CFLAGS=-DUAPI_HEADERS 1188 GDBSERVER_LDFLAGS= 1189 ;; 1190 *) 1191 echo "Unknown TOOLCHAIN=$TOOLCHAIN" 1192 exit 1193 esac 1194} 1195 1196# Return the host "tag" used to identify prebuilt host binaries. 1197# NOTE: Handles the case where '$MINGW = true' or '$DARWIN = true' 1198# For now, valid values are: linux-x86, darwin-x86 and windows 1199get_prebuilt_host_tag () 1200{ 1201 local RET=$HOST_TAG 1202 if [ "$MINGW" = "yes" ]; then 1203 if [ "$TRY64" = "no" ]; then 1204 RET=windows 1205 else 1206 RET=windows-x86_64 1207 fi 1208 fi 1209 if [ "$DARWIN" = "yes" ]; then 1210 RET=darwin-x86_64 # let the following handles 32-bit case 1211 fi 1212 case $RET in 1213 linux-x86_64) 1214 if [ "$TRY64" = "no" ]; then 1215 RET=linux-x86 1216 fi 1217 ;; 1218 darwin-x86_64) 1219 if [ "$TRY64" = "no" ]; then 1220 RET=darwin-x86 1221 fi 1222 ;; 1223 esac 1224 echo $RET 1225} 1226 1227# Return the executable suffix corresponding to host executables 1228get_prebuilt_host_exe_ext () 1229{ 1230 if [ "$MINGW" = "yes" ]; then 1231 echo ".exe" 1232 else 1233 echo "" 1234 fi 1235} 1236 1237# Find all archs from $DEV_DIR/platforms or $NDK_DIR/platforms 1238# Return: the list of found arch name 1239find_ndk_archs () 1240{ 1241 local NDK_ROOT_DIR DEVDIR 1242 local RESULT FOUND_ARCHS 1243 1244 if [ ! -z "$NDK_DIR" ]; then 1245 NDK_ROOT_DIR=$NDK_DIR 1246 else 1247 NDK_ROOT_DIR=$ANDROID_NDK_ROOT 1248 fi 1249 1250 DEVDIR="$ANDROID_NDK_ROOT/../development/ndk" 1251 1252 # Check development directory first 1253 if [ -d $DEVDIR/platforms ]; then 1254 RESULT=$(ls $DEVDIR/platforms/android-* | grep "arch-") 1255 for arch in $RESULT; do 1256 arch=$(basename $arch | sed -e 's/^arch-//') 1257 FOUND_ARCHS="$FOUND_ARCHS $arch" 1258 done 1259 fi 1260 1261 # Check ndk directory 1262 if [ -z "$FOUND_ARCHS" ] && [ -d $NDK_ROOT_DIR/platforms ]; then 1263 RESULT=$(ls $NDK_ROOT_DIR/platforms/android-* | grep "arch-") 1264 for arch in $RESULT; do 1265 arch=$(basename $arch | sed -e 's/^arch-//') 1266 FOUND_ARCHS="$FOUND_ARCHS $arch" 1267 done 1268 fi 1269 1270 # If we cannot find any arch, set to default archs 1271 if [ -z "$FOUND_ARCHS" ]; then 1272 FOUND_ARCHS=$DEFAULT_ARCHS 1273 fi 1274 1275 echo "$(sort_uniq $FOUND_ARCHS)" 1276} 1277 1278# Find unknown archs from $NDK_DIR/platforms 1279# Return: arch names not in ndk default archs 1280find_ndk_unknown_archs() 1281{ 1282 local FOUND_ARCHS=$(find_ndk_archs) 1283 # TODO: arm64, x86_64 is here just to be found as known arch. 1284 # It can be removed as soon as it is added into $DEFAULT_ARCHS 1285 echo "$(filter_out "$DEFAULT_ARCHS arm64 x86_64 mips64" "$FOUND_ARCHS")" 1286} 1287 1288# Determine whether given arch is in unknown archs list 1289# $1: arch 1290# Return: yes or no 1291arch_in_unknown_archs() 1292{ 1293 local UNKNOWN_ARCH=$(find_ndk_unknown_archs | grep $1) 1294 if [ -z "$UNKNOWN_ARCH" ]; then 1295 echo "no" 1296 else 1297 echo "yes" 1298 fi 1299} 1300 1301# Get library suffix for given ABI 1302# $1: ABI 1303# Return: .so or .bc 1304get_lib_suffix_for_abi () 1305{ 1306 local ABI=$1 1307 if [ $(arch_in_unknown_archs $ABI) = "yes" ]; then 1308 echo ".bc" 1309 else 1310 echo ".so" 1311 fi 1312} 1313 1314# Convert an ABI name into an Architecture name 1315# $1: ABI name 1316# Result: Arch name 1317convert_abi_to_arch () 1318{ 1319 local RET 1320 local ABI=$1 1321 case $ABI in 1322 armeabi|armeabi-v7a|armeabi-v7a-hard) 1323 RET=arm 1324 ;; 1325 x86|mips|x86_64|mips64) 1326 RET=$ABI 1327 ;; 1328 mips32r6) 1329 RET=mips 1330 ;; 1331 arm64-v8a) 1332 RET=arm64 1333 ;; 1334 *) 1335 if [ "$(arch_in_unknown_archs $ABI)" = "yes" ]; then 1336 RET=$ABI 1337 else 1338 >&2 echo "ERROR: Unsupported ABI name: $ABI, use one of: armeabi, armeabi-v7a, x86, mips, armeabi-v7a-hard, arm64-v8a, x86_64 or mips64" 1339 exit 1 1340 fi 1341 ;; 1342 esac 1343 echo "$RET" 1344} 1345 1346# Take architecture name as input, and output the list of corresponding ABIs 1347# Inverse for convert_abi_to_arch 1348# $1: ARCH name 1349# Out: ABI names list (comma-separated) 1350convert_arch_to_abi () 1351{ 1352 local RET 1353 local ARCH=$1 1354 case $ARCH in 1355 arm) 1356 RET=armeabi,armeabi-v7a,armeabi-v7a-hard 1357 ;; 1358 x86|x86_64|mips|mips64) 1359 RET=$ARCH 1360 ;; 1361 arm64) 1362 RET=arm64-v8a 1363 ;; 1364 *) 1365 if [ "$(arch_in_unknown_archs $ARCH)" = "yes" ]; then 1366 RET=$ARCH 1367 else 1368 >&2 echo "ERROR: Unsupported ARCH name: $ARCH, use one of: arm, x86, mips" 1369 exit 1 1370 fi 1371 ;; 1372 esac 1373 echo "$RET" 1374} 1375 1376# Take a list of architecture names as input, and output the list of corresponding ABIs 1377# $1: ARCH names list (separated by spaces or commas) 1378# Out: ABI names list (comma-separated) 1379convert_archs_to_abis () 1380{ 1381 local RET 1382 for ARCH in $(commas_to_spaces $@); do 1383 ABI=$(convert_arch_to_abi $ARCH) 1384 if [ -n "$ABI" ]; then 1385 if [ -n "$RET" ]; then 1386 RET=$RET",$ABI" 1387 else 1388 RET=$ABI 1389 fi 1390 else # Error message is printed by convert_arch_to_abi 1391 exit 1 1392 fi 1393 done 1394 echo "$RET" 1395} 1396 1397# Return the default toolchain binary path prefix for given architecture and gcc version 1398# For example: arm 4.8 -> toolchains/arm-linux-androideabi-4.8/prebuilt/<system>/bin/arm-linux-androideabi- 1399# $1: Architecture name 1400# $2: GCC version 1401# $3: optional, system name, defaults to $HOST_TAG 1402get_toolchain_binprefix_for_arch () 1403{ 1404 local NAME PREFIX DIR BINPREFIX 1405 local SYSTEM=${3:-$(get_prebuilt_host_tag)} 1406 NAME=$(get_toolchain_name_for_arch $1 $2) 1407 PREFIX=$(get_default_toolchain_prefix_for_arch $1) 1408 DIR=$(get_toolchain_install . $NAME $SYSTEM) 1409 BINPREFIX=${DIR#./}/bin/$PREFIX- 1410 echo "$BINPREFIX" 1411} 1412 1413# Return llvm toolchain binary path prefix for given llvm version 1414# $1: llvm version 1415# $2: optional, system name, defaults to $HOST_TAG 1416get_llvm_toolchain_binprefix () 1417{ 1418 local NAME DIR BINPREFIX 1419 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 1420 NAME=llvm-$1 1421 DIR=$(get_toolchain_install . $NAME $SYSTEM) 1422 BINPREFIX=${DIR#./}/bin/ 1423 echo "$BINPREFIX" 1424} 1425 1426# Return the default toochain binary path prefix for a given architecture 1427# For example: arm -> toolchains/arm-linux-androideabi-4.8/prebuilt/<system>/bin/arm-linux-androideabi- 1428# $1: Architecture name 1429# $2: optional, system name, defaults to $HOST_TAG 1430get_default_toolchain_binprefix_for_arch () 1431{ 1432 local GCCVER=$(get_default_gcc_version_for_arch $ARCH) 1433 get_toolchain_binprefix_for_arch $1 $GCCVER $2 1434} 1435 1436# Return default API level for a given arch 1437# This is the level used to build the toolchains. 1438# 1439# $1: Architecture name 1440get_default_api_level_for_arch () 1441{ 1442 # For unknown arch, use API level $FIRST_API64_LEVEL 1443 if [ $(arch_in_unknown_archs $1) = "yes" ]; then 1444 echo $FIRST_API64_LEVEL 1445 else 1446 # For now, always build the toolchain against API level 9 for 32-bit arch 1447 # and API level $FIRST_API64_LEVEL for 64-bit arch 1448 case $1 in 1449 *64) echo $FIRST_API64_LEVEL ;; 1450 *) echo 9 ;; 1451 esac 1452 fi 1453} 1454 1455# Return the default platform sysroot corresponding to a given architecture 1456# This is the sysroot used to build the toolchain and other binaries like 1457# the STLport libraries. 1458# $1: Architecture name 1459get_default_platform_sysroot_for_arch () 1460{ 1461 local ARCH=$1 1462 local LEVEL=$(get_default_api_level_for_arch $ARCH) 1463 1464 if [ "$ARCH" != "${ARCH%%64*}" ] ; then 1465 LEVEL=$FIRST_API64_LEVEL 1466 fi 1467 echo "platforms/android-$LEVEL/arch-$ARCH" 1468} 1469 1470# Return the default platform sysroot corresponding to a given abi 1471# $1: ABI 1472get_default_platform_sysroot_for_abi () 1473{ 1474 local ARCH=$(convert_abi_to_arch $1) 1475 $(get_default_platform_sysroot_for_arch $ARCH) 1476} 1477 1478# Return the default libs dir corresponding to a given architecture 1479# $1: Architecture name 1480get_default_libdir_for_arch () 1481{ 1482 case $1 in 1483 x86_64|mips64) echo "lib64" ;; 1484 arm64) echo "lib" ;; # return "lib" until aarch64 is built to look for sysroot/usr/lib64 1485 *) echo "lib" ;; 1486 esac 1487} 1488 1489# Return the default libs dir corresponding to a given abi 1490# $1: ABI 1491get_default_libdir_for_abi () 1492{ 1493 local ARCH 1494 1495 case $1 in 1496 mips32r6) echo "libr6" ;; 1497 *) 1498 local ARCH=$(convert_abi_to_arch $1) 1499 echo "$(get_default_libdir_for_arch $ARCH)" 1500 ;; 1501 esac 1502} 1503 1504# Return the host/build specific path for prebuilt toolchain binaries 1505# relative to $1. 1506# 1507# $1: target root NDK directory 1508# $2: toolchain name 1509# $3: optional, host system name 1510# 1511get_toolchain_install () 1512{ 1513 local NDK="$1" 1514 shift 1515 echo "$NDK/$(get_toolchain_install_subdir "$@")" 1516} 1517 1518# $1: toolchain name 1519# $2: optional, host system name 1520get_toolchain_install_subdir () 1521{ 1522 local SYSTEM=${2:-$(get_prebuilt_host_tag)} 1523 echo "toolchains/$1/prebuilt/$SYSTEM" 1524} 1525 1526# Return the relative install prefix for prebuilt host 1527# executables (relative to the NDK top directory). 1528# NOTE: This deals with MINGW==yes or DARWIN==yes appropriately 1529# 1530# $1: optional, system name 1531# Out: relative path to prebuilt install prefix 1532get_prebuilt_install_prefix () 1533{ 1534 local TAG=${1:-$(get_prebuilt_host_tag)} 1535 echo "prebuilt/$TAG" 1536} 1537 1538# Return the relative path of an installed prebuilt host 1539# executable 1540# NOTE: This deals with MINGW==yes or DARWIN==yes appropriately. 1541# 1542# $1: executable name 1543# $2: optional, host system name 1544# Out: path to prebuilt host executable, relative 1545get_prebuilt_host_exec () 1546{ 1547 local PREFIX EXE 1548 PREFIX=$(get_prebuilt_install_prefix $2) 1549 EXE=$(get_prebuilt_host_exe_ext) 1550 echo "$PREFIX/bin/$1$EXE" 1551} 1552 1553# Return the name of a given host executable 1554# $1: executable base name 1555# Out: executable name, with optional suffix (e.g. .exe for windows) 1556get_host_exec_name () 1557{ 1558 local EXE=$(get_prebuilt_host_exe_ext) 1559 echo "$1$EXE" 1560} 1561 1562# Return the directory where host-specific binaries are installed. 1563# $1: target root NDK directory 1564get_host_install () 1565{ 1566 echo "$1/$(get_prebuilt_install_prefix)" 1567} 1568 1569# Set the toolchain target NDK location. 1570# this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX 1571# $1: target NDK path 1572# $2: toolchain name 1573set_toolchain_ndk () 1574{ 1575 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 1576 log "Using toolchain path: $TOOLCHAIN_PATH" 1577 1578 TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET 1579 log "Using toolchain prefix: $TOOLCHAIN_PREFIX" 1580} 1581 1582# Check that a toolchain is properly installed at a target NDK location 1583# 1584# $1: target root NDK directory 1585# $2: toolchain name 1586# 1587check_toolchain_install () 1588{ 1589 TOOLCHAIN_PATH=`get_toolchain_install "$1" $2` 1590 if [ ! -d "$TOOLCHAIN_PATH" ] ; then 1591 echo "ERROR: Cannot find directory '$TOOLCHAIN_PATH'!" 1592 echo " Toolchain '$2' not installed in '$NDK_DIR'!" 1593 echo " Ensure that the toolchain has been installed there before." 1594 exit 1 1595 fi 1596 1597 set_toolchain_ndk $1 $2 1598} 1599 1600# $1: toolchain source directory 1601check_toolchain_src_dir () 1602{ 1603 local SRC_DIR="$1" 1604 if [ -z "$SRC_DIR" ]; then 1605 echo "ERROR: Please provide the path to the toolchain source tree. See --help" 1606 exit 1 1607 fi 1608 1609 if [ ! -d "$SRC_DIR" ]; then 1610 echo "ERROR: Not a directory: '$SRC_DIR'" 1611 exit 1 1612 fi 1613 1614 if [ ! -f "$SRC_DIR/build/configure" -o ! -d "$SRC_DIR/gcc" ]; then 1615 echo "ERROR: Either the file $SRC_DIR/build/configure or" 1616 echo " the directory $SRC_DIR/gcc does not exist." 1617 echo "This is not the top of a toolchain tree: $SRC_DIR" 1618 echo "You must give the path to a copy of the toolchain source directories" 1619 echo "created by 'download-toolchain-sources.sh." 1620 exit 1 1621 fi 1622} 1623 1624# 1625# The NDK_TMPDIR variable is used to specify a root temporary directory 1626# when invoking toolchain build scripts. If it is not defined, we will 1627# create one here, and export the value to ensure that any scripts we 1628# call after that use the same one. 1629# 1630if [ -z "$NDK_TMPDIR" ]; then 1631 NDK_TMPDIR=/tmp/ndk-$USER/tmp/build-$$ 1632 mkdir -p $NDK_TMPDIR 1633 if [ $? != 0 ]; then 1634 echo "ERROR: Could not create NDK_TMPDIR: $NDK_TMPDIR" 1635 exit 1 1636 fi 1637 export NDK_TMPDIR 1638fi 1639 1640# Define HOST_TAG32, as the 32-bit version of HOST_TAG 1641# We do this by replacing an -x86_64 suffix by -x86 1642HOST_TAG32=$HOST_TAG 1643case $HOST_TAG32 in 1644 *-x86_64) 1645 HOST_TAG32=${HOST_TAG%%_64} 1646 ;; 1647esac 1648