Home | History | Annotate | Download | only in build
      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 and ANDROID_PREBUILT
    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
    503     if [ ! -d $ANDROID_PREBUILT ] ; then
    504         # this can happen when building on x86_64
    505         case $OS in
    506             linux-x86_64)
    507                 ANDROID_PREBUILT_HOST_TAG=linux-x86
    508                 ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG
    509                 log "Forcing usage of 32-bit prebuilts"
    510                 force_32bit_binaries
    511                 ;;
    512             *)
    513         esac
    514         if [ ! -d $ANDROID_PREBUILT ] ; then
    515             echo "Can't find the prebuilt directory $ANDROID_PREBUILT in Android build"
    516             exit 1
    517         fi
    518     fi
    519     log "Prebuilt   : ANDROID_PREBUILT=$ANDROID_PREBUILT"
    520 }
    521 
    522 ## Build configuration file support
    523 ## you must define $config_mk before calling this function
    524 ##
    525 create_config_mk ()
    526 {
    527     # create the directory if needed
    528     local  config_dir
    529     config_mk=${config_mk:-objs/config.make}
    530     config_dir=`dirname $config_mk`
    531     mkdir -p $config_dir 2> $TMPL
    532     if [ $? != 0 ] ; then
    533         echo "Can't create directory for build config file: $config_dir"
    534         cat $TMPL
    535         clean_exit
    536     fi
    537 
    538     # re-create the start of the configuration file
    539     log "Generate   : $config_mk"
    540 
    541     echo "# This file was autogenerated by $PROGNAME. Do not edit !" > $config_mk
    542     echo "OS          := $OS" >> $config_mk
    543     echo "HOST_OS     := $HOST_OS" >> $config_mk
    544     echo "HOST_ARCH   := $HOST_ARCH" >> $config_mk
    545     echo "CC          := $CC" >> $config_mk
    546     echo "HOST_CC     := $CC" >> $config_mk
    547     echo "LD          := $LD" >> $config_mk
    548     echo "AR          := $AR" >> $config_mk
    549     echo "CFLAGS      := $CFLAGS" >> $config_mk
    550     echo "LDFLAGS     := $LDFLAGS" >> $config_mk
    551 }
    552 
    553 add_android_config_mk ()
    554 {
    555     echo "" >> $config_mk
    556     if [ $TARGET_ARCH = arm ] ; then
    557     echo "TARGET_ARCH       := arm" >> $config_mk
    558     fi
    559     if [ $TARGET_ARCH = x86 ] ; then
    560     echo "TARGET_ARCH       := x86" >> $config_mk
    561     fi
    562     echo "HOST_PREBUILT_TAG := $HOST_TAG" >> $config_mk
    563     echo "PREBUILT          := $ANDROID_PREBUILT" >> $config_mk
    564 }
    565 
    566 # Find pattern $1 in string $2
    567 # This is to be used in if statements as in:
    568 #
    569 #    if pattern_match <pattern> <string>; then
    570 #       ...
    571 #    fi
    572 #
    573 pattern_match ()
    574 {
    575     echo "$2" | grep -q -E -e "$1"
    576 }
    577 
    578 # Find if a given shell program is available.
    579 # We need to take care of the fact that the 'which <foo>' command
    580 # may return either an empty string (Linux) or something like
    581 # "no <foo> in ..." (Darwin). Also, we need to redirect stderr
    582 # to /dev/null for Cygwin
    583 #
    584 # $1: variable name
    585 # $2: program name
    586 #
    587 # Result: set $1 to the full path of the corresponding command
    588 #         or to the empty/undefined string if not available
    589 #
    590 find_program ()
    591 {
    592     local PROG
    593     PROG=`which $2 2>/dev/null`
    594     if [ -n "$PROG" ] ; then
    595         if pattern_match '^no ' "$PROG"; then
    596             PROG=
    597         fi
    598     fi
    599     eval $1="$PROG"
    600 }
    601