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