1 # Common functions for all prebuilt-related scripts
2 # This is included/sourced by other scripts
5 . `dirname $0`/../core/ndk-common.sh
7 #====================================================
11 #====================================================
13 # Return the maximum length of a series of strings
15 # Usage: len=`max_length <string1> <string2> ...`
19 echo "$@" | tr ' ' '\n' | awk 'BEGIN {max=0} {len=length($1); if (len > max) max=len} END {print max}'
22 # Translate dashes to underscores
23 # Usage: str=`dashes_to_underscores <values>`
24 dashes_to_underscores ()
29 # Translate underscores to dashes
30 # Usage: str=`underscores_to_dashes <values>`
31 underscores_to_dashes ()
36 #====================================================
40 #====================================================
42 # We recognize the following option formats:
51 # NOTE: We translate '-' into '_' when storing the options in global variables
58 # Set a given option attribute
60 # $2: option attribute
65 eval OPTIONS_$1_$2=\"$3\"
68 # Get a given option attribute
70 # $2: option attribute
74 echo `var_value OPTIONS_$1_$2`
77 # Register a new option
79 # $2: small abstract for the option
80 # $3: optional. default value
82 register_option_internal ()
89 # Check for something like --setting=<value>
90 echo "$1" | grep -q -E -e '^--[^=]+=<.+>$'
92 optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'`
93 optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'`
94 opttype="long_setting"
98 # Check for something like --flag
99 echo "$1" | grep -q -E -e '^--[^=]+$'
106 # Check for something like -f<value>
107 echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$'
109 optlabel=`expr -- "$1" : '\(-.\).*'`
110 optvalue=`expr -- "$1" : '-.\(<.+>\)'`
111 opttype="short_setting"
115 # Check for something like -f
116 echo "$1" | grep -q -E -e '^-.$'
123 echo "ERROR: Invalid option format: $1"
124 echo " Check register_option call"
128 log "new option: type='$opttype' name='$optlabel' value='$optvalue'"
130 optname=`dashes_to_underscores $optlabel`
131 OPTIONS="$OPTIONS $optname"
132 OPTIONS_TEXT="$OPTIONS_TEXT $1"
133 option_set_attr $optname label "$optlabel"
134 option_set_attr $optname otype "$opttype"
135 option_set_attr $optname value "$optvalue"
136 option_set_attr $optname text "$1"
137 option_set_attr $optname abstract "$2"
138 option_set_attr $optname default "$3"
141 # Register a new option with a function callback.
144 # $2: name of function that will be called when the option is parsed
145 # $3: small abstract for the option
146 # $4: optional. default value
150 local optname optvalue opttype optlabel
151 register_option_internal "$1" "$3" "$4"
152 option_set_attr $optname funcname "$2"
155 # Register a new option with a variable store
158 # $2: name of variable that will be set by this option
159 # $3: small abstract for the option
161 # NOTE: The current value of $2 is used as the default
163 register_var_option ()
165 local optname optvalue opttype optlabel
166 register_option_internal "$1" "$3" "`var_value $2`"
167 option_set_attr $optname varname "$2"
172 do_mingw_option () { MINGW=yes; }
174 register_mingw_option ()
176 if [ "$HOST_OS" = "linux" ] ; then
177 register_option "--mingw" do_mingw_option "Generate windows binaries on Linux."
181 # Print the help, including a list of registered options for this program
182 # Note: Assumes PROGRAM_PARAMETERS and PROGRAM_DESCRIPTION exist and
183 # correspond to the parameters list and the program description
187 local opt text abstract default
189 echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS"
191 if [ -n "$PROGRAM_DESCRIPTION" ] ; then
192 echo "$PROGRAM_DESCRIPTION"
195 echo "Valid options (defaults are in brackets):"
198 maxw=`max_length "$OPTIONS_TEXT"`
199 AWK_SCRIPT=`echo "{ printf \"%-${maxw}s\", \\$1 }"`
200 for opt in $OPTIONS; do
201 text=`option_get_attr $opt text | awk "$AWK_SCRIPT"`
202 abstract=`option_get_attr $opt abstract`
203 default=`option_get_attr $opt default`
204 if [ -n "$default" ] ; then
205 echo " $text $abstract [$default]"
207 echo " $text $abstract"
213 option_panic_no_args ()
215 echo "ERROR: Option '$1' does not take arguments. See --help for usage."
219 option_panic_missing_arg ()
221 echo "ERROR: Option '$1' requires an argument. See --help for usage."
225 extract_parameters ()
227 local opt optname otype value name fin funcname
229 while [ -n "$1" ] ; do
230 # If the parameter does not begin with a dash
231 # it is not an option.
232 param=`expr -- "$1" : '^\([^\-].*\)$'`
233 if [ -n "$param" ] ; then
234 if [ -z "$PARAMETERS" ] ; then
237 PARAMETERS="$PARAMETERS $1"
243 while [ -n "1" ] ; do
244 # Try to match a long setting, i.e. --option=value
245 opt=`expr -- "$1" : '^\(--[^=]*\)=.*$'`
246 if [ -n "$opt" ] ; then
248 value=`expr -- "$1" : '^--[^=]*=\(.*\)$'`
252 # Try to match a long flag, i.e. --option
253 opt=`expr -- "$1" : '^\(--.*\)$'`
254 if [ -n "$opt" ] ; then
260 # Try to match a short setting, i.e. -o<value>
261 opt=`expr -- "$1" : '^\(-[A-Za-z0-9]\)..*$'`
262 if [ -n "$opt" ] ; then
263 otype="short_setting"
264 value=`expr -- "$1" : '^-.\(.*\)$'`
268 # Try to match a short flag, i.e. -o
269 opt=`expr -- "$1" : '^\(-.\)$'`
270 if [ -n "$opt" ] ; then
276 echo "ERROR: Unknown option '$1'. Use --help for list of valid values."
280 #echo "Found opt='$opt' otype='$otype' value='$value'"
282 name=`dashes_to_underscores $opt`
284 for xopt in $OPTIONS; do
285 if [ "$name" != "$xopt" ] ; then
288 # Check that the type is correct here
290 # This also allows us to handle -o <value> as -o<value>
292 xotype=`option_get_attr $name otype`
293 if [ "$otype" != "$xotype" ] ; then
296 option_panic_no_args $opt
299 if [ -z "$2" ] ; then
300 option_panic_missing_arg $opt
306 option_panic_no_args $opt
309 option_panic_missing_arg $opt
317 if [ "$found" = "0" ] ; then
318 echo "ERROR: Unknown option '$opt'. See --help for usage."
321 # Set variable or launch option-specific function.
322 varname=`option_get_attr $name varname`
323 if [ -n "$varname" ] ; then
324 eval ${varname}=\"$value\"
326 eval `option_get_attr $name funcname` \"$value\"
342 if [ $VERBOSE = "yes" ] ; then
349 register_option "--help" do_option_help "Print this help."
350 register_option "--verbose" do_option_verbose "Enable verbose mode."
352 #====================================================
354 # TOOLCHAIN AND ABI PROCESSING
356 #====================================================
358 # Determine optional variable value
359 # $1: final variable name
360 # $2: option variable name
361 # $3: small description for the option
364 if [ -n "$2" ] ; then
366 log "Using specific $3: $2"
368 log "Using default $3: `var_value $1`"
373 # If SYSROOT is empty, check that $1/$2 contains a sysroot
374 # and set the variable to it.
377 # $2: platform/arch suffix
380 if [ -z "$SYSROOT" ] ; then
381 log "Probing directory for sysroot: $1/$2"
382 if [ -d $1/$2 ] ; then
389 # $1: Option value (or empty)
393 if [ -n "$1" ] ; then
395 log "Using specified sysroot: $1"
397 SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH
399 check_sysroot $NDK_DIR/platforms $SYSROOT_SUFFIX
400 check_sysroot $ANDROID_NDK_ROOT/platforms $SYSROOT_SUFFIX
401 check_sysroot `dirname $ANDROID_NDK_ROOT`/development/ndk/platforms $SYSROOT_SUFFIX
403 if [ -z "$SYSROOT" ] ; then
404 echo "ERROR: Could not find NDK sysroot path for $SYSROOT_SUFFIX."
405 echo " Use --sysroot=<path> to specify one."
410 if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then
411 echo "ERROR: Invalid sysroot path: $SYSROOT"
412 echo " Use --sysroot=<path> to indicate a valid one."
417 # Use the check for the availability of a compatibility SDK in Darwin
418 # this can be used to generate binaries compatible with either Tiger or
422 # $2: MacOS X minimum version (e.g. 10.4)
425 if [ -d "$1" ] ; then
426 HOST_CFLAGS="-isysroot $1 -mmacosx-version-min=$2 -DMAXOSX_DEPLOYEMENT_TARGET=$2"
427 HOST_LDFLAGS="-Wl,-syslibroot,$sdk -mmacosx-version-min=$2"
434 prepare_host_flags ()
439 ABI_CONFIGURE_BUILD=i386-linux-gnu
442 ABI_CONFIGURE_BUILD=x86_64-linux-gnu
445 ABI_CONFIGURE_BUILD=i686-apple-darwin
448 ABI_CONFIGURE_BUILD=x86_64-apple-darwin
451 ABI_CONFIGURE_BUILD=i686-pc-cygwin
454 echo "ERROR: Unsupported HOST_TAG: $HOST_TAG"
455 echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh"
459 # By default, assume host == build
460 ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD"
462 # On Linux, detect our legacy-compatible toolchain when in the Android
463 # source tree, and use it to force the generation of glibc-2.7 compatible
466 # We only do this if the CC variable is not defined to a given value
467 # and the --mingw option is not used.
469 if [ "$HOST_OS" = "linux" -a -z "$CC" -a "$MINGW" != "yes" ]; then
470 LEGACY_TOOLCHAIN_DIR="$ANDROID_NDK_ROOT/../prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3"
471 if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then
472 dump "Forcing generation of Linux binaries with legacy toolchain"
473 CC="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-gcc"
474 CXX="$LEGACY_TOOLCHAIN_DIR/bin/i686-linux-g++"
478 # Force generation of 32-bit binaries on 64-bit systems
483 # Try to build with Tiger SDK if available
484 if check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku 10.4; then
485 log "Generating Tiger-compatible binaries!"
486 # Otherwise with Leopard SDK
487 elif check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk 10.5; then
488 log "Generating Leopard-compatible binaries!"
490 local version=`sw_vers -productVersion`
491 log "Generating $version-compatible binaries!"
496 # Force generation of 32-bit binaries on 64-bit systems.
497 # We used to test the value of $HOST_TAG for *-x86_64, but this is
498 # not sufficient on certain systems.
500 # For example, Snow Leopard can be booted with a 32-bit kernel, running
501 # a 64-bit userland, with a compiler that generates 64-bit binaries by
502 # default *even* though "gcc -v" will report --target=i686-apple-darwin10!
504 # So know, simply probe for the size of void* by performing a small runtime
508 /* this test should fail if the compiler generates 64-bit machine code */
509 int test_array[1-2*(sizeof(void*) != 4)];
511 echo -n "Checking whether the compiler generates 32-bit binaries..."
512 log $CC $HOST_CFLAGS -c -o $TMPO $TMPC
513 $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1
514 if [ $? != 0 ] ; then
516 # NOTE: We need to modify the definitions of CC and CXX directly
517 # here. Just changing the value of CFLAGS / HOST_CFLAGS
518 # will not work well with the GCC toolchain scripts.
525 # For now, we only support building 32-bit binaries anyway
526 force_32bit_binaries # to modify HOST_TAG and others
529 # Now handle the --mingw flag
530 if [ "$MINGW" = "yes" ] ; then
535 echo "ERROR: Can only enable mingw on Linux platforms !"
539 ABI_CONFIGURE_HOST=i586-mingw32msvc
543 # It turns out that we need to undefine this to be able to
544 # perform a canadian-cross build with mingw. Otherwise, the
545 # GMP configure scripts will not be called with the right options
550 parse_toolchain_name ()
552 if [ -z "$TOOLCHAIN" ] ; then
553 echo "ERROR: Missing toolchain name!"
557 ABI_CFLAGS_FOR_TARGET=
558 ABI_CXXFLAGS_FOR_TARGET=
560 # Determine ABI based on toolchain name
565 ABI_CONFIGURE_TARGET="arm-eabi"
567 arm-linux-androideabi-*)
569 ABI_CONFIGURE_TARGET="arm-linux-androideabi"
570 ABI_CONFIGURE_EXTRA_FLAGS="--with-gmp-version=4.2.4 --with-mpfr-version=2.4.1
572 # Disable ARM Gold linker for now, it doesn't build on Windows, it
573 # crashes with SIGBUS on Darwin, and produces weird executables on
574 # linux that strip complains about... Sigh.
575 #ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --enable-gold=both/gold"
577 # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
578 # You can't really build these separately at the moment.
579 ABI_CFLAGS_FOR_TARGET="-fexceptions"
580 ABI_CXXFLAGS_FOR_TARGET="-frtti"
581 ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --enable-libstdc__-v3"
582 # Stick to 6.6 for now. 7.1.x doesn't seem to work right now.
587 ABI_INSTALL_NAME="x86"
588 ABI_CONFIGURE_TARGET="i686-android-linux-gnu"
592 echo "Invalid toolchain specified. Expected (arm-eabi-*|x86-*)"
599 log "Targetting CPU: $ARCH"
601 GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9\.]*\)'`
602 log "Using GCC version: $GCC_VERSION"
604 # Determine --host value when building gdbserver
607 GDBSERVER_HOST=arm-eabi-linux
608 GDBSERVER_CFLAGS="-fno-short-enums"
611 GDBSERVER_HOST=i686-android-linux-gnu
618 # Return the host/build specific path for prebuilt toolchain binaries
621 # $1: target root NDK directory
623 get_toolchain_install ()
625 echo "$1/toolchains/$TOOLCHAIN/prebuilt/$HOST_TAG"
629 # Set the toolchain target NDK location.
630 # this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX
631 # $1: target NDK path
634 TOOLCHAIN_PATH=`get_toolchain_install $1`
635 log "Using toolchain path: $TOOLCHAIN_PATH"
637 TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET
638 log "Using toolchain prefix: $TOOLCHAIN_PREFIX"
641 # Check that a toolchain is properly installed at a target NDK location
643 # $1: target root NDK directory
645 check_toolchain_install ()
647 TOOLCHAIN_PATH=`get_toolchain_install $1`
648 if [ ! -d "$TOOLCHAIN_PATH" ] ; then
649 echo "ERROR: Toolchain '$TOOLCHAIN' not installed in '$NDK_DIR'!"
650 echo " Ensure that the toolchain has been installed there before."
658 random_temp_directory ()
660 mkdir -p /tmp/ndk-toolchain
661 mktemp -d /tmp/ndk-toolchain/build-XXXXXX
668 # Current list of platform levels we support
670 # Note: levels 6 and 7 are omitted since they have the same native
673 API_LEVELS="3 4 5 8 9"
675 # Location of the STLport sources, relative to the NDK root directory
676 STLPORT_SUBDIR=sources/cxx-stl/stlport
678 # Default ABIs for the prebuilt STLport binaries
679 STLPORT_ABIS="armeabi armeabi-v7a"
681 # Location of the GNU libstdc++ headers and libraries, relative to the NDK
683 GNUSTL_SUBDIR=sources/cxx-stl/gnu-libstdc++
685 # The date to use when downloading toolchain sources from android.git.kernel.org
686 # Leave it empty for tip of tree.
687 TOOLCHAIN_GIT_DATE=2010-12-13