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, but you can override this with the --out-dir=<path>
     43 option.
     44 "
     45 
     46 PACKAGE_DIR=
     47 register_var_option "--package-dir=<path>" PACKAGE_DIR "Put prebuilt tarballs into <path>."
     48 
     49 NDK_DIR=
     50 register_var_option "--ndk-dir=<path>" NDK_DIR "Specify NDK root path for the build."
     51 
     52 BUILD_DIR=
     53 OPTION_BUILD_DIR=
     54 register_var_option "--build-dir=<path>" OPTION_BUILD_DIR "Specify temporary build dir."
     55 
     56 OUT_DIR=
     57 register_var_option "--out-dir=<path>" OUT_DIR "Specify output directory directly."
     58 
     59 ABIS=$(spaces_to_commas $PREBUILT_ABIS)
     60 register_var_option "--abis=<list>" ABIS "Specify list of target ABIs."
     61 
     62 JOBS="$BUILD_NUM_CPUS"
     63 register_var_option "-j<number>" JOBS "Use <number> build jobs in parallel"
     64 
     65 NO_MAKEFILE=
     66 register_var_option "--no-makefile" NO_MAKEFILE "Do not use makefile to speed-up build"
     67 
     68 NUM_JOBS=$BUILD_NUM_CPUS
     69 register_var_option "-j<number>" NUM_JOBS "Run <number> build jobs in parallel"
     70 
     71 extract_parameters "$@"
     72 
     73 SRCDIR=$(echo $PARAMETERS | sed 1q)
     74 check_toolchain_src_dir "$SRCDIR"
     75 
     76 GNUSTL_SRCDIR=$SRCDIR/gcc/gcc-$DEFAULT_GCC_VERSION/libstdc++-v3
     77 if [ ! -d "$GNUSTL_SRCDIR" ]; then
     78     echo "ERROR: Not a valid toolchain source tree."
     79     echo "Can't find: $GNUSTL_SRCDIR"
     80     exit 1
     81 fi
     82 
     83 if [ ! -f "$GNUSTL_SRCDIR/configure" ]; then
     84     echo "ERROR: Configure script missing: $GNUSTL_SRCDIR/configure"
     85     exit 1
     86 fi
     87 
     88 ABIS=$(commas_to_spaces $ABIS)
     89 
     90 # Handle NDK_DIR
     91 if [ -z "$NDK_DIR" ] ; then
     92     NDK_DIR=$ANDROID_NDK_ROOT
     93     log "Auto-config: --ndk-dir=$NDK_DIR"
     94 else
     95     if [ ! -d "$NDK_DIR" ] ; then
     96         echo "ERROR: NDK directory does not exists: $NDK_DIR"
     97         exit 1
     98     fi
     99 fi
    100 
    101 if [ -z "$OPTION_BUILD_DIR" ]; then
    102     BUILD_DIR=$NDK_TMPDIR/build-gnustl
    103 else
    104     BUILD_DIR=$OPTION_BUILD_DIR
    105 fi
    106 mkdir -p "$BUILD_DIR"
    107 fail_panic "Could not create build directory: $BUILD_DIR"
    108 
    109 # $1: ABI name
    110 # $2: Build directory
    111 # $3: "static" or "shared"
    112 # $4: Destination directory (optional, will default to $GNUSTL_SUBDIR/lib/$ABI)
    113 build_gnustl_for_abi ()
    114 {
    115     local ARCH BINPREFIX SYSROOT
    116     local ABI=$1
    117     local BUILDDIR="$2"
    118     local LIBTYPE="$3"
    119     local DSTDIR="$4"
    120     local SRC OBJ OBJECTS CFLAGS CXXFLAGS
    121 
    122     prepare_target_build $ABI $PLATFORM $NDK_DIR
    123     fail_panic "Could not setup target build."
    124 
    125     INSTALLDIR=$BUILDDIR/install
    126     BUILDDIR=$BUILDDIR/$LIBTYPE-$ABI
    127 
    128     # If the output directory is not specified, use default location
    129     if [ -z "$DSTDIR" ]; then
    130         DSTDIR=$NDK_DIR/$GNUSTL_SUBDIR/libs/$ABI
    131     fi
    132     mkdir -p $DSTDIR
    133 
    134     ARCH=$(convert_abi_to_arch $ABI)
    135     BINPREFIX=$NDK_DIR/$(get_default_toolchain_binprefix_for_arch $ARCH)
    136     SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH)
    137 
    138     # Sanity check
    139     if [ ! -f "$SYSROOT/usr/lib/libc.a" ]; then
    140 	echo "ERROR: Empty sysroot! you probably need to run gen-platforms.sh before this script."
    141 	exit 1
    142     fi
    143     if [ ! -f "$SYSROOT/usr/lib/libc.so" ]; then
    144         echo "ERROR: Sysroot misses shared libraries! you probably need to run gen-platforms.sh"
    145         echo "*without* the --minimal flag before running this script."
    146         exit 1
    147     fi 
    148 
    149     case $ARCH in
    150         arm)
    151             BUILD_HOST=arm-linux-androideabi
    152             ;;
    153         x86)
    154             BUILD_HOST=i686-android-linux
    155             ;;
    156         mips)
    157             BUILD_HOST=mipsel-linux-android
    158             ;;
    159     esac
    160 
    161     export CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -D__BIONIC__ -O2"
    162     export CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -D__BIONIC__ -O2"
    163 
    164     export CC=${BINPREFIX}gcc
    165     export CXX=${BINPREFIX}g++
    166     export AS=${BINPREFIX}as
    167     export LD=${BINPREFIX}ld
    168     export AR=${BINPREFIX}ar
    169     export RANLIB=${BINPREFIX}ranlib
    170     export STRIP=${BINPREFIX}strip
    171 
    172     setup_ccache
    173 
    174     export LDFLAGS="-nostdinc -L$SYSROOT/usr/lib -lc"
    175 
    176     if [ "$ABI" = "armeabi-v7a" ]; then
    177         CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
    178         LDFLAGS=$LDFLAGS" -Wl,--fix-cortex-a8"
    179     fi
    180 
    181     if [ "$ABI" = "mips" ]; then
    182         LDFLAGS=$LDFLAGS" -Wl,-T,$NDK_DIR/toolchains/mipsel-linux-android-4.4.3/mipself.xsc"
    183     fi
    184 
    185     LIBTYPE_FLAGS=
    186     if [ $LIBTYPE = "static" ]; then
    187         # Ensure we disable visibility for the static library to reduce the
    188         # size of the code that will be linked against it.
    189         LIBTYPE_FLAGS="--enable-static --disable-shared --disable-visibility"
    190         CXXFLAGS=$CXXFLAGS" -fvisibility=hidden -fvisibility-inlines-hidden"
    191     else
    192         LIBTYPE_FLAGS="--disable-static --enable-shared"
    193         #LDFLAGS=$LDFLAGS" -lsupc++"
    194     fi
    195 
    196     PROJECT="gnustl_$LIBTYPE $ABI"
    197     echo "$PROJECT: configuring"
    198     mkdir -p $BUILDDIR && rm -rf $BUILDDIR/* &&
    199     cd $BUILDDIR &&
    200     run $GNUSTL_SRCDIR/configure \
    201         --prefix=$INSTALLDIR \
    202         --host=$BUILD_HOST \
    203         $LIBTYPE_FLAGS \
    204         --disable-symvers \
    205         --disable-multilib \
    206         --enable-threads \
    207         --disable-nls \
    208         --disable-sjlj-exceptions \
    209         --disable-tls \
    210         --disable-libstdcxx-pch
    211 
    212     fail_panic "Could not configure $PROJECT"
    213 
    214     echo "$PROJECT: compiling"
    215     run make -j$NUM_JOBS
    216     fail_panic "Could not build $PROJECT"
    217 
    218     echo "$PROJECT: installing"
    219     run make install
    220     fail_panic "Could not create $ABI prebuilts for GNU libsupc++/libstdc++"
    221 }
    222 
    223 
    224 HAS_COMMON_HEADERS=
    225 
    226 # $1: ABI
    227 # $2: Build directory
    228 copy_gnustl_libs ()
    229 {
    230     local ABI="$1"
    231     local BUILDDIR="$2"
    232     local ARCH=$(convert_abi_to_arch $ABI)
    233     local VERSION=$DEFAULT_GCC_VERSION
    234     local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH)
    235     PREFIX=${PREFIX%%-}
    236 
    237     local SDIR="$BUILDDIR/install"
    238     local DDIR="$NDK_DIR/$GNUSTL_SUBDIR"
    239 
    240     # Copy the common headers only the first time this function is called.
    241     if [ -z "$HAS_COMMON_HEADERS" ]; then
    242         copy_directory "$SDIR/include/c++/$VERSION" "$DDIR/include"
    243         rm -rf "$DDIR/include/$PREFIX"
    244         HAS_COMMON_HEADERS=true
    245     fi
    246 
    247     rm -rf "$DIR/libs/$ABI" && 
    248     mkdir -p "$DDIR/libs/$ABI/include"
    249 
    250     # Copy the ABI-specific headers
    251     copy_directory "$SDIR/include/c++/$VERSION/$PREFIX/bits" "$DDIR/libs/$ABI/include/bits"
    252 
    253     # Copy the ABI-specific libraries
    254     # Note: the shared library name is libgnustl_shared.so due our custom toolchain patch
    255     copy_file_list "$SDIR/lib" "$DDIR/libs/$ABI" libsupc++.a libgnustl_shared.so
    256     # Note: we need to rename libgnustl_shared.a to libgnustl_static.a
    257     cp "$SDIR/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/libgnustl_static.a"
    258 }
    259 
    260 
    261 
    262 for ABI in $ABIS; do
    263     build_gnustl_for_abi $ABI "$BUILD_DIR" static
    264     build_gnustl_for_abi $ABI "$BUILD_DIR" shared
    265     copy_gnustl_libs $ABI "$BUILD_DIR"
    266 done
    267 
    268 # If needed, package files into tarballs
    269 if [ -n "$PACKAGE_DIR" ] ; then
    270     # First, the headers as a single package
    271     PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers.tar.bz2"
    272     dump "Packaging: $PACKAGE"
    273     pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/include"
    274 
    275     # Then, one package per ABI for libraries
    276     for ABI in $ABIS; do
    277         FILES=""
    278         for LIB in include/bits libsupc++.a libgnustl_static.a libgnustl_shared.so; do
    279             FILES="$FILES $GNUSTL_SUBDIR/libs/$ABI/$LIB"
    280         done
    281         PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$ABI.tar.bz2"
    282         dump "Packaging: $PACKAGE"
    283         pack_archive "$PACKAGE" "$NDK_DIR" "$FILES"
    284         fail_panic "Could not package $ABI STLport binaries!"
    285     done
    286 fi
    287 
    288 if [ -z "$OPTION_BUILD_DIR" ]; then
    289     log "Cleaning up..."
    290     rm -rf $BUILD_DIR
    291 else
    292     log "Don't forget to cleanup: $BUILD_DIR"
    293 fi
    294 
    295 log "Done!"
    296