1 # Copyright (C) 2008 The Android Open Source Project 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # 15 # This file is included by other shell scripts; do not execute it directly. 16 # It contains common definitions. 17 # 18 PROGNAME=`basename $0` 19 20 ## Logging support 21 ## 22 VERBOSE=yes 23 VERBOSE2=no 24 25 log () 26 { 27 if [ "$VERBOSE" = "yes" ] ; then 28 echo "$1" 29 fi 30 } 31 32 log2 () 33 { 34 if [ "$VERBOSE2" = "yes" ] ; then 35 echo "$1" 36 fi 37 } 38 39 ## Utilities 40 ## 41 42 # return the value of a given named variable 43 # $1: variable name 44 # 45 var_value () 46 { 47 # find a better way to do that ? 48 local result 49 eval result="$`echo $1`" 50 echo $result 51 } 52 53 # convert to uppercase 54 to_uppercase () 55 { 56 echo $1 | tr "[:lower:]" "[:upper:]" 57 } 58 59 ## Normalize OS and CPU 60 ## 61 62 CPU=`uname -m` 63 case "$CPU" in 64 i?86) CPU=x86 65 ;; 66 amd64) CPU=x86_64 67 ;; 68 powerpc) CPU=ppc 69 ;; 70 esac 71 72 log2 "CPU=$CPU" 73 74 # at this point, the supported values for CPU are: 75 # x86 76 # x86_64 77 # ppc 78 # 79 # other values may be possible but haven't been tested 80 # 81 82 EXE="" 83 OS=`uname -s` 84 case "$OS" in 85 Darwin) 86 OS=darwin-$CPU 87 ;; 88 Linux) 89 # note that building 32-bit binaries on x86_64 is handled later 90 OS=linux-$CPU 91 ;; 92 FreeBSD) 93 OS=freebsd-$CPU 94 ;; 95 CYGWIN*|*_NT-*) 96 OS=windows 97 EXE=.exe 98 if [ "x$OSTYPE" = xcygwin ] ; then 99 OS=cygwin 100 HOST_CFLAGS="$CFLAGS -mno-cygwin" 101 HOST_LDFLAGS="$LDFLAGS -mno-cygwin" 102 fi 103 ;; 104 esac 105 106 log2 "OS=$OS" 107 log2 "EXE=$EXE" 108 109 # at this point, the value of OS should be one of the following: 110 # linux-x86 111 # linux-x86_64 112 # darwin-x86 113 # darwin-ppc 114 # windows (MSys) 115 # cygwin 116 # 117 # Note that cygwin is treated as a special case because it behaves very differently 118 # for a few things 119 # 120 # other values may be possible but have not been tested 121 122 # define HOST_OS as $OS without any cpu-specific suffix 123 # 124 case $OS in 125 linux-*) HOST_OS=linux 126 ;; 127 darwin-*) HOST_OS=darwin 128 ;; 129 freebsd-*) HOST_OS=freebsd 130 ;; 131 *) HOST_OS=$OS 132 esac 133 134 # define HOST_ARCH as the $CPU 135 HOST_ARCH=$CPU 136 137 # define HOST_TAG 138 # special case: windows-x86 => windows 139 compute_host_tag () 140 { 141 case $HOST_OS-$HOST_ARCH in 142 cygwin-x86|windows-x86) 143 HOST_TAG=windows 144 ;; 145 *) 146 HOST_TAG=$HOST_OS-$HOST_ARCH 147 ;; 148 esac 149 } 150 compute_host_tag 151 152 #### Toolchain support 153 #### 154 155 # Various probes are going to need to run a small C program 156 TMPC=/tmp/android-$$-test.c 157 TMPO=/tmp/android-$$-test.o 158 TMPE=/tmp/android-$$-test$EXE 159 TMPL=/tmp/android-$$-test.log 160 161 # cleanup temporary files 162 clean_temp () 163 { 164 rm -f $TMPC $TMPO $TMPL $TMPE 165 } 166 167 # cleanup temp files then exit with an error 168 clean_exit () 169 { 170 clean_temp 171 exit 1 172 } 173 174 # this function should be called to enforce the build of 32-bit binaries on 64-bit systems 175 # that support it. 176 FORCE_32BIT=no 177 force_32bit_binaries () 178 { 179 if [ $CPU = x86_64 ] ; then 180 FORCE_32BIT=yes 181 case $OS in 182 linux-x86_64) OS=linux-x86 ;; 183 darwin-x86_64) OS=darwin-x86 ;; 184 freebsd-x86_64) OS=freebsd-x86 ;; 185 esac 186 HOST_ARCH=x86 187 CPU=x86 188 compute_host_tag 189 log "Check32Bits: Forcing generation of 32-bit binaries (--try-64 to disable)" 190 fi 191 } 192 193 # Enable linux-mingw32 compilation. This allows you to build 194 # windows executables on a Linux machine, which is considerably 195 # faster than using Cygwin / MSys to do the same job. 196 # 197 enable_linux_mingw () 198 { 199 # Are we on Linux ? 200 log "Mingw : Checking for Linux host" 201 if [ "$HOST_OS" != "linux" ] ; then 202 echo "Sorry, but mingw compilation is only supported on Linux !" 203 exit 1 204 fi 205 # Do we have the binaries installed 206 log "Mingw : Checking for mingw32 installation" 207 MINGW32_PREFIX=i586-mingw32msvc 208 find_program MINGW32_CC $MINGW32_PREFIX-gcc 209 if [ -z "$MINGW32_CC" ] ; then 210 echo "ERROR: It looks like $MINGW32_PREFIX-gcc is not in your path" 211 echo "Please install the mingw32 package !" 212 exit 1 213 fi 214 log2 "Mingw : Found $MINGW32_CC" 215 CC=$MINGW32_CC 216 LD=$MINGW32_CC 217 AR=$MINGW32_PREFIX-ar 218 FORCE_32BIT=no 219 } 220 221 # Cygwin is normally not supported, unless you call this function 222 # 223 enable_cygwin () 224 { 225 if [ $OS = cygwin ] ; then 226 CFLAGS="$CFLAGS -mno-cygwin" 227 LDFLAGS="$LDFLAGS -mno-cygwin" 228 OS=windows 229 HOST_OS=windows 230 fi 231 } 232 233 # this function will setup the compiler and linker and check that they work as advertized 234 # note that you should call 'force_32bit_binaries' before this one if you want it to work 235 # as advertized. 236 # 237 setup_toolchain () 238 { 239 if [ "$OS" = cygwin ] ; then 240 echo "Do not compile this program or library with Cygwin, use MSYS instead !!" 241 echo "As an experimental feature, you can try to --try-cygwin option to override this" 242 exit 2 243 fi 244 245 if [ -z "$CC" ] ; then 246 CC=gcc 247 if [ $CPU = "powerpc" ] ; then 248 CC=gcc-3.3 249 fi 250 fi 251 252 # check that we can compile a trivial C program with this compiler 253 cat > $TMPC <<EOF 254 int main(void) {} 255 EOF 256 257 if [ $FORCE_32BIT = yes ] ; then 258 CFLAGS="$CFLAGS -m32" 259 LDFLAGS="$LDFLAGS -m32" 260 compile 261 if [ $? != 0 ] ; then 262 # sometimes, we need to also tell the assembler to generate 32-bit binaries 263 # this is highly dependent on your GCC installation (and no, we can't set 264 # this flag all the time) 265 CFLAGS="$CFLAGS -Wa,--32" 266 compile 267 fi 268 fi 269 270 compile 271 if [ $? != 0 ] ; then 272 echo "your C compiler doesn't seem to work: $CC" 273 cat $TMPL 274 clean_exit 275 fi 276 log "CC : compiler check ok ($CC)" 277 278 # check that we can link the trivial program into an executable 279 if [ -z "$LD" ] ; then 280 LD=$CC 281 fi 282 link 283 if [ $? != 0 ] ; then 284 OLD_LD=$LD 285 LD=gcc 286 compile 287 link 288 if [ $? != 0 ] ; then 289 LD=$OLD_LD 290 echo "your linker doesn't seem to work:" 291 cat $TMPL 292 clean_exit 293 fi 294 fi 295 log "LD : linker check ok ($LD)" 296 297 if [ -z "$AR" ]; then 298 AR=ar 299 fi 300 log "AR : archiver ($AR)" 301 } 302 303 # try to compile the current source file in $TMPC into an object 304 # stores the error log into $TMPL 305 # 306 compile () 307 { 308 log2 "Object : $CC -o $TMPO -c $CFLAGS $TMPC" 309 $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL 310 } 311 312 # try to link the recently built file into an executable. error log in $TMPL 313 # 314 link() 315 { 316 log2 "Link : $LD -o $TMPE $TMPO $LDFLAGS" 317 $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL 318 } 319 320 # run a command 321 # 322 execute() 323 { 324 log2 "Running: $*" 325 $* 326 } 327 328 # perform a simple compile / link / run of the source file in $TMPC 329 compile_exec_run() 330 { 331 log2 "RunExec : $CC -o $TMPE $CFLAGS $TMPC" 332 compile 333 if [ $? != 0 ] ; then 334 echo "Failure to compile test program" 335 cat $TMPC 336 cat $TMPL 337 clean_exit 338 fi 339 link 340 if [ $? != 0 ] ; then 341 echo "Failure to link test program" 342 cat $TMPC 343 echo "------" 344 cat $TMPL 345 clean_exit 346 fi 347 $TMPE 348 } 349 350 ## Feature test support 351 ## 352 353 # Each feature test allows us to check against a single target-specific feature 354 # We run the feature checks in a Makefile in order to be able to do them in 355 # parallel, and we also have some cached values in our output directory, just 356 # in case. 357 # 358 # check that a given C program in $TMPC can be compiled on the host system 359 # $1: variable name which will be set to "yes" or "no" depending on result 360 # you can define EXTRA_CFLAGS for extra C compiler flags 361 # for convenience, this variable will be unset by the function 362 # 363 feature_check_compile () 364 { 365 local result_cc=yes 366 local OLD_CFLAGS 367 OLD_CFLAGS="$CFLAGS" 368 CFLAGS="$CFLAGS $EXTRA_CFLAGS" 369 compile 370 if [ $? != 0 ] ; then 371 result_cc=no 372 fi 373 eval $1=$result_cc 374 EXTRA_CFLAGS= 375 CFLAGS=$OLD_CFLAGS 376 } 377 378 # check that a given C program $TMPC can be linked on the host system 379 # $1: variable name which will be set to "yes" or "no" depending on result 380 # you can define EXTRA_CFLAGS for extra C compiler flags 381 # you can define EXTRA_LDFLAGS for extra linker flags 382 # for convenience, these variables will be unset by the function 383 # 384 feature_check_link () 385 { 386 local result_cl=yes 387 local OLD_CFLAGS OLD_LDFLAGS 388 OLD_CFLAGS=$CFLAGS 389 OLD_LDFLAGS=$LDFLAGS 390 CFLAGS="$CFLAGS $EXTRA_CFLAGS" 391 LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" 392 compile 393 if [ $? != 0 ] ; then 394 result_cl=no 395 else 396 link 397 if [ $? != 0 ] ; then 398 result_cl=no 399 fi 400 fi 401 CFLAGS=$OLD_CFLAGS 402 LDFLAGS=$OLD_LDFLAGS 403 eval $1=$result_cl 404 } 405 406 # check that a given C header file exists on the host system 407 # $1: variable name which will be set to "yes" or "no" depending on result 408 # $2: header name 409 # 410 # you can define EXTRA_CFLAGS for extra C compiler flags 411 # for convenience, this variable will be unset by the function. 412 # 413 feature_check_header () 414 { 415 local result_ch 416 log "HeaderCheck: $2" 417 echo "#include $2" > $TMPC 418 cat >> $TMPC <<EOF 419 int main(void) { return 0; } 420 EOF 421 feature_check_compile result_ch 422 eval $1=$result_ch 423 #eval result=$`echo $1` 424 #log "Host : $1=$result_ch" 425 } 426 427 # run the test program that is in $TMPC and set its exit status 428 # in the $1 variable. 429 # you can define EXTRA_CFLAGS and EXTRA_LDFLAGS 430 # 431 feature_run_exec () 432 { 433 local run_exec_result 434 local OLD_CFLAGS="$CFLAGS" 435 local OLD_LDFLAGS="$LDFLAGS" 436 CFLAGS="$CFLAGS $EXTRA_CFLAGS" 437 LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" 438 compile_exec_run 439 run_exec_result=$? 440 CFLAGS="$OLD_CFLAGS" 441 LDFLAGS="$OLD_LDFLAGS" 442 eval $1=$run_exec_result 443 log "Host : $1=$run_exec_result" 444 } 445 446 ## Android build system auto-detection 447 ## 448 449 # check whether we're running within the Android build system 450 # sets the variable IN_ANDROID_BUILD to either "yes" or "no" 451 # 452 # in case of success, defines ANDROID_TOP to point to the top 453 # of the Android source tree. 454 # 455 check_android_build () 456 { 457 unset ANDROID_TOP 458 IN_ANDROID_BUILD=no 459 460 if [ -z "$ANDROID_BUILD_TOP" ] ; then 461 return ; 462 fi 463 464 ANDROID_TOP=$ANDROID_BUILD_TOP 465 log "ANDROID_TOP found at $ANDROID_TOP" 466 # $ANDROID_TOP/config/envsetup.make is for the old tree layout 467 # $ANDROID_TOP/build/envsetup.sh is for the new one 468 ANDROID_CONFIG_MK=$ANDROID_TOP/build/core/config.mk 469 if [ ! -f $ANDROID_CONFIG_MK ] ; then 470 ANDROID_CONFIG_MK=$ANDROID_TOP/config/envsetup.make 471 fi 472 if [ ! -f $ANDROID_CONFIG_MK ] ; then 473 echo "Weird: Cannot find build system root defaulting to non-Android build" 474 unset ANDROID_TOP 475 return 476 fi 477 # normalize ANDROID_TOP, we don't want a trailing / 478 ANDROID_TOPDIR=`dirname $ANDROID_TOP` 479 if [ "$ANDROID_TOPDIR" != "." ] ; then 480 ANDROID_TOP=$ANDROID_TOPDIR/`basename $ANDROID_TOP` 481 fi 482 IN_ANDROID_BUILD=yes 483 } 484 485 # Get the value of an Android build variable as an absolute path. 486 # you should only call this if IN_ANDROID_BUILD is "yes" 487 # 488 get_android_abs_build_var () 489 { 490 (cd $ANDROID_TOP && CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f $ANDROID_CONFIG_MK dumpvar-abs-$1) 491 } 492 493 # Locate the Android prebuilt directory for your os 494 # you should only call this if IN_ANDROID_BUILD is "yes" 495 # 496 # This will set ANDROID_PREBUILT_HOST_TAG, ANDROID_PREBUILT and ANDROID_PREBUILTS 497 # 498 locate_android_prebuilt () 499 { 500 # locate prebuilt directory 501 ANDROID_PREBUILT_HOST_TAG=$OS 502 ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG # AOSP still has it 503 ANDROID_PREBUILTS=$ANDROID_TOP/prebuilts/misc/$ANDROID_PREBUILT_HOST_TAG # AOSP does't have it yet 504 if [ ! -d $ANDROID_PREBUILT ] ; then 505 # this can happen when building on x86_64, or in AOSP 506 case $OS in 507 linux-x86_64) 508 ANDROID_PREBUILT_HOST_TAG=linux-x86 509 ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG 510 ;; 511 *) 512 esac 513 if [ ! -d $ANDROID_PREBUILT ] ; then 514 ANDROID_PREBUILT= 515 fi 516 fi 517 if [ ! -d $ANDROID_PREBUILTS ] ; then 518 # this can happen when building on x86_64 519 case $OS in 520 linux-x86_64) 521 ANDROID_PREBUILT_HOST_TAG=linux-x86 522 ANDROID_PREBUILTS=$ANDROID_TOP/prebuilts/misc/$ANDROID_PREBUILT_HOST_TAG 523 ;; 524 *) 525 esac 526 if [ ! -d $ANDROID_PREBUILTS ] ; then 527 ANDROID_PREBUILTS= 528 fi 529 fi 530 log "Prebuilt : ANDROID_PREBUILT=$ANDROID_PREBUILT" 531 log "Prebuilts : ANDROID_PREBUILTS=$ANDROID_PREBUILTS" 532 } 533 534 ## Build configuration file support 535 ## you must define $config_mk before calling this function 536 ## 537 create_config_mk () 538 { 539 # create the directory if needed 540 local config_dir 541 config_mk=${config_mk:-objs/config.make} 542 config_dir=`dirname $config_mk` 543 mkdir -p $config_dir 2> $TMPL 544 if [ $? != 0 ] ; then 545 echo "Can't create directory for build config file: $config_dir" 546 cat $TMPL 547 clean_exit 548 fi 549 550 # re-create the start of the configuration file 551 log "Generate : $config_mk" 552 553 echo "# This file was autogenerated by $PROGNAME. Do not edit !" > $config_mk 554 echo "OS := $OS" >> $config_mk 555 echo "HOST_OS := $HOST_OS" >> $config_mk 556 echo "HOST_ARCH := $HOST_ARCH" >> $config_mk 557 echo "CC := $CC" >> $config_mk 558 echo "HOST_CC := $CC" >> $config_mk 559 echo "LD := $LD" >> $config_mk 560 echo "AR := $AR" >> $config_mk 561 echo "CFLAGS := $CFLAGS" >> $config_mk 562 echo "LDFLAGS := $LDFLAGS" >> $config_mk 563 } 564 565 add_android_config_mk () 566 { 567 echo "" >> $config_mk 568 if [ $TARGET_ARCH = arm ] ; then 569 echo "TARGET_ARCH := arm" >> $config_mk 570 fi 571 if [ $TARGET_ARCH = x86 ] ; then 572 echo "TARGET_ARCH := x86" >> $config_mk 573 fi 574 echo "HOST_PREBUILT_TAG := $HOST_TAG" >> $config_mk 575 echo "PREBUILT := $ANDROID_PREBUILT" >> $config_mk 576 echo "PREBUILTS := $ANDROID_PREBUILTS" >> $config_mk 577 } 578 579 # Find pattern $1 in string $2 580 # This is to be used in if statements as in: 581 # 582 # if pattern_match <pattern> <string>; then 583 # ... 584 # fi 585 # 586 pattern_match () 587 { 588 echo "$2" | grep -q -E -e "$1" 589 } 590 591 # Find if a given shell program is available. 592 # We need to take care of the fact that the 'which <foo>' command 593 # may return either an empty string (Linux) or something like 594 # "no <foo> in ..." (Darwin). Also, we need to redirect stderr 595 # to /dev/null for Cygwin 596 # 597 # $1: variable name 598 # $2: program name 599 # 600 # Result: set $1 to the full path of the corresponding command 601 # or to the empty/undefined string if not available 602 # 603 find_program () 604 { 605 local PROG 606 PROG=`which $2 2>/dev/null` 607 if [ -n "$PROG" ] ; then 608 if pattern_match '^no ' "$PROG"; then 609 PROG= 610 fi 611 fi 612 eval $1="$PROG" 613 } 614