Home | History | Annotate | Download | only in tools
      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: name of function that will be called when the option is parsed
     80 # $3: small abstract for the option
     81 # $4: optional. default value
     82 #
     83 register_option ()
     84 {
     85     local optname optvalue opttype optlabel
     86     optlabel=
     87     optname=
     88     optvalue=
     89     opttype=
     90     while [ -n "1" ] ; do
     91         # Check for something like --setting=<value>
     92         echo "$1" | grep -q -E -e '^--[^=]+=<.+>$'
     93         if [ $? = 0 ] ; then
     94             optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'`
     95             optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'`
     96             opttype="long_setting"
     97             break
     98         fi
     99 
    100         # Check for something like --flag
    101         echo "$1" | grep -q -E -e '^--[^=]+$'
    102         if [ $? = 0 ] ; then
    103             optlabel="$1"
    104             opttype="long_flag"
    105             break
    106         fi
    107 
    108         # Check for something like -f<value>
    109         echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$'
    110         if [ $? = 0 ] ; then
    111             optlabel=`expr -- "$1" : '\(-.\).*'`
    112             optvalue=`expr -- "$1" : '-.\(<.+>\)'`
    113             opttype="short_setting"
    114             break
    115         fi
    116 
    117         # Check for something like -f
    118         echo "$1" | grep -q -E -e '^-.$'
    119         if [ $? = 0 ] ; then
    120             optlabel="$1"
    121             opttype="short_flag"
    122             break
    123         fi
    124 
    125         echo "ERROR: Invalid option format: $1"
    126         echo "       Check register_option call"
    127         exit 1
    128     done
    129 
    130     log "new option: type='$opttype' name='$optlabel' value='$optvalue'"
    131 
    132     optname=`dashes_to_underscores $optlabel`
    133     OPTIONS="$OPTIONS $optname"
    134     OPTIONS_TEXT="$OPTIONS_TEXT $1"
    135     option_set_attr $optname label "$optlabel"
    136     option_set_attr $optname otype "$opttype"
    137     option_set_attr $optname value "$optvalue"
    138     option_set_attr $optname text "$1"
    139     option_set_attr $optname funcname "$2"
    140     option_set_attr $optname abstract "$3"
    141     option_set_attr $optname default "$4"
    142 }
    143 
    144 # Print the help, including a list of registered options for this program
    145 # Note: Assumes PROGRAM_PARAMETERS and PROGRAM_DESCRIPTION exist and
    146 #       correspond to the parameters list and the program description
    147 #
    148 print_help ()
    149 {
    150     local opt text abstract default
    151 
    152     echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS"
    153     echo ""
    154     if [ -n "$PROGRAM_DESCRIPTION" ] ; then
    155         echo "$PROGRAM_DESCRIPTION"
    156         echo ""
    157     fi
    158     echo "Valid options (defaults are in brackets):"
    159     echo ""
    160 
    161     maxw=`max_length "$OPTIONS_TEXT"`
    162     AWK_SCRIPT=`echo "{ printf \"%-${maxw}s\", \\$1 }"`
    163     for opt in $OPTIONS; do
    164         text=`option_get_attr $opt text | awk "$AWK_SCRIPT"`
    165         abstract=`option_get_attr $opt abstract`
    166         default=`option_get_attr $opt default`
    167         if [ -n "$default" ] ; then
    168             echo "  $text     $abstract [$default]"
    169         else
    170             echo "  $text     $abstract"
    171         fi
    172     done
    173     echo ""
    174 }
    175 
    176 option_panic_no_args ()
    177 {
    178     echo "ERROR: Option '$1' does not take arguments. See --help for usage."
    179     exit 1
    180 }
    181 
    182 option_panic_missing_arg ()
    183 {
    184     echo "ERROR: Option '$1' requires an argument. See --help for usage."
    185     exit 1
    186 }
    187 
    188 extract_parameters ()
    189 {
    190     local opt optname otype value name fin funcname
    191     PARAMETERS=""
    192     while [ -n "$1" ] ; do
    193         # If the parameter does not begin with a dash
    194         # it is not an option.
    195         param=`expr -- "$1" : '^\([^\-].*\)$'`
    196         if [ -n "$param" ] ; then
    197             if [ -z "$PARAMETERS" ] ; then
    198                 PARAMETERS="$1"
    199             else
    200                 PARAMETERS="$PARAMETERS $1"
    201             fi
    202             shift
    203             continue
    204         fi
    205 
    206         while [ -n "1" ] ; do
    207             # Try to match a long setting, i.e. --option=value
    208             opt=`expr -- "$1" : '^\(--[^=]*\)=.*$'`
    209             if [ -n "$opt" ] ; then
    210                 otype="long_setting"
    211                 value=`expr -- "$1" : '^--[^=]*=\(.*\)$'`
    212                 break
    213             fi
    214 
    215             # Try to match a long flag, i.e. --option
    216             opt=`expr -- "$1" : '^\(--.*\)$'`
    217             if [ -n "$opt" ] ; then
    218                 otype="long_flag"
    219                 value=
    220                 break
    221             fi
    222 
    223             # Try to match a short setting, i.e. -o<value>
    224             opt=`expr -- "$1" : '^\(-[A-Za-z0-9]\)..*$'`
    225             if [ -n "$opt" ] ; then
    226                 otype="short_setting"
    227                 value=`expr -- "$1" : '^-.\(.*\)$'`
    228                 break
    229             fi
    230 
    231             # Try to match a short flag, i.e. -o
    232             opt=`expr -- "$1" : '^\(-.\)$'`
    233             if [ -n "$opt" ] ; then
    234                 otype="short_flag"
    235                 value=
    236                 break
    237             fi
    238 
    239             echo "ERROR: Unknown option '$1'. Use --help for list of valid values."
    240             exit 1
    241         done
    242 
    243         #echo "Found opt='$opt' otype='$otype' value='$value'"
    244 
    245         name=`dashes_to_underscores $opt`
    246         found=0
    247         for xopt in $OPTIONS; do
    248             if [ "$name" != "$xopt" ] ; then
    249                 continue
    250             fi
    251             # Check that the type is correct here
    252             #
    253             # This also allows us to handle -o <value> as -o<value>
    254             #
    255             xotype=`option_get_attr $name otype`
    256             if [ "$otype" != "$xotype" ] ; then
    257                 case "$xotype" in
    258                 "short_flag")
    259                     option_panic_no_args $opt
    260                     ;;
    261                 "short_setting")
    262                     if [ -z "$2" ] ; then
    263                         option_panic_missing_arg $opt
    264                     fi
    265                     value="$2"
    266                     shift
    267                     ;;
    268                 "long_flag")
    269                     option_panic_no_args $opt
    270                     ;;
    271                 "long_setting")
    272                     option_panic_missing_arg $opt
    273                     ;;
    274                 esac
    275             fi
    276             found=1
    277             break
    278             break
    279         done
    280         if [ "$found" = "0" ] ; then
    281             echo "ERROR: Unknown option '$opt'. See --help for usage."
    282             exit 1
    283         fi
    284         # Launch option-specific function, value, if any as argument
    285         eval `option_get_attr $name funcname` \"$value\"
    286         shift
    287     done
    288 }
    289 
    290 do_option_help ()
    291 {
    292     print_help
    293     exit 0
    294 }
    295 
    296 VERBOSE=no
    297 VERBOSE2=no
    298 do_option_verbose ()
    299 {
    300     if [ $VERBOSE = "yes" ] ; then
    301         VERBOSE2=yes
    302     else
    303         VERBOSE=yes
    304     fi
    305 }
    306 
    307 register_option "--help"          do_option_help     "Print this help."
    308 register_option "--verbose"       do_option_verbose  "Enable verbose mode."
    309 
    310 #====================================================
    311 #
    312 #  TOOLCHAIN AND ABI PROCESSING
    313 #
    314 #====================================================
    315 
    316 # Determine optional variable value
    317 # $1: final variable name
    318 # $2: option variable name
    319 # $3: small description for the option
    320 fix_option ()
    321 {
    322     if [ -n "$2" ] ; then
    323         eval $1="$2"
    324         log "Using specific $3: $2"
    325     else
    326         log "Using default $3: `var_value $1`"
    327     fi
    328 }
    329 
    330 # Determine sysroot
    331 # $1: Option value (or empty)
    332 #
    333 fix_sysroot ()
    334 {
    335     if [ -n "$1" ] ; then
    336         eval SYSROOT="$1"
    337         log "Using specified sysroot: $1"
    338     else
    339         SYSROOT_SUFFIX=build/platforms/$PLATFORM/arch-$ARCH
    340         if [ -d $NDK_DIR/$SYSROOT_SUFFIX ] ; then
    341             SYSROOT=$NDK_DIR/$SYSROOT_SUFFIX
    342             log "Using target NDK sysroot: $SYSROOT"
    343         else
    344             SYSROOT=$ANDROID_NDK_ROOT/$SYSROOT_SUFFIX
    345             log "Using install NDK sysroot: $SYSROOT"
    346         fi
    347     fi
    348 
    349     if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then
    350         echo "ERROR: Invalid sysroot path: $SYSROOT"
    351         echo "       Use --sysroot=<path> to indicate a valid one."
    352         exit 1
    353     fi
    354 }
    355 
    356 prepare_host_flags ()
    357 {
    358     # Force generation of 32-bit binaries on 64-bit systems
    359     case $HOST_TAG in
    360         *-x86_64)
    361             HOST_CFLAGS="$HOST_CFLAGS -m32"
    362             HOST_LDFLAGS="$HOST_LDFLAGS -m32"
    363             force_32bit_binaries  # to modify HOST_TAG and others
    364             ;;
    365     esac
    366 }
    367 
    368 parse_toolchain_name ()
    369 {
    370     if [ -z "$TOOLCHAIN" ] ; then
    371         echo "ERROR: Missing toolchain name!"
    372         exit 1
    373     fi
    374 
    375     # Determine ABI based on toolchain name
    376     #
    377     case "$TOOLCHAIN" in
    378     arm-eabi-*)
    379         ARCH="arm"
    380         ABI_INSTALL_NAME="arm-eabi"
    381         ABI_TOOLCHAIN_PREFIX="arm-eabi"
    382         ABI_CONFIGURE_HOST="arm-eabi-linux"
    383         ;;
    384     x86-*)
    385         ARCH="x86"
    386         ABI_INSTALL_NAME="x86"
    387         ABI_TOOLCHAIN_PREFIX="i686-android-linux-gnu"
    388         ABI_CONFIGURE_HOST="i686-linux"
    389         PLATFORM=android-5
    390         ;;
    391     * )
    392         echo "Invalid toolchain specified. Expected (arm-eabi-*|x86-*)"
    393         echo ""
    394         print_help
    395         exit 1
    396         ;;
    397     esac
    398 
    399     log "Targetting CPU: $ARCH"
    400 
    401     GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9\.]*\)'`
    402     log "Using GCC version: $GCC_VERSION"
    403 
    404 }
    405 
    406 set_toolchain_install ()
    407 {
    408     TOOLCHAIN_PATH=$1
    409     log "Using toolchain path: $TOOLCHAIN_PATH"
    410 
    411     TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_TOOLCHAIN_PREFIX
    412     log "Using toolchain prefix: $TOOLCHAIN_PREFIX"
    413 }
    414 
    415 check_toolchain_install ()
    416 {
    417     TOOLCHAIN_PATH=$1/build/prebuilt/$HOST_TAG/$TOOLCHAIN
    418     if [ ! -d "$TOOLCHAIN_PATH" ] ; then
    419         echo "ERROR: Toolchain '$TOOLCHAIN' not installed in '$NDK_DIR'!"
    420         echo "       Ensure that the toolchain has been installed there before."
    421         exit 1
    422     fi
    423 
    424     set_toolchain_install $TOOLCHAIN_PATH
    425 }
    426 
    427 
    428 random_temp_directory ()
    429 {
    430     mktemp -d /tmp/ndk-toolchain-XXXXXX
    431 }
    432