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 "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# 234enable_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# 248setup_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 265int main(void) {} 266EOF 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# 310compile () 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# 318link() 319{ 320 log2 "Link : $LD -o $TMPE $TMPO $LDFLAGS" 321 $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL 322} 323 324# run a command 325# 326execute() 327{ 328 log2 "Running: $*" 329 $* 330} 331 332# perform a simple compile / link / run of the source file in $TMPC 333compile_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# 367feature_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# 388feature_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# 418feature_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; } 425EOF 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# 437feature_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# 462check_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# 495get_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# 505locate_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. 545create_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 577add_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# 598pattern_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# 615find_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