• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    CYGWIN*|*_NT-*)
93        OS=windows
94        EXE=.exe
95        if [ "x$OSTYPE" = xcygwin ] ; then
96            OS=cygwin
97            HOST_CFLAGS="$CFLAGS -mno-cygwin"
98            HOST_LDFLAGS="$LDFLAGS -mno-cygwin"
99        fi
100        ;;
101esac
102
103log2 "OS=$OS"
104log2 "EXE=$EXE"
105
106# at this point, the value of OS should be one of the following:
107#   linux-x86
108#   linux-x86_64
109#   darwin-x86
110#   darwin-ppc
111#   windows  (MSys)
112#   cygwin
113#
114# Note that cygwin is treated as a special case because it behaves very differently
115# for a few things
116#
117# other values may be possible but have not been tested
118
119# define HOST_OS as $OS without any cpu-specific suffix
120#
121case $OS in
122    linux-*) HOST_OS=linux
123    ;;
124    darwin-*) HOST_OS=darwin
125    ;;
126    *) HOST_OS=$OS
127esac
128
129# define HOST_ARCH as the $CPU
130HOST_ARCH=$CPU
131
132#### Toolchain support
133####
134
135# Various probes are going to need to run a small C program
136TMPC=/tmp/android-$$-test.c
137TMPO=/tmp/android-$$-test.o
138TMPE=/tmp/android-$$-test$EXE
139TMPL=/tmp/android-$$-test.log
140
141# cleanup temporary files
142clean_temp ()
143{
144    rm -f $TMPC $TMPO $TMPL $TMPE
145}
146
147# cleanup temp files then exit with an error
148clean_exit ()
149{
150    clean_temp
151    exit 1
152}
153
154# this function should be called to enforce the build of 32-bit binaries on 64-bit systems
155# that support it.
156FORCE_32BIT=no
157force_32bit_binaries ()
158{
159    if [ $CPU = x86_64 ] ; then
160        FORCE_32BIT=yes
161        case $OS in
162            linux-x86_64) OS=linux-x86 ;;
163            darwin-x86_64) OS=darwin-x86 ;;
164        esac
165        HOST_ARCH=x86
166        CPU=x86
167        log "Check32Bits: Forcing generation of 32-bit binaries (--try-64 to disable)"
168    fi
169}
170
171# Cygwin is normally not supported, unless you call this function
172#
173enable_cygwin ()
174{
175    if [ $OS = cygwin ] ; then
176        CFLAGS="$CFLAGS -mno-cygwin"
177        LDFLAGS="$LDFLAGS -mno-cygwin"
178        OS=windows
179        HOST_OS=windows
180    fi
181}
182
183# this function will setup the compiler and linker and check that they work as advertized
184# note that you should call 'force_32bit_binaries' before this one if you want it to work
185# as advertized.
186#
187setup_toolchain ()
188{
189    if [ "$OS" = cygwin ] ; then
190        echo "Do not compile this program or library with Cygwin, use MSYS instead !!"
191        echo "As an experimental feature, you can try to --try-cygwin option to override this"
192        exit 2
193    fi
194
195    if [ -z "$CC" ] ; then
196        CC=gcc
197        if [ $CPU = "powerpc" ] ; then
198            CC=gcc-3.3
199        fi
200    fi
201
202    # check that we can compile a trivial C program with this compiler
203    cat > $TMPC <<EOF
204int main(void) {}
205EOF
206
207    if [ $FORCE_32BIT = yes ] ; then
208        CFLAGS="$CFLAGS -m32"
209        LDFLAGS="$LDFLAGS -m32"
210        compile
211        if [ $? != 0 ] ; then
212            # sometimes, we need to also tell the assembler to generate 32-bit binaries
213            # this is highly dependent on your GCC installation (and no, we can't set
214            # this flag all the time)
215            CFLAGS="$CFLAGS -Wa,--32"
216            compile
217        fi
218    fi
219
220    compile
221    if [ $? != 0 ] ; then
222        echo "your C compiler doesn't seem to work:"
223        cat $TMPL
224        clean_exit
225    fi
226    log "CC         : compiler check ok ($CC)"
227
228    # check that we can link the trivial program into an executable
229    if [ -z "$LD" ] ; then
230        LD=$CC
231    fi
232    link
233    if [ $? != 0 ] ; then
234        OLD_LD=$LD
235        LD=gcc
236        compile
237        link
238        if [ $? != 0 ] ; then
239            LD=$OLD_LD
240            echo "your linker doesn't seem to work:"
241            cat $TMPL
242            clean_exit
243        fi
244    fi
245    log "LD         : linker check ok ($LD)"
246}
247
248# try to compile the current source file in $TMPC into an object
249# stores the error log into $TMPL
250#
251compile ()
252{
253    log2 "Object     : $CC -o $TMPO -c $CFLAGS $TMPC"
254    $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL
255}
256
257# try to link the recently built file into an executable. error log in $TMPL
258#
259link()
260{
261    log2 "Link      : $LD -o $TMPE $TMPO $LDFLAGS"
262    $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL
263}
264
265# run a command
266#
267execute()
268{
269    log2 "Running: $*"
270    $*
271}
272
273# perform a simple compile / link / run of the source file in $TMPC
274compile_exec_run()
275{
276    log2 "RunExec    : $CC -o $TMPE $CFLAGS $TMPC"
277    compile
278    if [ $? != 0 ] ; then
279        echo "Failure to compile test program"
280        cat $TMPC
281        cat $TMPL
282        clean_exit
283    fi
284    link
285    if [ $? != 0 ] ; then
286        echo "Failure to link test program"
287        cat $TMPC
288        echo "------"
289        cat $TMPL
290        clean_exit
291    fi
292    $TMPE
293}
294
295## Feature test support
296##
297
298# Each feature test allows us to check against a single target-specific feature
299# We run the feature checks in a Makefile in order to be able to do them in
300# parallel, and we also have some cached values in our output directory, just
301# in case.
302#
303# check that a given C program in $TMPC can be compiled on the host system
304# $1: variable name which will be set to "yes" or "no" depending on result
305# you can define EXTRA_CFLAGS for extra C compiler flags
306# for convenience, this variable will be unset by the function
307#
308feature_check_compile ()
309{
310    local result_cc=yes
311    local OLD_CFLAGS
312    OLD_CFLAGS="$CFLAGS"
313    CFLAGS="$CFLAGS $EXTRA_CFLAGS"
314    compile
315    if [ $? != 0 ] ; then
316        result_cc=no
317    fi
318    eval $1=$result_cc
319    EXTRA_CFLAGS=
320    CFLAGS=$OLD_CFLAGS
321}
322
323# check that a given C program $TMPC can be linked on the host system
324# $1: variable name which will be set to "yes" or "no" depending on result
325# you can define EXTRA_CFLAGS for extra C compiler flags
326# you can define EXTRA_LDFLAGS for extra linker flags
327# for convenience, these variables will be unset by the function
328#
329feature_check_link ()
330{
331    local result_cl=yes
332    local OLD_CFLAGS OLD_LDFLAGS
333    OLD_CFLAGS=$CFLAGS
334    OLD_LDFLAGS=$LDFLAGS
335    CFLAGS="$CFLAGS $EXTRA_CFLAGS"
336    LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS"
337    compile
338    if [ $? != 0 ] ; then
339        result_cl=no
340    else
341        link
342        if [ $? != 0 ] ; then
343            result_cl=no
344        fi
345    fi
346    CFLAGS=$OLD_CFLAGS
347    LDFLAGS=$OLD_LDFLAGS
348    eval $1=$result_cl
349}
350
351# check that a given C header file exists on the host system
352# $1: variable name which will be set to "yes" or "no" depending on result
353# $2: header name
354#
355# you can define EXTRA_CFLAGS for extra C compiler flags
356# for convenience, this variable will be unset by the function.
357#
358feature_check_header ()
359{
360    local result_ch
361    log2 "HeaderChk  : $2"
362    echo "#include $2" > $TMPC
363    cat >> $TMPC <<EOF
364        int main(void) { return 0; }
365EOF
366    feature_check_compile result_ch
367    eval $1=$result_ch
368    #eval result=$`echo $1`
369    #log  "Host       : $1=$result_ch"
370}
371
372# run the test program that is in $TMPC and set its exit status
373# in the $1 variable.
374# you can define EXTRA_CFLAGS and EXTRA_LDFLAGS
375#
376feature_run_exec ()
377{
378    local run_exec_result
379    local OLD_CFLAGS="$CFLAGS"
380    local OLD_LDFLAGS="$LDFLAGS"
381    CFLAGS="$CFLAGS $EXTRA_CFLAGS"
382    LDFLAGS="$LDFLAGS $EXTRA_LDFLAGS"
383    compile_exec_run
384    run_exec_result=$?
385    CFLAGS="$OLD_CFLAGS"
386    LDFLAGS="$OLD_LDFLAGS"
387    eval $1=$run_exec_result
388    log "Host       : $1=$run_exec_result"
389}
390
391## Android build system auto-detection
392##
393
394# check whether we're running within the Android build system
395# sets the variable IN_ANDROID_BUILD to either "yes" or "no"
396#
397# in case of success, defines ANDROID_TOP to point to the top
398# of the Android source tree.
399#
400check_android_build ()
401{
402    unset ANDROID_TOP
403    IN_ANDROID_BUILD=no
404
405    if [ -z "$ANDROID_PRODUCT_OUT" ] ; then
406        return ;
407    fi
408
409    ANDROID_TOP=`cd $ANDROID_PRODUCT_OUT/../../../.. && pwd`
410    log "ANDROID_TOP found at $ANDROID_TOP"
411    # $ANDROID_TOP/config/envsetup.make is for the old tree layout
412    # $ANDROID_TOP/build/envsetup.sh is for the new one
413    ANDROID_CONFIG_MK=$ANDROID_TOP/build/core/config.mk
414    if [ ! -f $ANDROID_CONFIG_MK ] ; then
415        ANDROID_CONFIG_MK=$ANDROID_TOP/config/envsetup.make
416    fi
417    if [ ! -f $ANDROID_CONFIG_MK ] ; then
418        echo "Weird: Cannot find build system root defaulting to non-Android build"
419        unset ANDROID_TOP
420        return
421    fi
422    # normalize ANDROID_TOP, we don't want a trailing /
423    ANDROID_TOPDIR=`dirname $ANDROID_TOP`
424    if [ "$ANDROID_TOPDIR" != "." ] ; then
425        ANDROID_TOP=$ANDROID_TOPDIR/`basename $ANDROID_TOP`
426    fi
427    IN_ANDROID_BUILD=yes
428}
429
430# Get the value of an Android build variable as an absolute path.
431# you should only call this if IN_ANDROID_BUILD is "yes"
432#
433get_android_abs_build_var ()
434{
435   (cd $ANDROID_TOP && CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f $ANDROID_CONFIG_MK dumpvar-abs-$1)
436}
437
438# Locate the Android prebuilt directory for your os
439# you should only call this if IN_ANDROID_BUILD is "yes"
440#
441# This will set ANDROID_PREBUILT_HOST_TAG and ANDROID_PREBUILT
442#
443locate_android_prebuilt ()
444{
445    # locate prebuilt directory
446    ANDROID_PREBUILT_HOST_TAG=$OS
447    ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG
448    if [ ! -d $ANDROID_PREBUILT ] ; then
449        # this can happen when building on x86_64
450        case $OS in
451            linux-x86_64)
452                ANDROID_PREBUILT_HOST_TAG=linux-x86
453                ANDROID_PREBUILT=$ANDROID_TOP/prebuilt/$ANDROID_PREBUILT_HOST_TAG
454                log "Forcing usage of 32-bit prebuilts"
455                force_32bit_binaries
456                ;;
457            *)
458        esac
459        if [ ! -d $ANDROID_PREBUILT ] ; then
460            echo "Can't find the prebuilt directory $ANDROID_PREBUILT in Android build"
461            exit 1
462        fi
463    fi
464    log "Prebuilt   : ANDROID_PREBUILT=$ANDROID_PREBUILT"
465}
466
467## Build configuration file support
468## you must define $config_mk before calling this function
469##
470create_config_mk ()
471{
472    # create the directory if needed
473    local  config_dir
474    config_mk=${config_mk:-objs/config.make}
475    config_dir=`dirname $config_mk`
476    mkdir -p $config_dir 2> $TMPL
477    if [ $? != 0 ] ; then
478        echo "Can't create directory for build config file: $config_dir"
479        cat $TMPL
480        clean_exit
481    fi
482
483    # re-create the start of the configuration file
484    log "Generate   : $config_mk"
485
486    echo "# This file was autogenerated by $PROGNAME. Do not edit !" > $config_mk
487    echo "OS          := $OS" >> $config_mk
488    echo "HOST_OS     := $HOST_OS" >> $config_mk
489    echo "HOST_ARCH   := $HOST_ARCH" >> $config_mk
490    echo "CC          := $CC" >> $config_mk
491    echo "HOST_CC     := $CC" >> $config_mk
492    echo "LD          := $LD" >> $config_mk
493    echo "CFLAGS      := $CFLAGS" >> $config_mk
494    echo "LDFLAGS     := $LDFLAGS" >> $config_mk
495}
496
497add_android_config_mk ()
498{
499    echo "" >> $config_mk
500    echo "TARGET_ARCH       := arm" >> $config_mk
501    echo "HOST_PREBUILT_TAG := $ANDROID_PREBUILT_HOST_TAG" >> $config_mk
502    echo "PREBUILT          := $ANDROID_PREBUILT" >> $config_mk
503}
504