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-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# 124case $OS in 125 linux-*) HOST_OS=linux 126 ;; 127 darwin-*) HOST_OS=darwin 128 ;; 129 freebsd-*) HOST_OS=freebsd 130 ;; 131 *) HOST_OS=$OS 132esac 133 134# define HOST_ARCH as the $CPU 135HOST_ARCH=$CPU 136 137# define HOST_TAG 138# special case: windows-x86 => windows 139compute_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} 150compute_host_tag 151 152#### Toolchain support 153#### 154 155# Various probes are going to need to run a small C program 156TMPC=/tmp/android-$$-test.c 157TMPO=/tmp/android-$$-test.o 158TMPE=/tmp/android-$$-test$EXE 159TMPL=/tmp/android-$$-test.log 160 161# cleanup temporary files 162clean_temp () 163{ 164 rm -f $TMPC $TMPO $TMPL $TMPE 165} 166 167# cleanup temp files then exit with an error 168clean_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. 176FORCE_32BIT=no 177force_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# 197enable_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# 223enable_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# 237setup_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 254int main(void) {} 255EOF 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# 306compile () 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# 314link() 315{ 316 log2 "Link : $LD -o $TMPE $TMPO $LDFLAGS" 317 $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL 318} 319 320# run a command 321# 322execute() 323{ 324 log2 "Running: $*" 325 $* 326} 327 328# perform a simple compile / link / run of the source file in $TMPC 329compile_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# 363feature_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# 384feature_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# 413feature_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; } 420EOF 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# 431feature_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# 455check_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# 488get_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# 498locate_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## 537create_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 565add_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# 586pattern_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# 603find_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