OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / ndk / build / tools / prebuilt-common.sh
1 # Common functions for all prebuilt-related scripts
2 # This is included/sourced by other scripts
3 #
4
5 . `dirname $0`/../core/ndk-common.sh
6
7 #====================================================
8 #
9 #  UTILITY FUNCTIONS
10 #
11 #====================================================
12
13 # Return the maximum length of a series of strings
14 #
15 # Usage:  len=`max_length <string1> <string2> ...`
16 #
17 max_length ()
18 {
19     echo "$@" | tr ' ' '\n' | awk 'BEGIN {max=0} {len=length($1); if (len > max) max=len} END {print max}'
20 }
21
22 # Translate dashes to underscores
23 # Usage:  str=`dashes_to_underscores <values>`
24 dashes_to_underscores ()
25 {
26     echo $@ | tr '-' '_'
27 }
28
29 # Translate underscores to dashes
30 # Usage: str=`underscores_to_dashes <values>`
31 underscores_to_dashes ()
32 {
33     echo $@ | tr '_' '-'
34 }
35
36 #====================================================
37 #
38 #  OPTION PROCESSING
39 #
40 #====================================================
41
42 # We recognize the following option formats:
43 #
44 #  -f
45 #  --flag
46 #
47 #  -s<value>
48 #  --setting=<value>
49 #
50
51 # NOTE: We translate '-' into '_' when storing the options in global variables
52 #
53
54 OPTIONS=""
55 OPTION_FLAGS=""
56 OPTION_SETTINGS=""
57
58 # Set a given option attribute
59 # $1: option name
60 # $2: option attribute
61 # $3: attribute value
62 #
63 option_set_attr ()
64 {
65     eval OPTIONS_$1_$2=\"$3\"
66 }
67
68 # Get a given option attribute
69 # $1: option name
70 # $2: option attribute
71 #
72 option_get_attr ()
73 {
74     echo `var_value OPTIONS_$1_$2`
75 }
76
77 # Register a new option
78 # $1: option
79 # $2: small abstract for the option
80 # $3: optional. default value
81 #
82 register_option_internal ()
83 {
84     optlabel=
85     optname=
86     optvalue=
87     opttype=
88     while [ -n "1" ] ; do
89         # Check for something like --setting=<value>
90         echo "$1" | grep -q -E -e '^--[^=]+=<.+>$'
91         if [ $? = 0 ] ; then
92             optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'`
93             optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'`
94             opttype="long_setting"
95             break
96         fi
97
98         # Check for something like --flag
99         echo "$1" | grep -q -E -e '^--[^=]+$'
100         if [ $? = 0 ] ; then
101             optlabel="$1"
102             opttype="long_flag"
103             break
104         fi
105
106         # Check for something like -f<value>
107         echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$'
108         if [ $? = 0 ] ; then
109             optlabel=`expr -- "$1" : '\(-.\).*'`
110             optvalue=`expr -- "$1" : '-.\(<.+>\)'`
111             opttype="short_setting"
112             break
113         fi
114
115         # Check for something like -f
116         echo "$1" | grep -q -E -e '^-.$'
117         if [ $? = 0 ] ; then
118             optlabel="$1"
119             opttype="short_flag"
120             break
121         fi
122
123         echo "ERROR: Invalid option format: $1"
124         echo "       Check register_option call"
125         exit 1
126     done
127
128     log "new option: type='$opttype' name='$optlabel' value='$optvalue'"
129
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"
139 }
140
141 # Register a new option with a function callback.
142 #
143 # $1: option
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
147 #
148 register_option ()
149 {
150     local optname optvalue opttype optlabel
151     register_option_internal "$1" "$3" "$4"
152     option_set_attr $optname funcname "$2"
153 }
154
155 # Register a new option with a variable store
156 #
157 # $1: option
158 # $2: name of variable that will be set by this option
159 # $3: small abstract for the option
160 #
161 # NOTE: The current value of $2 is used as the default
162 #
163 register_var_option ()
164 {
165     local optname optvalue opttype optlabel
166     register_option_internal "$1" "$3" "`var_value $2`"
167     option_set_attr $optname varname "$2"
168 }
169
170
171 MINGW=no
172 do_mingw_option () { MINGW=yes; }
173
174 register_mingw_option ()
175 {
176     if [ "$HOST_OS" = "linux" ] ; then
177         register_option "--mingw" do_mingw_option "Generate windows binaries on Linux."
178     fi
179 }
180
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
184 #
185 print_help ()
186 {
187     local opt text abstract default
188
189     echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS"
190     echo ""
191     if [ -n "$PROGRAM_DESCRIPTION" ] ; then
192         echo "$PROGRAM_DESCRIPTION"
193         echo ""
194     fi
195     echo "Valid options (defaults are in brackets):"
196     echo ""
197
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]"
206         else
207             echo "  $text     $abstract"
208         fi
209     done
210     echo ""
211 }
212
213 option_panic_no_args ()
214 {
215     echo "ERROR: Option '$1' does not take arguments. See --help for usage."
216     exit 1
217 }
218
219 option_panic_missing_arg ()
220 {
221     echo "ERROR: Option '$1' requires an argument. See --help for usage."
222     exit 1
223 }
224
225 extract_parameters ()
226 {
227     local opt optname otype value name fin funcname
228     PARAMETERS=""
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
235                 PARAMETERS="$1"
236             else
237                 PARAMETERS="$PARAMETERS $1"
238             fi
239             shift
240             continue
241         fi
242
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
247                 otype="long_setting"
248                 value=`expr -- "$1" : '^--[^=]*=\(.*\)$'`
249                 break
250             fi
251
252             # Try to match a long flag, i.e. --option
253             opt=`expr -- "$1" : '^\(--.*\)$'`
254             if [ -n "$opt" ] ; then
255                 otype="long_flag"
256                 value="yes"
257                 break
258             fi
259
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" : '^-.\(.*\)$'`
265                 break
266             fi
267
268             # Try to match a short flag, i.e. -o
269             opt=`expr -- "$1" : '^\(-.\)$'`
270             if [ -n "$opt" ] ; then
271                 otype="short_flag"
272                 value="yes"
273                 break
274             fi
275
276             echo "ERROR: Unknown option '$1'. Use --help for list of valid values."
277             exit 1
278         done
279
280         #echo "Found opt='$opt' otype='$otype' value='$value'"
281
282         name=`dashes_to_underscores $opt`
283         found=0
284         for xopt in $OPTIONS; do
285             if [ "$name" != "$xopt" ] ; then
286                 continue
287             fi
288             # Check that the type is correct here
289             #
290             # This also allows us to handle -o <value> as -o<value>
291             #
292             xotype=`option_get_attr $name otype`
293             if [ "$otype" != "$xotype" ] ; then
294                 case "$xotype" in
295                 "short_flag")
296                     option_panic_no_args $opt
297                     ;;
298                 "short_setting")
299                     if [ -z "$2" ] ; then
300                         option_panic_missing_arg $opt
301                     fi
302                     value="$2"
303                     shift
304                     ;;
305                 "long_flag")
306                     option_panic_no_args $opt
307                     ;;
308                 "long_setting")
309                     option_panic_missing_arg $opt
310                     ;;
311                 esac
312             fi
313             found=1
314             break
315             break
316         done
317         if [ "$found" = "0" ] ; then
318             echo "ERROR: Unknown option '$opt'. See --help for usage."
319             exit 1
320         fi
321         # Set variable or launch option-specific function.
322         varname=`option_get_attr $name varname`
323         if [ -n "$varname" ] ; then
324             eval ${varname}=\"$value\"
325         else
326             eval `option_get_attr $name funcname` \"$value\"
327         fi
328         shift
329     done
330 }
331
332 do_option_help ()
333 {
334     print_help
335     exit 0
336 }
337
338 VERBOSE=no
339 VERBOSE2=no
340 do_option_verbose ()
341 {
342     if [ $VERBOSE = "yes" ] ; then
343         VERBOSE2=yes
344     else
345         VERBOSE=yes
346     fi
347 }
348
349 register_option "--help"          do_option_help     "Print this help."
350 register_option "--verbose"       do_option_verbose  "Enable verbose mode."
351
352 #====================================================
353 #
354 #  TOOLCHAIN AND ABI PROCESSING
355 #
356 #====================================================
357
358 # Determine optional variable value
359 # $1: final variable name
360 # $2: option variable name
361 # $3: small description for the option
362 fix_option ()
363 {
364     if [ -n "$2" ] ; then
365         eval $1="$2"
366         log "Using specific $3: $2"
367     else
368         log "Using default $3: `var_value $1`"
369     fi
370 }
371
372
373 # If SYSROOT is empty, check that $1/$2 contains a sysroot
374 # and set the variable to it.
375 #
376 # $1: sysroot path
377 # $2: platform/arch suffix
378 check_sysroot ()
379 {
380     if [ -z "$SYSROOT" ] ; then
381         log "Probing directory for sysroot: $1/$2"
382         if [ -d $1/$2 ] ; then
383             SYSROOT=$1/$2
384         fi
385     fi
386 }
387
388 # Determine sysroot
389 # $1: Option value (or empty)
390 #
391 fix_sysroot ()
392 {
393     if [ -n "$1" ] ; then
394         eval SYSROOT="$1"
395         log "Using specified sysroot: $1"
396     else
397         SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH
398         SYSROOT=
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
402
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."
406             exit 1
407         fi
408     fi
409
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."
413         exit 1
414     fi
415 }
416
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
419 # Leopard.
420 #
421 # $1: SDK root path
422 # $2: MacOS X minimum version (e.g. 10.4)
423 check_darwin_sdk ()
424 {
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"
428         return 0  # success
429     fi
430     return 1
431 }
432
433
434 prepare_host_flags ()
435 {
436     # detect build tag
437     case $HOST_TAG in
438         linux-x86)
439             ABI_CONFIGURE_BUILD=i386-linux-gnu
440             ;;
441         linux-x86_64)
442             ABI_CONFIGURE_BUILD=x86_64-linux-gnu
443             ;;
444         darwin-x86)
445             ABI_CONFIGURE_BUILD=i686-apple-darwin
446             ;;
447         darwin-x86_64)
448             ABI_CONFIGURE_BUILD=x86_64-apple-darwin
449             ;;
450         windows)
451             ABI_CONFIGURE_BUILD=i686-pc-cygwin
452             ;;
453         *)
454             echo "ERROR: Unsupported HOST_TAG: $HOST_TAG"
455             echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh"
456             ;;
457     esac
458
459     # By default, assume host == build
460     ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD"
461
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
464     # binaries.
465     #
466     # We only do this if the CC variable is not defined to a given value
467     # and the --mingw option is not used.
468     #
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++"
475         fi
476     fi
477
478     # Force generation of 32-bit binaries on 64-bit systems
479     CC=${CC:-gcc}
480     CXX=${CXX:-g++}
481     case $HOST_TAG in
482         darwin-*)
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!"
489             else
490                 local version=`sw_vers -productVersion`
491                 log "Generating $version-compatible binaries!"
492             fi
493             ;;
494     esac
495
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.
499     #
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!
503     #
504     # So know, simply probe for the size of void* by performing a small runtime
505     # compilation test.
506     #
507     cat > $TMPC <<EOF
508     /* this test should fail if the compiler generates 64-bit machine code */
509     int test_array[1-2*(sizeof(void*) != 4)];
510 EOF
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
515         echo "no"
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.
519         CC="$CC -m32"
520         CXX="$CXX -m32"
521     else
522         echo "yes"
523     fi
524
525     # For now, we only support building 32-bit binaries anyway
526     force_32bit_binaries  # to modify HOST_TAG and others
527     HOST_GMP_ABI="32"
528
529     # Now handle the --mingw flag
530     if [ "$MINGW" = "yes" ] ; then
531         case $HOST_TAG in
532             linux-*)
533                 ;;
534             *)
535                 echo "ERROR: Can only enable mingw on Linux platforms !"
536                 exit 1
537                 ;;
538         esac
539         ABI_CONFIGURE_HOST=i586-mingw32msvc
540         HOST_OS=windows
541         HOST_TAG=windows
542         HOST_EXE=.exe
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
546         HOST_GMP_ABI=
547     fi
548 }
549
550 parse_toolchain_name ()
551 {
552     if [ -z "$TOOLCHAIN" ] ; then
553         echo "ERROR: Missing toolchain name!"
554         exit 1
555     fi
556
557     ABI_CFLAGS_FOR_TARGET=
558     ABI_CXXFLAGS_FOR_TARGET=
559
560     # Determine ABI based on toolchain name
561     #
562     case "$TOOLCHAIN" in
563     arm-eabi-*)
564         ARCH="arm"
565         ABI_CONFIGURE_TARGET="arm-eabi"
566         ;;
567     arm-linux-androideabi-*)
568         ARCH="arm"
569         ABI_CONFIGURE_TARGET="arm-linux-androideabi"
570         ABI_CONFIGURE_EXTRA_FLAGS="--with-gmp-version=4.2.4 --with-mpfr-version=2.4.1
571 --with-arch=armv5te"
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"
576
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.
583         #GDB_VERSION=7.1.x
584         ;;
585     x86-*)
586         ARCH="x86"
587         ABI_INSTALL_NAME="x86"
588         ABI_CONFIGURE_TARGET="i686-android-linux-gnu"
589         PLATFORM=android-5
590         ;;
591     * )
592         echo "Invalid toolchain specified. Expected (arm-eabi-*|x86-*)"
593         echo ""
594         print_help
595         exit 1
596         ;;
597     esac
598
599     log "Targetting CPU: $ARCH"
600
601     GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9\.]*\)'`
602     log "Using GCC version: $GCC_VERSION"
603
604     # Determine --host value when building gdbserver
605     case "$TOOLCHAIN" in
606     arm-*)
607         GDBSERVER_HOST=arm-eabi-linux
608         GDBSERVER_CFLAGS="-fno-short-enums"
609         ;;
610     x86-*)
611         GDBSERVER_HOST=i686-android-linux-gnu
612         GDBSERVER_CFLAGS=
613         ;;
614     esac
615
616 }
617
618 # Return the host/build specific path for prebuilt toolchain binaries
619 # relative to $1.
620 #
621 # $1: target root NDK directory
622 #
623 get_toolchain_install ()
624 {
625     echo "$1/toolchains/$TOOLCHAIN/prebuilt/$HOST_TAG"
626 }
627
628
629 # Set the toolchain target NDK location.
630 # this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX
631 # $1: target NDK path
632 set_toolchain_ndk ()
633 {
634     TOOLCHAIN_PATH=`get_toolchain_install $1`
635     log "Using toolchain path: $TOOLCHAIN_PATH"
636
637     TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET
638     log "Using toolchain prefix: $TOOLCHAIN_PREFIX"
639 }
640
641 # Check that a toolchain is properly installed at a target NDK location
642 #
643 # $1: target root NDK directory
644 #
645 check_toolchain_install ()
646 {
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."
651         exit 1
652     fi
653
654     set_toolchain_ndk $1
655 }
656
657
658 random_temp_directory ()
659 {
660     mkdir -p /tmp/ndk-toolchain
661     mktemp -d /tmp/ndk-toolchain/build-XXXXXX
662 }
663
664 #
665 # Common definitions
666 #
667
668 # Current list of platform levels we support
669 #
670 # Note: levels 6 and 7 are omitted since they have the same native
671 # APIs as level 5.
672 #
673 API_LEVELS="3 4 5 8 9"
674
675 # Location of the STLport sources, relative to the NDK root directory
676 STLPORT_SUBDIR=sources/cxx-stl/stlport
677
678 # Default ABIs for the prebuilt STLport binaries
679 STLPORT_ABIS="armeabi armeabi-v7a"
680
681 # Location of the GNU libstdc++ headers and libraries, relative to the NDK
682 # root directory.
683 GNUSTL_SUBDIR=sources/cxx-stl/gnu-libstdc++
684
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