Home | History | Annotate | Download | only in tools
      1 #!/bin/sh
      2 #
      3 # Copyright (C) 2011 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 #  This shell script is used to rebuild the prebuilt GNU libsupc++ and
     18 #  libstdc++ binaries from their sources. It requires an NDK installation
     19 #  that contains valid plaforms files and toolchain binaries.
     20 #
     21 
     22 # include common function and variable definitions
     23 . `dirname $0`/prebuilt-common.sh
     24 
     25 PROGRAM_PARAMETERS="<src-dir>"
     26 
     27 PROGRAM_DESCRIPTION=\
     28 "Rebuild the prebuilt GNU libsupc++ / libstdc++ binaries for the Android NDK.
     29 
     30 This script is called when packaging a new NDK release. It will simply
     31 rebuild the GNU libsupc++ and libstdc++ static and shared libraries from
     32 sources.
     33 
     34 This requires a temporary NDK installation containing platforms and
     35 toolchain binaries for all target architectures, as well as the path to
     36 the corresponding gcc source tree.
     37 
     38 By default, this will try with the current NDK directory, unless
     39 you use the --ndk-dir=<path> option.
     40 
     41 The output will be placed in appropriate sub-directories of
     42 <ndk>/$GNUSTL_SUBDIR/<gcc-version>, but you can override this with the --out-dir=<path>
     43 option.
     44 "
     45 GCC_VERSION_LIST=$DEFAULT_GCC_VERSION_LIST
     46 register_var_option "--gcc-version-list=<vers>" GCC_VERSION_LIST "List of GCC versions"
     47 
     48 PACKAGE_DIR=
     49 register_var_option "--package-dir=<path>" PACKAGE_DIR "Put prebuilt tarballs into <path>."
     50 
     51 NDK_DIR=
     52 register_var_option "--ndk-dir=<path>" NDK_DIR "Specify NDK root path for the build."
     53 
     54 BUILD_DIR=
     55 OPTION_BUILD_DIR=
     56 register_var_option "--build-dir=<path>" OPTION_BUILD_DIR "Specify temporary build dir."
     57 
     58 OUT_DIR=
     59 register_var_option "--out-dir=<path>" OUT_DIR "Specify output directory directly."
     60 
     61 ABIS=$(spaces_to_commas $PREBUILT_ABIS)
     62 register_var_option "--abis=<list>" ABIS "Specify list of target ABIs."
     63 
     64 NO_MAKEFILE=
     65 register_var_option "--no-makefile" NO_MAKEFILE "Do not use makefile to speed-up build"
     66 
     67 VISIBLE_LIBGNUSTL_STATIC=
     68 register_var_option "--visible-libgnustl-static" VISIBLE_LIBGNUSTL_STATIC "Do not use hidden visibility for libgnustl_static.a"
     69 
     70 register_jobs_option
     71 
     72 extract_parameters "$@"
     73 
     74 SRCDIR=$(echo $PARAMETERS | sed 1q)
     75 check_toolchain_src_dir "$SRCDIR"
     76 
     77 ABIS=$(commas_to_spaces $ABIS)
     78 
     79 # Handle NDK_DIR
     80 if [ -z "$NDK_DIR" ] ; then
     81     NDK_DIR=$ANDROID_NDK_ROOT
     82     log "Auto-config: --ndk-dir=$NDK_DIR"
     83 else
     84     if [ ! -d "$NDK_DIR" ] ; then
     85         echo "ERROR: NDK directory does not exists: $NDK_DIR"
     86         exit 1
     87     fi
     88 fi
     89 
     90 if [ -z "$OPTION_BUILD_DIR" ]; then
     91     BUILD_DIR=$NDK_TMPDIR/build-gnustl
     92 else
     93     BUILD_DIR=$OPTION_BUILD_DIR
     94 fi
     95 mkdir -p "$BUILD_DIR"
     96 fail_panic "Could not create build directory: $BUILD_DIR"
     97 
     98 # $1: ABI name
     99 # $2: Build directory
    100 # $3: "static" or "shared"
    101 # $4: GCC version
    102 # $5: optional "thumb"
    103 build_gnustl_for_abi ()
    104 {
    105     local ARCH BINPREFIX SYSROOT GNUSTL_SRCDIR
    106     local ABI=$1
    107     local BUILDDIR="$2"
    108     local LIBTYPE="$3"
    109     local GCC_VERSION="$4"
    110     local THUMB="$5"
    111     local DSTDIR=$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION/libs/$ABI/$THUMB
    112     local SRC OBJ OBJECTS CFLAGS CXXFLAGS
    113 
    114     prepare_target_build $ABI $PLATFORM $NDK_DIR
    115     fail_panic "Could not setup target build."
    116 
    117     INSTALLDIR=$BUILDDIR/install-$ABI-$GCC_VERSION/$THUMB
    118     BUILDDIR=$BUILDDIR/$LIBTYPE-${ABI}${THUMB}-$GCC_VERSION
    119 
    120     mkdir -p $DSTDIR
    121 
    122     ARCH=$(convert_abi_to_arch $ABI)
    123     BINPREFIX=$NDK_DIR/$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION)
    124 
    125     GNUSTL_SRCDIR=$SRCDIR/gcc/gcc-$GCC_VERSION/libstdc++-v3
    126     # Sanity check
    127     if [ ! -d "$GNUSTL_SRCDIR" ]; then
    128         echo "ERROR: Not a valid toolchain source tree."
    129         echo "Can't find: $GNUSTL_SRCDIR"
    130         exit 1
    131     fi
    132 
    133     if [ ! -f "$GNUSTL_SRCDIR/configure" ]; then
    134         echo "ERROR: Configure script missing: $GNUSTL_SRCDIR/configure"
    135         exit 1
    136     fi
    137 
    138     SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH)
    139     # Sanity check
    140     if [ ! -f "$SYSROOT/usr/lib/libc.a" ]; then
    141 	echo "ERROR: Empty sysroot! you probably need to run gen-platforms.sh before this script."
    142 	exit 1
    143     fi
    144     if [ ! -f "$SYSROOT/usr/lib/libc.so" ]; then
    145         echo "ERROR: Sysroot misses shared libraries! you probably need to run gen-platforms.sh"
    146         echo "*without* the --minimal flag before running this script."
    147         exit 1
    148     fi 
    149 
    150     case $ARCH in
    151         arm)
    152             BUILD_HOST=arm-linux-androideabi
    153             ;;
    154         x86)
    155             BUILD_HOST=i686-linux-android
    156             ;;
    157         mips)
    158             BUILD_HOST=mipsel-linux-android
    159             ;;
    160     esac
    161 
    162     EXTRA_FLAGS=
    163     if [ -n "$THUMB" ] ; then
    164         EXTRA_FLAGS="-mthumb"
    165     fi
    166     export CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
    167     export CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
    168     export CPPFLAGS="$CPPFLAGS --sysroot=$SYSROOT"
    169 
    170     export CC=${BINPREFIX}gcc
    171     export CXX=${BINPREFIX}g++
    172     export AS=${BINPREFIX}as
    173     export LD=${BINPREFIX}ld
    174     export AR=${BINPREFIX}ar
    175     export RANLIB=${BINPREFIX}ranlib
    176     export STRIP=${BINPREFIX}strip
    177 
    178     setup_ccache
    179 
    180     export LDFLAGS="-L$SYSROOT/usr/lib -lc $EXTRA_FLAGS"
    181 
    182     if [ "$ABI" = "armeabi-v7a" ]; then
    183         CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
    184         LDFLAGS=$LDFLAGS" -Wl,--fix-cortex-a8"
    185     fi
    186 
    187     LIBTYPE_FLAGS=
    188     if [ $LIBTYPE = "static" ]; then
    189         # Ensure we disable visibility for the static library to reduce the
    190         # size of the code that will be linked against it.
    191         if [ -z "$VISIBLE_LIBGNUSTL_STATIC" ] ; then
    192             LIBTYPE_FLAGS="--enable-static --disable-shared"
    193             if [ $GCC_VERSION = "4.4.3" -o $GCC_VERSION = "4.6" ]; then
    194                 LIBTYPE_FLAGS=$LIBTYPE_FLAGS" --disable-visibility"
    195             else
    196                 LIBTYPE_FLAGS=$LIBTYPE_FLAGS" --disable-libstdcxx-visibility"
    197             fi
    198             CXXFLAGS=$CXXFLAGS" -fvisibility=hidden -fvisibility-inlines-hidden"
    199         fi
    200     else
    201         LIBTYPE_FLAGS="--disable-static --enable-shared"
    202         #LDFLAGS=$LDFLAGS" -lsupc++"
    203     fi
    204 
    205     PROJECT="gnustl_$LIBTYPE gcc-$GCC_VERSION $ABI $THUMB"
    206     echo "$PROJECT: configuring"
    207     mkdir -p $BUILDDIR && rm -rf $BUILDDIR/* &&
    208     cd $BUILDDIR &&
    209     run $GNUSTL_SRCDIR/configure \
    210         --prefix=$INSTALLDIR \
    211         --host=$BUILD_HOST \
    212         $LIBTYPE_FLAGS \
    213         --enable-libstdcxx-time \
    214         --disable-symvers \
    215         --disable-multilib \
    216         --disable-nls \
    217         --disable-sjlj-exceptions \
    218         --disable-tls \
    219         --disable-libstdcxx-pch \
    220         --with-gxx-include-dir=$INSTALLDIR/include/c++/$GCC_VERSION
    221 
    222     fail_panic "Could not configure $PROJECT"
    223 
    224     echo "$PROJECT: compiling"
    225     run make -j$NUM_JOBS
    226     fail_panic "Could not build $PROJECT"
    227 
    228     echo "$PROJECT: installing"
    229     run make install
    230     fail_panic "Could not create $ABI $THUMB prebuilts for GNU libsupc++/libstdc++"
    231 }
    232 
    233 
    234 HAS_COMMON_HEADERS=
    235 
    236 # $1: ABI
    237 # $2: Build directory
    238 # $3: GCC_VERSION
    239 copy_gnustl_libs ()
    240 {
    241     local ABI="$1"
    242     local BUILDDIR="$2"
    243     local ARCH=$(convert_abi_to_arch $ABI)
    244     local GCC_VERSION="$3"
    245     local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH)
    246     PREFIX=${PREFIX%%-}
    247 
    248     local SDIR="$BUILDDIR/install-$ABI-$GCC_VERSION"
    249     local DDIR="$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION"
    250 
    251     local GCC_VERSION_NO_DOT=$(echo $GCC_VERSION|sed 's/\./_/g')
    252     # Copy the common headers only once per gcc version
    253     if [ -z `var_value HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT` ]; then
    254         copy_directory "$SDIR/include/c++/$GCC_VERSION" "$DDIR/include"
    255         rm -rf "$DDIR/include/$PREFIX"
    256 	eval HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT=true
    257     fi
    258 
    259     rm -rf "$DDIR/libs/$ABI" &&
    260     mkdir -p "$DDIR/libs/$ABI/include"
    261 
    262     # Copy the ABI-specific headers
    263     copy_directory "$SDIR/include/c++/$GCC_VERSION/$PREFIX/bits" "$DDIR/libs/$ABI/include/bits"
    264 
    265     # Copy the ABI-specific libraries
    266     # Note: the shared library name is libgnustl_shared.so due our custom toolchain patch
    267     copy_file_list "$SDIR/lib" "$DDIR/libs/$ABI" libsupc++.a libgnustl_shared.so
    268     # Note: we need to rename libgnustl_shared.a to libgnustl_static.a
    269     cp "$SDIR/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/libgnustl_static.a"
    270     if [ -d "$SDIR/thumb" ] ; then
    271         copy_file_list "$SDIR/thumb/lib" "$DDIR/libs/$ABI/thumb" libsupc++.a libgnustl_shared.so
    272         cp "$SDIR/thumb/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/thumb/libgnustl_static.a"
    273     fi
    274 }
    275 
    276 GCC_VERSION_LIST=$(commas_to_spaces $GCC_VERSION_LIST)
    277 for VERSION in $GCC_VERSION_LIST; do
    278     for ABI in $ABIS; do
    279         build_gnustl_for_abi $ABI "$BUILD_DIR" static $VERSION
    280         build_gnustl_for_abi $ABI "$BUILD_DIR" shared $VERSION
    281         if [ "$ABI" != "${ABI%%arm*}" ] ; then
    282             build_gnustl_for_abi $ABI "$BUILD_DIR" static $VERSION thumb
    283             build_gnustl_for_abi $ABI "$BUILD_DIR" shared $VERSION thumb
    284         fi
    285         copy_gnustl_libs $ABI "$BUILD_DIR" $VERSION
    286     done
    287 done
    288 
    289 # If needed, package files into tarballs
    290 if [ -n "$PACKAGE_DIR" ] ; then
    291     for VERSION in $GCC_VERSION_LIST; do
    292         # First, the headers as a single package for a given gcc version
    293         PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers-$VERSION.tar.bz2"
    294         dump "Packaging: $PACKAGE"
    295         pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/$VERSION/include"
    296 
    297         # Then, one package per version/ABI for libraries
    298         for ABI in $ABIS; do
    299             FILES=""
    300             for LIB in include/bits libsupc++.a libgnustl_static.a libgnustl_shared.so; do
    301                 FILES="$FILES $GNUSTL_SUBDIR/$VERSION/libs/$ABI/$LIB"
    302                 THUMB_FILE="$GNUSTL_SUBDIR/$VERSION/libs/$ABI/thumb/$LIB"
    303                 if [ -f "$NDK_DIR/$THUMB_FILE" ] ; then
    304                     FILES="$FILES $THUMB_FILE"
    305                 fi
    306             done
    307             PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$VERSION-$ABI.tar.bz2"
    308             dump "Packaging: $PACKAGE"
    309             pack_archive "$PACKAGE" "$NDK_DIR" "$FILES"
    310             fail_panic "Could not package $ABI STLport binaries!"
    311         done
    312     done
    313 fi
    314 
    315 if [ -z "$OPTION_BUILD_DIR" ]; then
    316     log "Cleaning up..."
    317     rm -rf $BUILD_DIR
    318 else
    319     log "Don't forget to cleanup: $BUILD_DIR"
    320 fi
    321 
    322 log "Done!"
    323