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=$(basename "$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         # Ensure we have unwind tables in the generated machine code
    283         # This is useful to get good stack traces
    284         cflags=$cflags" -funwind-tables"
    285 
    286         obj=$_BUILD_DIR/$obj.o
    287         if [ "$_BUILD_MK" ]; then
    288             echo "$obj: $srcfull" >> $_BUILD_MK
    289         fi
    290         builder_log "${_BUILD_PREFIX}$text: $src"
    291         builder_command $NDK_CCACHE $cc -c -o "$obj" "$srcfull" $cflags
    292         fail_panic "Could not compile ${_BUILD_PREFIX}$src"
    293         _BUILD_OBJECTS=$_BUILD_OBJECTS" $obj"
    294     done
    295 }
    296 
    297 builder_static_library ()
    298 {
    299     local lib libname
    300     libname=$1
    301     if [ -z "$_BUILD_DSTDIR" ]; then
    302         panic "Destination directory not set"
    303     fi
    304     lib=$_BUILD_DSTDIR/$libname
    305     lib=${lib%%.a}.a
    306     if [ "$_BUILD_MK" ]; then
    307         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    308         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    309     fi
    310     if [ -z "${_BUILD_AR}" ]; then
    311         _BUILD_AR=${AR:-ar}
    312     fi
    313     builder_log "${_BUILD_PREFIX}Archive: $libname"
    314     rm -f "$lib"
    315     builder_command ${_BUILD_AR} crs "$lib" "$_BUILD_OBJECTS"
    316     fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
    317 }
    318 
    319 builder_host_static_library ()
    320 {
    321     local lib libname
    322     libname=$1
    323     if [ -z "$_BUILD_DSTDIR" ]; then
    324         panic "Destination directory not set"
    325     fi
    326     lib=$_BUILD_DSTDIR/$libname
    327     lib=${lib%%.a}.a
    328     if [ "$_BUILD_MK" ]; then
    329         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    330         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    331     fi
    332     if [ -z "$BUILD_AR" ]; then
    333         _BUILD_AR=${AR:-ar}
    334     fi
    335     builder_log "${_BUILD_PREFIX}Archive: $libname"
    336     rm -f "$lib"
    337     builder_command ${_BUILD_AR} crs "$lib" "$_BUILD_OBJECTS"
    338     fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
    339 }
    340 
    341 builder_shared_library ()
    342 {
    343     local lib libname
    344     libname=$1
    345     lib=$_BUILD_DSTDIR/$libname
    346     lib=${lib%%.so}.so
    347     if [ "$_BUILD_MK" ]; then
    348         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    349         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    350     fi
    351     builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
    352 
    353     # Important: -lgcc must appear after objects and static libraries,
    354     #            but before shared libraries for Android. It doesn't hurt
    355     #            for other platforms.
    356     builder_command ${_BUILD_CXX} \
    357         -Wl,-soname,$(basename $lib) \
    358         -Wl,-shared,-Bsymbolic \
    359         $_BUILD_LDFLAGS_BEGIN_SO \
    360         $_BUILD_OBJECTS \
    361         $_BUILD_STATIC_LIBRARIES \
    362         -lgcc \
    363         $_BUILD_SHARED_LIBRARIES \
    364         -lc -lm \
    365         $_BUILD_LDFLAGS \
    366         $_BUILD_LDFLAGS_END_SO \
    367         -o $lib
    368     fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
    369 }
    370 
    371 builder_host_shared_library ()
    372 {
    373     local lib libname
    374     libname=$1
    375     lib=$_BUILD_DSTDIR/$libname
    376     lib=${lib%%.so}.so
    377     if [ "$_BUILD_MK" ]; then
    378         _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
    379         echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
    380     fi
    381     builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
    382 
    383     if [ -z "$_BUILD_CXX" ]; then
    384         _BUILD_CXX=${CXX:-g++}
    385     fi
    386 
    387     # Important: -lgcc must appear after objects and static libraries,
    388     #            but before shared libraries for Android. It doesn't hurt
    389     #            for other platforms.
    390     builder_command ${_BUILD_CXX} \
    391         -shared -s \
    392         $_BUILD_OBJECTS \
    393         $_BUILD_STATIC_LIBRARIES \
    394         $_BUILD_SHARED_LIBRARIES \
    395         $_BUILD_LDFLAGS \
    396         -o $lib
    397     fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
    398 }
    399 
    400 builder_host_executable ()
    401 {
    402     local exe exename
    403     exename=$1
    404     exe=$_BUILD_DSTDIR/$exename$HOST_EXE
    405     if [ "$_BUILD_MK" ]; then
    406         _BUILD_TARGETS=$_BUILD_TARGETS" $exe"
    407         echo "$exe: $_BUILD_OBJECTS" >> $_BUILD_MK
    408     fi
    409     builder_log "${_BUILD_PREFIX}Executable: $exename$HOST_EXE"
    410 
    411     if [ -z "$_BUILD_CXX" ]; then
    412         _BUILD_CXX=${CXX:-g++}
    413     fi
    414 
    415     # Important: -lgcc must appear after objects and static libraries,
    416     #            but before shared libraries for Android. It doesn't hurt
    417     #            for other platforms.
    418     builder_command ${_BUILD_CXX} \
    419         -s \
    420         $_BUILD_OBJECTS \
    421         $_BUILD_STATIC_LIBRARIES \
    422         $_BUILD_SHARED_LIBRARIES \
    423         $_BUILD_LDFLAGS \
    424         -o $exe
    425     fail_panic "Could not create ${_BUILD_PREFIX}executable $libname"
    426 }
    427 
    428 
    429 builder_end ()
    430 {
    431     if [ "$_BUILD_MK" ]; then
    432         echo "all: $_BUILD_TARGETS" >> $_BUILD_MK
    433         run make -j$NUM_JOBS -f $_BUILD_MK
    434         fail_panic "Could not build project!"
    435     fi
    436 
    437     if [ "$_BUILD_DIR_NEW" ]; then
    438         log2 "Cleaning up build directory: $_BUILD_DIR"
    439         rm -rf "$_BUILD_DIR"
    440         _BUILD_DIR_NEW=
    441     fi
    442 }
    443 
    444 # Same as builder_begin, but to target Android with a specific ABI
    445 # $1: ABI name (e.g. armeabi)
    446 # $2: Build directory
    447 # $3: Optional llvm version
    448 # $4: Optional Makefile name
    449 builder_begin_android ()
    450 {
    451     local ABI BUILDDIR LLVM_VERSION MAKEFILE
    452     local ARCH UNKNOWN_ARCH PLATFORM SYSROOT FLAGS
    453     local CRTBEGIN_SO_O CRTEND_SO_O CRTBEGIN_EXE_SO CRTEND_SO_O
    454     local BINPREFIX GCC_TOOLCHAIN LLVM_TRIPLE
    455     if [ -z "$NDK_DIR" ]; then
    456         panic "NDK_DIR is not defined!"
    457     elif [ ! -d "$NDK_DIR/platforms" ]; then
    458         panic "Missing directory: $NDK_DIR/platforms"
    459     fi
    460     ABI=$1
    461     BUILDDIR=$2
    462     LLVM_VERSION=$3
    463     MAKEFILE=$4
    464     ARCH=$(convert_abi_to_arch $ABI)
    465     UNKNOWN_ARCH=$(find_ndk_unknown_archs | grep $ARCH)
    466     PLATFORM=${2##android-}
    467     SYSROOT=$NDK_DIR/platforms/android-$PLATFORM/arch-$ARCH
    468 
    469     if [ ! -z "$UNKNOWN_ARCH" ]; then
    470         LLVM_VERSION=$DEFAULT_LLVM_VERSION
    471     fi
    472 
    473     if [ -z "$LLVM_VERSION" ]; then
    474         BINPREFIX=$NDK_DIR/$(get_default_toolchain_binprefix_for_arch $ARCH)
    475     else
    476         BINPREFIX=$NDK_DIR/$(get_llvm_toolchain_binprefix $LLVM_VERSION)
    477         GCC_TOOLCHAIN=`dirname $NDK_DIR/$(get_default_toolchain_binprefix_for_arch $ARCH)`
    478         GCC_TOOLCHAIN=`dirname $GCC_TOOLCHAIN`
    479     fi
    480 
    481     SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH)
    482 
    483     CRTBEGIN_EXE_O=$SYSROOT/usr/lib/crtbegin_dynamic.o
    484     CRTEND_EXE_O=$SYSROOT/usr/lib/crtend_android.o
    485 
    486     CRTBEGIN_SO_O=$SYSROOT/usr/lib/crtbegin_so.o
    487     CRTEND_SO_O=$SYSROOT/usr/lib/crtend_so.o
    488     if [ ! -f "$CRTBEGIN_SO_O" ]; then
    489         CRTBEGIN_SO_O=$CRTBEGIN_EXE_O
    490     fi
    491     if [ ! -f "$CRTEND_SO_O" ]; then
    492         CRTEND_SO_O=$CRTEND_EXE_O
    493     fi
    494 
    495     builder_begin "$BUILDDIR" "$MAKEFILE"
    496     builder_set_prefix "$ABI "
    497     if [ -z "$LLVM_VERSION" ]; then
    498         builder_set_binprefix "$BINPREFIX"
    499     else
    500         builder_set_binprefix_llvm "$BINPREFIX"
    501         case $ABI in
    502             armeabi)
    503                 LLVM_TRIPLE=armv5te-none-linux-androideabi
    504                 ;;
    505             armeabi-v7a)
    506                 LLVM_TRIPLE=armv7-none-linux-androideabi
    507                 ;;
    508             x86)
    509                 LLVM_TRIPLE=i686-none-linux-android
    510                 ;;
    511             mips)
    512                 LLVM_TRIPLE=mipsel-none-linux-android
    513                 ;;
    514             *)
    515                 LLVM_TRIPLE=le32-none-ndk
    516                 GCC_TOOLCHAIN=
    517                 CRTBEGIN_SO_O=
    518                 CRTEND_SO_O=
    519                 CRTBEGIN_EXE_O=
    520                 CRTEND_EXE_O=
    521                 FLAGS=-emit-llvm
    522                 ;;
    523         esac
    524         builder_cflags "-target $LLVM_TRIPLE $FLAGS"
    525         builder_ldflags "-target $LLVM_TRIPLE $FLAGS"
    526         if [ ! -z $GCC_TOOLCHAIN ]; then
    527             builder_cflags "-gcc-toolchain $GCC_TOOLCHAIN"
    528             builder_ldflags "-gcc-toolchain $GCC_TOOLCHAIN"
    529         fi
    530     fi
    531 
    532     builder_cflags "--sysroot=$SYSROOT"
    533     builder_cxxflags "--sysroot=$SYSROOT"
    534     _BUILD_LDFLAGS_BEGIN_SO="--sysroot=$SYSROOT -nostdlib $CRTBEGIN_SO_O"
    535     _BUILD_LDFLAGS_BEGIN_EXE="--sysroot=$SYSROOT -nostdlib $CRTBEGIN_EXE_O"
    536 
    537     _BUILD_LDFLAGS_END_SO="$CRTEND_SO_O"
    538     _BUILD_LDFLAGS_END_EXE="$CRTEND_EXE_O"
    539 
    540     case $ABI in
    541         armeabi)
    542             builder_cflags "-mthumb"
    543             ;;
    544         armeabi-v7a)
    545             builder_cflags "-mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
    546             builder_ldflags "-march=armv7-a -Wl,--fix-cortex-a8"
    547             ;;
    548     esac
    549 }
    550 
    551 # $1: Build directory
    552 # $2: Optional Makefile name
    553 builder_begin_host ()
    554 {
    555     prepare_host_build
    556     builder_begin "$1" "$2"
    557     builder_set_prefix "$HOST_TAG "
    558 }
    559