Home | History | Annotate | Download | only in tools
      1 #
      2 # Copyright (C) 2011 The Android Open Source Project
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #      http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 #
     16 #  This file contains various shell function definitions that can be
     17 #  used to either build a static and shared libraries from sources, or
     18 #  generate a Makefile to do it in parallel.
     19 #
     20 
     21 _BUILD_TAB=$(echo " " | tr ' ' '\t')
     22 
     23 builder_command ()
     24 {
     25     if [ -z "$_BUILD_MK" ]; then
     26         if [ "$VERBOSE2" = "yes" ]; then
     27             echo "$@"
     28         fi
     29         "$@"
     30     else
     31         echo "${_BUILD_TAB}${_BUILD_HIDE}$@" >> $_BUILD_MK
     32     fi
     33 }
     34 
     35 
     36 builder_log ()
     37 {
     38     if [ "$_BUILD_MK" ]; then
     39         echo "${_BUILD_TAB}${_BUILD_HIDE}echo $@" >> $_BUILD_MK
     40     else
     41         log "$@"
     42     fi
     43 }
     44 
     45 # $1: Build directory
     46 # $2: Optional Makefile name
     47 builder_begin ()
     48 {
     49     _BUILD_DIR_NEW=
     50     _BUILD_DIR=$1
     51     if [ ! -d "$_BUILD_DIR" ]; then
     52         mkdir -p "$_BUILD_DIR"
     53         fail_panic "Can't create build directory: $_BUILD_DIR"
     54         _BUILD_DIR_NEW=true
     55     else
     56         rm -rf "$_BUILD_DIR/*"
     57         fail_panic "Can't cleanup build directory: $_BUILD_DIR"
     58     fi
     59     _BUILD_TARGETS=
     60     _BUILD_PREFIX=
     61     _BUILD_MK=$2
     62     if [ -n "$_BUILD_MK" ]; then
     63         log "Creating temporary build Makefile: $_BUILD_MK"
     64         rm -f $_BUILD_MK &&
     65         echo "# Auto-generated by $0 - do not edit!" > $_BUILD_MK
     66         echo ".PHONY: all" >> $_BUILD_MK
     67         echo "all:" >> $_BUILD_MK
     68     fi
     69     # HIDE is used to hide the Makefile output, unless --verbose --verbose
     70     # is used.
     71     if [ "$VERBOSE2" = "yes" ]; then
     72         _BUILD_HIDE=""
     73     else
     74         _BUILD_HIDE=@
     75     fi
     76 
     77     builder_begin_module
     78 }
     79 
     80 # $1: Variable name
     81 # out: Variable value
     82 _builder_varval ()
     83 {
     84     eval echo "\$$1"
     85 }
     86 
     87 _builder_varadd ()
     88 {
     89     local _varname="$1"
     90     local _varval="$(_builder_varval $_varname)"
     91     shift
     92     if [ -z "$_varval" ]; then
     93         eval $_varname=\"$@\"
     94     else
     95         eval $_varname=\$$_varname\" $@\"
     96     fi
     97 }
     98 
     99 
    100 builder_set_prefix ()
    101 {
    102     _BUILD_PREFIX="$@"
    103 }
    104 
    105 builder_begin_module ()
    106 {
    107     _BUILD_CC=
    108     _BUILD_CXX=
    109     _BUILD_AR=
    110     _BUILD_C_INCLUDES=
    111     _BUILD_CFLAGS=
    112     _BUILD_CXXFLAGS=
    113     _BUILD_LDFLAGS_BEGIN_SO=
    114     _BUILD_LDFLAGS_END_SO=
    115     _BUILD_LDFLAGS_BEGIN_EXE=
    116     _BUILD_LDFLAGS_END_EXE=
    117     _BUILD_LDFLAGS=
    118     _BUILD_BINPREFIX=
    119     _BUILD_DSTDIR=
    120     _BUILD_SRCDIR=.
    121     _BUILD_OBJECTS=
    122     _BUILD_STATIC_LIBRARIES=
    123     _BUILD_SHARED_LIBRARIES=
    124 }
    125 
    126 builder_set_binprefix ()
    127 {
    128     _BUILD_BINPREFIX=$1
    129     _BUILD_CC=${1}gcc
    130     _BUILD_CXX=${1}g++
    131     _BUILD_AR=${1}ar
    132 }
    133 
    134 builder_set_binprefix_llvm ()
    135 {
    136     _BUILD_BINPREFIX=$1
    137     _BUILD_CC=${1}clang
    138     _BUILD_CXX=${1}clang++
    139 }
    140 
    141 builder_set_builddir ()
    142 {
    143     _BUILD_DIR=$1
    144 }
    145 
    146 builder_set_srcdir ()
    147 {
    148     _BUILD_SRCDIR=$1
    149 }
    150 
    151 builder_set_dstdir ()
    152 {
    153     _BUILD_DSTDIR=$1
    154 }
    155 
    156 builder_ldflags ()
    157 {
    158     _builder_varadd _BUILD_LDFLAGS "$@"
    159 }
    160 
    161 builder_ldflags_exe ()
    162 {
    163     _builder_varadd _BUILD_LDFLAGS_EXE "$@"
    164 }
    165 
    166 builder_cflags ()
    167 {
    168     _builder_varadd _BUILD_CFLAGS "$@"
    169 }
    170 
    171 builder_cxxflags ()
    172 {
    173     _builder_varadd _BUILD_CXXFLAGS "$@"
    174 }
    175 
    176 builder_c_includes ()
    177 {
    178     _builder_varadd _BUILD_C_INCLUDES "$@"
    179 }
    180 
    181 # $1: optional var to hold the original cflags before reset
    182 builder_reset_cflags ()
    183 {
    184     local _varname="$1"
    185     if [ -n "$_varname" ] ; then
    186         eval $_varname=\"$_BUILD_CFLAGS\"
    187     fi
    188     _BUILD_CFLAGS=
    189 }
    190 
    191 # $1: optional var to hold the original cxxflags before reset
    192 builder_reset_cxxflags ()
    193 {
    194     local _varname="$1"
    195     if [ -n "$_varname" ] ; then
    196         eval $_varname=\"$_BUILD_CXXFLAGS\"
    197     fi
    198     _BUILD_CXXFLAGS=
    199 }
    200 
    201 # $1: optional var to hold the original c_includes before reset
    202 builder_reset_c_includes ()
    203 {
    204     local _varname="$1"
    205     if [ -n "$_varname" ] ; then
    206         eval $_varname=\"$_BUILD_C_INCLUDES\"
    207     fi
    208     _BUILD_C_INCLUDES=
    209 }
    210 
    211 builder_link_with ()
    212 {
    213     local LIB
    214     for LIB; do
    215         case $LIB in
    216             *.a)
    217                 _builder_varadd _BUILD_STATIC_LIBRARIES $LIB
    218                 ;;
    219             *.so)
    220                 _builder_varadd _BUILD_SHARED_LIBRARIES $LIB
    221                 ;;
    222             *)
    223                 echo "ERROR: Unknown link library extension: $LIB"
    224                 exit 1
    225         esac
    226     done
    227 }
    228 
    229 builder_sources ()
    230 {
    231     local src srcfull obj cc cflags text
    232     if [ -z "$_BUILD_DIR" ]; then
    233         panic "Build directory not set!"
    234     fi
    235     if [ -z "$_BUILD_CC" ]; then
    236         _BUILD_CC=${CC:-gcc}
    237     fi
    238     if [ -z "$_BUILD_CXX" ]; then
    239         _BUILD_CXX=${CXX:-g++}
    240     fi
    241     for src in "$@"; do
    242         srcfull=$_BUILD_SRCDIR/$src
    243         if [ ! -f "$srcfull" ]; then
    244             echo "ERROR: Missing source file: $srcfull"
    245             exit 1
    246         fi
    247         obj=$src
    248         cflags="$_BUILD_CFLAGS"
    249         for inc in $_BUILD_C_INCLUDES; do
    250             cflags=$cflags" -I$inc"
    251         done
    252         cflags=$cflags" -I$_BUILD_SRCDIR"
    253         case $obj in
    254             *.c)
    255                 obj=${obj%%.c}
    256                 text="C"
    257                 cc=$_BUILD_CC
    258                 ;;
    259             *.cpp)
    260                 obj=${obj%%.cpp}
    261                 text="C++"
    262                 cc=$_BUILD_CXX
    263                 cflags="$cflags $_BUILD_CXXFLAGS"
    264                 ;;
    265             *.cc)
    266                 obj=${obj%%.cc}
    267                 text="C++"
    268                 cc=$_BUILD_CXX
    269                 cflags="$cflags $_BUILD_CXXFLAGS"
    270                 ;;
    271             *.S|*.s)
    272                 obj=${obj%%.$obj}
    273                 text="ASM"
    274                 cc=$_BUILD_CC
    275                 ;;
    276             *)
    277                 echo "Unknown source file extension: $obj"
    278                 exit 1
    279                 ;;
    280         esac
    281 
    282         # Source file path can include ../ path items, ensure
    283         # that the generated object do not back up the output
    284         # directory by translating them to __/
    285         obj=$(echo "$obj" | tr '../' '__/')
    286 
    287         # Ensure we have unwind tables in the generated machine code
    288         # This is useful to get good stack traces
    289         cflags=$cflags" -funwind-tables"
    290 
    291         obj=$_BUILD_DIR/$obj.o
    292         if [ "$_BUILD_MK" ]; then
    293             echo "$obj: $srcfull" >> $_BUILD_MK
    294         fi
    295         builder_log "${_BUILD_PREFIX}$text: $src"
    296         builder_command mkdir -p $(dirname "$obj")
    297         builder_command $NDK_CCACHE $cc -c -o "$obj" "$srcfull" $cflags
    298         fail_panic "Could not compile ${_BUILD_PREFIX}$src"
    299         _BUILD_OBJECTS=$_BUILD_OBJECTS" $obj"
    300     done
    301 }
    302 
    303 builder_static_library ()
    304 {
    305     local lib libname
    306     libname=$1
    307     if [ -z "$_BUILD_DSTDIR" ]; then
    308         panic "Destination directory not set"
    309     fi
    310     lib=$_BUILD_DSTDIR/$libname
    311     lib=${lib%%.a}.a
    312     if [ "$_BUILD_MK" ]; then
    313         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    314         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    315     fi
    316     if [ -z "${_BUILD_AR}" ]; then
    317         _BUILD_AR=${AR:-ar}
    318     fi
    319     builder_log "${_BUILD_PREFIX}Archive: $libname"
    320     rm -f "$lib"
    321     builder_command ${_BUILD_AR} crs "$lib" "$_BUILD_OBJECTS"
    322     fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
    323 }
    324 
    325 builder_host_static_library ()
    326 {
    327     local lib libname
    328     libname=$1
    329     if [ -z "$_BUILD_DSTDIR" ]; then
    330         panic "Destination directory not set"
    331     fi
    332     lib=$_BUILD_DSTDIR/$libname
    333     lib=${lib%%.a}.a
    334     if [ "$_BUILD_MK" ]; then
    335         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    336         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    337     fi
    338     if [ -z "$BUILD_AR" ]; then
    339         _BUILD_AR=${AR:-ar}
    340     fi
    341     builder_log "${_BUILD_PREFIX}Archive: $libname"
    342     rm -f "$lib"
    343     builder_command ${_BUILD_AR} crs "$lib" "$_BUILD_OBJECTS"
    344     fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
    345 }
    346 
    347 builder_shared_library ()
    348 {
    349     local lib libname
    350     libname=$1
    351     lib=$_BUILD_DSTDIR/$libname
    352     lib=${lib%%.so}.so
    353     if [ "$_BUILD_MK" ]; then
    354         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    355         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    356     fi
    357     builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
    358 
    359     # Important: -lgcc must appear after objects and static libraries,
    360     #            but before shared libraries for Android. It doesn't hurt
    361     #            for other platforms.
    362     builder_command ${_BUILD_CXX} \
    363         -Wl,-soname,$(basename $lib) \
    364         -Wl,-shared,-Bsymbolic \
    365         $_BUILD_LDFLAGS_BEGIN_SO \
    366         $_BUILD_OBJECTS \
    367         $_BUILD_STATIC_LIBRARIES \
    368         -lgcc \
    369         $_BUILD_SHARED_LIBRARIES \
    370         -lc -lm \
    371         $_BUILD_LDFLAGS \
    372         $_BUILD_LDFLAGS_END_SO \
    373         -o $lib
    374     fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
    375 }
    376 
    377 # Same as builder_shared_library, but do not link the default libs
    378 builder_nostdlib_shared_library ()
    379 {
    380     local lib libname
    381     libname=$1
    382     lib=$_BUILD_DSTDIR/$libname
    383     lib=${lib%%.so}.so
    384     if [ "$_BUILD_MK" ]; then
    385         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    386         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    387     fi
    388     builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
    389 
    390     builder_command ${_BUILD_CXX} \
    391         -Wl,-soname,$(basename $lib) \
    392         -Wl,-shared,-Bsymbolic \
    393         $_BUILD_LDFLAGS_BEGIN_SO \
    394         $_BUILD_OBJECTS \
    395         $_BUILD_STATIC_LIBRARIES \
    396         $_BUILD_SHARED_LIBRARIES \
    397         $_BUILD_LDFLAGS \
    398         $_BUILD_LDFLAGS_END_SO \
    399         -o $lib
    400     fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
    401 }
    402 
    403 builder_host_shared_library ()
    404 {
    405     local lib libname
    406     libname=$1
    407     lib=$_BUILD_DSTDIR/$libname
    408     lib=${lib%%.so}.so
    409     if [ "$_BUILD_MK" ]; then
    410         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    411         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    412     fi
    413     builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
    414 
    415     if [ -z "$_BUILD_CXX" ]; then
    416         _BUILD_CXX=${CXX:-g++}
    417     fi
    418 
    419     # Important: -lgcc must appear after objects and static libraries,
    420     #            but before shared libraries for Android. It doesn't hurt
    421     #            for other platforms.
    422     builder_command ${_BUILD_CXX} \
    423         -shared -s \
    424         $_BUILD_OBJECTS \
    425         $_BUILD_STATIC_LIBRARIES \
    426         $_BUILD_SHARED_LIBRARIES \
    427         $_BUILD_LDFLAGS \
    428         -o $lib
    429     fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
    430 }
    431 
    432 builder_host_executable ()
    433 {
    434     local exe exename
    435     exename=$1
    436     exe=$_BUILD_DSTDIR/$exename$HOST_EXE
    437     if [ "$_BUILD_MK" ]; then
    438         _BUILD_TARGETS=$_BUILD_TARGETS" $exe"
    439         echo "$exe: $_BUILD_OBJECTS" >> $_BUILD_MK
    440     fi
    441     builder_log "${_BUILD_PREFIX}Executable: $exename$HOST_EXE"
    442 
    443     if [ -z "$_BUILD_CXX" ]; then
    444         _BUILD_CXX=${CXX:-g++}
    445     fi
    446 
    447     # Important: -lgcc must appear after objects and static libraries,
    448     #            but before shared libraries for Android. It doesn't hurt
    449     #            for other platforms.
    450     builder_command ${_BUILD_CXX} \
    451         -s \
    452         $_BUILD_OBJECTS \
    453         $_BUILD_STATIC_LIBRARIES \
    454         $_BUILD_SHARED_LIBRARIES \
    455         $_BUILD_LDFLAGS \
    456         -o $exe
    457     fail_panic "Could not create ${_BUILD_PREFIX}executable $libname"
    458 }
    459 
    460 
    461 builder_end ()
    462 {
    463     if [ "$_BUILD_MK" ]; then
    464         echo "all: $_BUILD_TARGETS" >> $_BUILD_MK
    465         run make -j$NUM_JOBS -f $_BUILD_MK
    466         fail_panic "Could not build project!"
    467     fi
    468 
    469     if [ "$_BUILD_DIR_NEW" ]; then
    470         log2 "Cleaning up build directory: $_BUILD_DIR"
    471         rm -rf "$_BUILD_DIR"
    472         _BUILD_DIR_NEW=
    473     fi
    474 }
    475 
    476 # Same as builder_begin, but to target Android with a specific ABI
    477 # $1: ABI name (e.g. armeabi)
    478 # $2: Build directory
    479 # $3: Gcc version
    480 # $4: Optional llvm version
    481 # $5: Optional Makefile name
    482 builder_begin_android ()
    483 {
    484     local ABI BUILDDIR LLVM_VERSION MAKEFILE
    485     local ARCH PLATFORM SYSROOT FLAGS
    486     local CRTBEGIN_SO_O CRTEND_SO_O CRTBEGIN_EXE_SO CRTEND_SO_O
    487     local BINPREFIX GCC_TOOLCHAIN LLVM_TRIPLE
    488     if [ -z "$NDK_DIR" ]; then
    489         panic "NDK_DIR is not defined!"
    490     elif [ ! -d "$NDK_DIR/platforms" ]; then
    491         panic "Missing directory: $NDK_DIR/platforms"
    492     fi
    493     ABI=$1
    494     BUILDDIR=$2
    495     GCC_VERSION=$3
    496     LLVM_VERSION=$4
    497     MAKEFILE=$5
    498     ARCH=$(convert_abi_to_arch $ABI)
    499     PLATFORM=${2##android-}
    500     SYSROOT=$NDK_DIR/platforms/android-$PLATFORM/arch-$ARCH
    501 
    502     if [ "$(arch_in_unknown_archs $ARCH)" = "yes" ]; then
    503         LLVM_VERSION=$DEFAULT_LLVM_VERSION
    504     fi
    505 
    506     if [ -z "$LLVM_VERSION" ]; then
    507         BINPREFIX=$NDK_DIR/$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION)
    508     else
    509         BINPREFIX=$NDK_DIR/$(get_llvm_toolchain_binprefix $LLVM_VERSION)
    510         GCC_TOOLCHAIN=`dirname $NDK_DIR/$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION)`
    511         GCC_TOOLCHAIN=`dirname $GCC_TOOLCHAIN`
    512     fi
    513 
    514     SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH)
    515 
    516     CRTBEGIN_EXE_O=$SYSROOT/usr/lib/crtbegin_dynamic.o
    517     CRTEND_EXE_O=$SYSROOT/usr/lib/crtend_android.o
    518 
    519     CRTBEGIN_SO_O=$SYSROOT/usr/lib/crtbegin_so.o
    520     CRTEND_SO_O=$SYSROOT/usr/lib/crtend_so.o
    521     if [ ! -f "$CRTBEGIN_SO_O" ]; then
    522         CRTBEGIN_SO_O=$CRTBEGIN_EXE_O
    523     fi
    524     if [ ! -f "$CRTEND_SO_O" ]; then
    525         CRTEND_SO_O=$CRTEND_EXE_O
    526     fi
    527 
    528     builder_begin "$BUILDDIR" "$MAKEFILE"
    529     builder_set_prefix "$ABI "
    530     if [ -z "$LLVM_VERSION" ]; then
    531         builder_set_binprefix "$BINPREFIX"
    532     else
    533         builder_set_binprefix_llvm "$BINPREFIX"
    534         case $ABI in
    535             armeabi)
    536                 LLVM_TRIPLE=armv5te-none-linux-androideabi
    537                 ;;
    538             armeabi-v7a)
    539                 LLVM_TRIPLE=armv7-none-linux-androideabi
    540                 ;;
    541             x86)
    542                 LLVM_TRIPLE=i686-none-linux-android
    543                 ;;
    544             mips)
    545                 LLVM_TRIPLE=mipsel-none-linux-android
    546                 ;;
    547             *)
    548                 LLVM_TRIPLE=le32-none-ndk
    549                 GCC_TOOLCHAIN=
    550                 CRTBEGIN_SO_O=
    551                 CRTEND_SO_O=
    552                 CRTBEGIN_EXE_O=
    553                 CRTEND_EXE_O=
    554                 FLAGS=-emit-llvm
    555                 ;;
    556         esac
    557         builder_cflags "-target $LLVM_TRIPLE $FLAGS"
    558         builder_ldflags "-target $LLVM_TRIPLE $FLAGS"
    559         if [ ! -z $GCC_TOOLCHAIN ]; then
    560             builder_cflags "-gcc-toolchain $GCC_TOOLCHAIN"
    561             builder_ldflags "-gcc-toolchain $GCC_TOOLCHAIN"
    562         fi
    563     fi
    564 
    565     builder_cflags "--sysroot=$SYSROOT"
    566     builder_cxxflags "--sysroot=$SYSROOT"
    567     _BUILD_LDFLAGS_BEGIN_SO="--sysroot=$SYSROOT -nostdlib $CRTBEGIN_SO_O"
    568     _BUILD_LDFLAGS_BEGIN_EXE="--sysroot=$SYSROOT -nostdlib $CRTBEGIN_EXE_O"
    569 
    570     _BUILD_LDFLAGS_END_SO="$CRTEND_SO_O"
    571     _BUILD_LDFLAGS_END_EXE="$CRTEND_EXE_O"
    572 
    573     case $ABI in
    574         armeabi)
    575             # add -minline-thumb1-jumptable such that gabi++/stlport/libc++ can be linked
    576             # with compiler-rt where helpers __gnu_thumb1_case_* (in libgcc.a) don't exist
    577             builder_cflags "-mthumb -minline-thumb1-jumptable"
    578             ;;
    579         armeabi-v7a)
    580             builder_cflags "-mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
    581             builder_ldflags "-march=armv7-a -Wl,--fix-cortex-a8"
    582             ;;
    583     esac
    584 }
    585 
    586 # $1: Build directory
    587 # $2: Optional Makefile name
    588 builder_begin_host ()
    589 {
    590     prepare_host_build
    591     builder_begin "$1" "$2"
    592     builder_set_prefix "$HOST_TAG "
    593 }
    594