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