common.sh revision 1af8215c58e5c94432f04ec87d34e429fe7cd7a6
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# 18PROGNAME=`basename $0` 19 20## Logging support 21## 22VERBOSE=yes 23VERBOSE2=no 24 25log () 26{ 27 if [ "$VERBOSE" = "yes" ] ; then 28 echo "$1" 29 fi 30} 31 32log2 () 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# 45var_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 54to_uppercase () 55{ 56 echo $1 | tr "[:lower:]" "[:upper:]" 57} 58 59## Normalize OS and CPU 60## 61 62CPU=`uname -m` 63case "$CPU" in 64 i?86) CPU=x86 65 ;; 66 amd64) CPU=x86_64 67 ;; 68 powerpc) CPU=ppc 69 ;; 70esac 71 72log2 "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 82EXE="" 83OS=`uname -s` 84case "$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 ;; 104esac 105 106log2 "OS=$OS" 107log2 "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# 125case $OS in 126 linux-*) HOST_OS=linux 127 ;; 128 darwin-*) HOST_OS=darwin 129 ;; 130 freebsd-*) HOST_OS=freebsd 131 ;; 132 *) HOST_OS=$OS 133esac 134 135# define HOST_ARCH as the $CPU 136HOST_ARCH=$CPU 137 138# define HOST_TAG 139# special case: windows-x86 => windows 140compute_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} 151compute_host_tag 152 153#### Toolchain support 154#### 155 156# Various probes are going to need to run a small C program 157TMPC=/tmp/android-$$-test.c 158TMPO=/tmp/android-$$-test.o 159TMPE=/tmp/android-$$-test$EXE 160TMPL=/tmp/android-$$-test.log 161 162# cleanup temporary files 163clean_temp () 164{ 165 rm -f $TMPC $TMPO $TMPL $TMPE 166} 167 168# cleanup temp files then exit with an error 169clean_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. 177FORCE_32BIT=no 178force_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# 198enable_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 "Mingw : Checking for mingw32 installation" 208 MINGW32_PREFIX=i586-mingw32msvc 209 find_program MINGW32_CC $MINGW32_PREFIX-gcc 210 if [ -z "$MINGW32_CC" ] ; then 211 echo "ERROR: It looks like $MINGW32_PREFIX-gcc is not in your path" 212 echo "Please install the mingw32 package !" 213 exit 1 214 fi 215 log2 "Mingw : Found $MINGW32_CC" 216 CC=$MINGW32_CC 217 LD=$MINGW32_CC 218 AR=$MINGW32_PREFIX-ar 219 FORCE_32BIT=no 220} 221 222# Cygwin is normally not supported, unless you call this function 223# 224enable_cygwin () 225{ 226 if [ $OS = cygwin ] ; then 227 CFLAGS="$CFLAGS -mno-cygwin" 228 LDFLAGS="$LDFLAGS -mno-cygwin" 229 OS=windows 230 HOST_OS=windows 231 fi 232} 233 234# this function will setup the compiler and linker and check that they work as advertized 235# note that you should call 'force_32bit_binaries' before this one if you want it to work 236# as advertized. 237# 238setup_toolchain () 239{ 240 if [ "$OS" = cygwin ] ; then 241 echo "Do not compile this program or library with Cygwin, use MSYS instead !!" 242 echo "As an experimental feature, you can try to --try-cygwin option to override this" 243 exit 2 244 fi 245 246 if [ -z "$CC" ] ; then 247 CC=gcc 248 if [ $CPU = "powerpc" ] ; then 249 CC=gcc-3.3 250 fi 251 fi 252 253 # check that we can compile a trivial C program with this compiler 254 cat > $TMPC <<EOF 255int main(void) {} 256EOF 257 258 if [ $FORCE_32BIT = yes ] ; then 259 CFLAGS="$CFLAGS -m32" 260 LDFLAGS="$LDFLAGS -m32" 261 compile 262 if [ $? != 0 ] ; then 263 # sometimes, we need to also tell the assembler to generate 32-bit binaries 264 # this is highly dependent on your GCC installation (and no, we can't set 265 # this flag all the time) 266 CFLAGS="$CFLAGS -Wa,--32" 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 clean_temp 302} 303 304# try to compile the current source file in $TMPC into an object 305# stores the error log into $TMPL 306# 307compile () 308{ 309 log2 "Object : $CC -o $TMPO -c $CFLAGS $TMPC" 310 $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL 311} 312 313# try to link the recently built file into an executable. error log in $TMPL 314# 315link() 316{ 317 log2 "Link : $LD -o $TMPE $TMPO $LDFLAGS" 318 $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL 319} 320 321# run a command 322# 323execute() 324{ 325 log2 "Running: $*" 326 $* 327} 328 329# perform a simple compile / link / run of the source file in $TMPC 330compile_exec_run() 331{ 332 log2 "RunExec : $CC -o $TMPE $CFLAGS $TMPC" 333 compile 334 if [ $? != 0 ] ; then 335 echo "Failure to compile test program" 336 cat $TMPC 337 cat $TMPL 338 clean_exit 339 fi 340 link 341 if [ $? != 0 ] ; then 342 echo "Failure to link test program" 343 cat $TMPC 344 echo "------" 345 cat $TMPL 346 clean_exit 347 fi 348 $TMPE 349} 350 351## Feature test support 352## 353 354# Each feature test allows us to check against a single target-specific feature 355# We run the feature checks in a Makefile in order to be able to do them in 356# parallel, and we also have some cached values in our output directory, just 357# in case. 358# 359# check that a given C program in $TMPC can be compiled on the host system 360# $1: variable name which will be set to "yes" or "no" depending on result 361# you can define EXTRA_CFLAGS for extra C compiler flags 362# for convenience, this variable will be unset by the function 363# 364feature_check_compile () 365{ 366 local result_cc=yes 367 local OLD_CFLAGS 368 OLD_CFLAGS="$CFLAGS" 369 CFLAGS="$CFLAGS $EXTRA_CFLAGS" 370 compile 371 if [ $? != 0 ] ; then 372 result_cc=no 373 fi 374 eval $1=$result_cc 375 EXTRA_CFLAGS= 376 CFLAGS=$OLD_CFLAGS 377} 378 379# check that a given C program $TMPC can be linked on the host system 380# $1: variable name which will be set to "yes" or "no" depending on result 381# you can define EXTRA_CFLAGS for extra C compiler flags 382# you can define EXTRA_LDFLAGS for extra linker flags 383# for convenience, these variables will be unset by the function 384# 385feature_check_link () 386{ 387 local result_cl=yes 388 local OLD_CFLAGS OLD_LDFLAGS 389 OLD_CFLAGS=$CFLAGS 390 OLD_LDFLAGS=$LDFLAGS 391 CFLAGS="$CFLAGS $EXTRA_CFLAGS" 392 LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" 393 compile 394 if [ $? != 0 ] ; then 395 result_cl=no 396 else 397 link 398 if [ $? != 0 ] ; then 399 result_cl=no 400 fi 401 fi 402 CFLAGS=$OLD_CFLAGS 403 LDFLAGS=$OLD_LDFLAGS 404 eval $1=$result_cl 405 clean_temp 406} 407 408# check that a given C header file exists on the host system 409# $1: variable name which will be set to "yes" or "no" depending on result 410# $2: header name 411# 412# you can define EXTRA_CFLAGS for extra C compiler flags 413# for convenience, this variable will be unset by the function. 414# 415feature_check_header () 416{ 417 local result_ch 418 log "HeaderCheck: $2" 419 echo "#include $2" > $TMPC 420 cat >> $TMPC <<EOF 421 int main(void) { return 0; } 422EOF 423 feature_check_compile result_ch 424 eval $1=$result_ch 425 #eval result=$`echo $1` 426 #log "Host : $1=$result_ch" 427 clean_temp 428} 429 430# run the test program that is in $TMPC and set its exit status 431# in the $1 variable. 432# you can define EXTRA_CFLAGS and EXTRA_LDFLAGS 433# 434feature_run_exec () 435{ 436 local run_exec_result 437 local OLD_CFLAGS="$CFLAGS" 438 local OLD_LDFLAGS="$LDFLAGS" 439 CFLAGS="$CFLAGS $EXTRA_CFLAGS" 440 LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS" 441 compile_exec_run 442 run_exec_result=$? 443 CFLAGS="$OLD_CFLAGS" 444 LDFLAGS="$OLD_LDFLAGS" 445 eval $1=$run_exec_result 446 log "Host : $1=$run_exec_result" 447 clean_temp 448} 449 450## Android build system auto-detection 451## 452 453# check whether we're running within the Android build system 454# sets the variable IN_ANDROID_BUILD to either "yes" or "no" 455# 456# in case of success, defines ANDROID_TOP to point to the top 457# of the Android source tree. 458# 459check_android_build () 460{ 461 unset ANDROID_TOP 462 IN_ANDROID_BUILD=no 463 464 if [ -z "$ANDROID_BUILD_TOP" ] ; then 465 return ; 466 fi 467 468 ANDROID_TOP=$ANDROID_BUILD_TOP 469 log "ANDROID_TOP found at $ANDROID_TOP" 470 # $ANDROID_TOP/config/envsetup.make is for the old tree layout 471 # $ANDROID_TOP/build/envsetup.sh is for the new one 472 ANDROID_CONFIG_MK=$ANDROID_TOP/build/core/config.mk 473 if [ ! -f $ANDROID_CONFIG_MK ] ; then 474 ANDROID_CONFIG_MK=$ANDROID_TOP/config/envsetup.make 475 fi 476 if [ ! -f $ANDROID_CONFIG_MK ] ; then 477 echo "Weird: Cannot find build system root defaulting to non-Android build" 478 unset ANDROID_TOP 479 return 480 fi 481 # normalize ANDROID_TOP, we don't want a trailing / 482 ANDROID_TOPDIR=`dirname $ANDROID_TOP` 483 if [ "$ANDROID_TOPDIR" != "." ] ; then 484 ANDROID_TOP=$ANDROID_TOPDIR/`basename $ANDROID_TOP` 485 fi 486 IN_ANDROID_BUILD=yes 487} 488 489# Get the value of an Android build variable as an absolute path. 490# you should only call this if IN_ANDROID_BUILD is "yes" 491# 492get_android_abs_build_var () 493{ 494 (cd $ANDROID_TOP && CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f $ANDROID_CONFIG_MK dumpvar-abs-$1) 495} 496 497# Locate the Android prebuilt directory for your os 498# you should only call this if IN_ANDROID_BUILD is "yes" 499# 500# This will set ANDROID_PREBUILT_HOST_TAG, ANDROID_PREBUILT and ANDROID_PREBUILTS 501# 502locate_android_prebuilt () 503{ 504 # locate prebuilt directory 505 ANDROID_PREBUILT_HOST_TAG=$OS 506 ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG # AOSP still has it 507 ANDROID_PREBUILTS=$ANDROID_TOP/prebuilts/misc/$ANDROID_PREBUILT_HOST_TAG # AOSP does't have it yet 508 if [ ! -d $ANDROID_PREBUILT ] ; then 509 # this can happen when building on x86_64, or in AOSP 510 case $OS in 511 linux-x86_64) 512 ANDROID_PREBUILT_HOST_TAG=linux-x86 513 ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG 514 ;; 515 *) 516 esac 517 if [ ! -d $ANDROID_PREBUILT ] ; then 518 ANDROID_PREBUILT= 519 fi 520 fi 521 if [ ! -d $ANDROID_PREBUILTS ] ; then 522 # this can happen when building on x86_64 523 case $OS in 524 linux-x86_64) 525 ANDROID_PREBUILT_HOST_TAG=linux-x86 526 ANDROID_PREBUILTS=$ANDROID_TOP/prebuilts/misc/$ANDROID_PREBUILT_HOST_TAG 527 ;; 528 *) 529 esac 530 if [ ! -d $ANDROID_PREBUILTS ] ; then 531 ANDROID_PREBUILTS= 532 fi 533 fi 534 log "Prebuilt : ANDROID_PREBUILT=$ANDROID_PREBUILT" 535 log "Prebuilts : ANDROID_PREBUILTS=$ANDROID_PREBUILTS" 536} 537 538## Build configuration file support 539## you must define $config_mk before calling this function 540## 541create_config_mk () 542{ 543 # create the directory if needed 544 local config_dir 545 config_mk=${config_mk:-objs/config.make} 546 config_dir=`dirname $config_mk` 547 mkdir -p $config_dir 2> $TMPL 548 if [ $? != 0 ] ; then 549 echo "Can't create directory for build config file: $config_dir" 550 cat $TMPL 551 clean_exit 552 fi 553 554 # re-create the start of the configuration file 555 log "Generate : $config_mk" 556 557 echo "# This file was autogenerated by $PROGNAME. Do not edit !" > $config_mk 558 echo "OS := $OS" >> $config_mk 559 echo "HOST_OS := $HOST_OS" >> $config_mk 560 echo "HOST_ARCH := $HOST_ARCH" >> $config_mk 561 echo "CC := $CC" >> $config_mk 562 echo "LD := $LD" >> $config_mk 563 echo "AR := $AR" >> $config_mk 564 echo "CFLAGS := $CFLAGS" >> $config_mk 565 echo "LDFLAGS := $LDFLAGS" >> $config_mk 566 echo "HOST_CC := $CC" >> $config_mk 567 echo "HOST_LD := $LD" >> $config_mk 568 echo "HOST_AR := $AR" >> $config_mk 569} 570 571add_android_config_mk () 572{ 573 echo "" >> $config_mk 574 if [ $TARGET_ARCH = arm ] ; then 575 echo "TARGET_ARCH := arm" >> $config_mk 576 fi 577 if [ $TARGET_ARCH = x86 ] ; then 578 echo "TARGET_ARCH := x86" >> $config_mk 579 fi 580 echo "HOST_PREBUILT_TAG := $HOST_TAG" >> $config_mk 581 echo "PREBUILT := $ANDROID_PREBUILT" >> $config_mk 582 echo "PREBUILTS := $ANDROID_PREBUILTS" >> $config_mk 583} 584 585# Find pattern $1 in string $2 586# This is to be used in if statements as in: 587# 588# if pattern_match <pattern> <string>; then 589# ... 590# fi 591# 592pattern_match () 593{ 594 echo "$2" | grep -q -E -e "$1" 595} 596 597# Find if a given shell program is available. 598# We need to take care of the fact that the 'which <foo>' command 599# may return either an empty string (Linux) or something like 600# "no <foo> in ..." (Darwin). Also, we need to redirect stderr 601# to /dev/null for Cygwin 602# 603# $1: variable name 604# $2: program name 605# 606# Result: set $1 to the full path of the corresponding command 607# or to the empty/undefined string if not available 608# 609find_program () 610{ 611 local PROG 612 PROG=`which $2 2>/dev/null` 613 if [ -n "$PROG" ] ; then 614 if pattern_match '^no ' "$PROG"; then 615 PROG= 616 fi 617 fi 618 eval $1="$PROG" 619} 620