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 if [ -z "$SRCDIR" ]; then
     75     echo "ERROR: Please provide the path to the toolchain source tree"
     76     exit 1
     77 fi
     78 
     79 GNUSTL_SRCDIR=$SRCDIR/gcc/gcc-$DEFAULT_GCC_VERSION/libstdc++-v3
     80 if [ ! -d "$GNUSTL_SRCDIR" ]; then
     81     echo "ERROR: Not a valid toolchain source tree."
     82     echo "Can't find: $GNUSTL_SRCDIR"
     83     exit 1
     84 fi
     85 
     86 if [ ! -f "$GNUSTL_SRCDIR/configure" ]; then
     87     echo "ERROR: Configure script missing: $GNUSTL_SRCDIR/configure"
     88     exit 1
     89 fi
     90 
     91 ABIS=$(commas_to_spaces $ABIS)
     92 
     93 # Handle NDK_DIR
     94 if [ -z "$NDK_DIR" ] ; then
     95     NDK_DIR=$ANDROID_NDK_ROOT
     96     log "Auto-config: --ndk-dir=$NDK_DIR"
     97 else
     98     if [ ! -d "$NDK_DIR" ] ; then
     99         echo "ERROR: NDK directory does not exists: $NDK_DIR"
    100         exit 1
    101     fi
    102 fi
    103 
    104 if [ -z "$OPTION_BUILD_DIR" ]; then
    105     BUILD_DIR=$NDK_TMPDIR/build-gnustl
    106 else
    107     BUILD_DIR=$OPTION_BUILD_DIR
    108 fi
    109 mkdir -p "$BUILD_DIR"
    110 fail_panic "Could not create build directory: $BUILD_DIR"
    111 
    112 build_gnustl_for_abi ()
    113 {
    114     local ARCH BINPREFIX SYSROOT
    115     local ABI=$1
    116     local BUILDDIR="$2"
    117     local DSTDIR="$3"
    118     local SRC OBJ OBJECTS CFLAGS CXXFLAGS
    119 
    120     prepare_target_build $ABI $PLATFORM $NDK_DIR
    121     fail_panic "Could not setup target build."
    122 
    123     # If the output directory is not specified, use default location
    124     if [ -z "$DSTDIR" ]; then
    125         DSTDIR=$NDK_DIR/$GNUSTL_SUBDIR/libs/$ABI
    126     fi
    127     mkdir -p $DSTDIR
    128 
    129     ARCH=$(convert_abi_to_arch $ABI)
    130     BINPREFIX=$NDK_DIR/$(get_default_toolchain_binprefix_for_arch $ARCH)
    131     SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH)
    132 
    133     # Sanity check
    134     if [ ! -f "$SYSROOT/usr/lib/libc.a" ]; then
    135 	echo "ERROR: Empty sysroot! you probably need to run gen-platforms.sh before this script."
    136 	exit 1
    137     fi
    138     if [ ! -f "$SYSROOT/usr/lib/libc.so" ]; then
    139         echo "ERROR: Sysroot misses shared libraries! you probably need to run gen-platforms.sh"
    140         echo "*without* the --minimal flag before running this script."
    141         exit 1
    142     fi 
    143 
    144     case $ARCH in
    145         arm)
    146             BUILD_HOST=arm-linux-androideabi
    147             ;;
    148         x86)
    149             BUILD_HOST=i686-android-linux
    150             ;;
    151     esac
    152 
    153     export CXXFLAGS="$CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -D__BIONIC__ -O2 -fvisibility=hidden -fvisibility-inlines-hidden"
    154 
    155     export CC=${BINPREFIX}gcc
    156     export CXX=${BINPREFIX}g++
    157     export AS=${BINPREFIX}as
    158     export LD=${BINPREFIX}ld
    159     export AR=${BINPREFIX}ar
    160     export RANLIB=${BINPREFIX}ranlib
    161     export STRIP=${BINPREFIX}strip
    162 
    163     setup_ccache
    164 
    165     export LDFLAGS="-nostdinc -L$SYSROOT/usr/lib -lc"
    166 
    167     PROJECT="GNU libstdc++ $ABI"
    168     echo "$PROJECT: configuring"
    169     mkdir -p $BUILD_DIR/$ABI &&
    170     cd $BUILDDIR &&
    171     run $GNUSTL_SRCDIR/configure \
    172         --prefix=$BUILDDIR/install \
    173         --host=$BUILD_HOST \
    174         --enable-shared --enable-static \
    175         --disable-symvers \
    176         --disable-multilib \
    177         --enable-threads --disable-nls \
    178         --disable-sjlj-exceptions --disable-tls
    179 
    180     fail_panic "Could not configure $PROJECT"
    181 
    182     echo "$PROJECT: compiling"
    183     run make -j$NUM_JOBS
    184     fail_panic "Could not build $PROJECT"
    185 
    186     echo "$PROJECT: installing"
    187     run make install
    188     fail_panic "Could not create $ABI prebuilts for GNU libsupc++/libstdc++"
    189 }
    190 
    191 
    192 HAS_COMMON_HEADERS=
    193 
    194 # $1: ABI
    195 # $2: Build directory
    196 copy_gnustl_libs ()
    197 {
    198     local ABI="$1"
    199     local BUILDDIR="$2"
    200     local ARCH=$(convert_abi_to_arch $ABI)
    201     local VERSION=$DEFAULT_GCC_VERSION
    202     local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH)
    203     PREFIX=${PREFIX%%-}
    204 
    205     local SDIR="$BUILDDIR/install"
    206     local DDIR="$NDK_DIR/$GNUSTL_SUBDIR"
    207 
    208     # Copy the common headers only the first time this function is called.
    209     if [ -z "$HAS_COMMON_HEADERS" ]; then
    210         copy_directory "$SDIR/include/c++/$VERSION" "$DDIR/include"
    211         rm -rf "$DDIR/include/$PREFIX"
    212         HAS_COMMON_HEADERS=true
    213     fi
    214 
    215     rm -rf "$DIR/libs/$ABI" && 
    216     mkdir -p "$DDIR/libs/$ABI/include"
    217 
    218     # Copy the ABI-specific headers
    219     copy_directory "$SDIR/include/c++/$VERSION/$PREFIX/bits" "$DDIR/libs/$ABI/include/bits"
    220 
    221     # Copy the ABI-specific libraries
    222     # Note: the shared library name is libgnustl_shared.so due our custom toolchain patch
    223     # We need to copy libstdc++.so which is identical to libgnustl_shared.so except for the DT_LIBRARY entry
    224     # within the ELF file, since it will be needed by the standalone toolchain installation later.
    225     copy_file_list "$SDIR/lib" "$DDIR/libs/$ABI" libsupc++.a libstdc++.so libgnustl_shared.so
    226     # Note: we need to rename libgnustl_shared.a to libgnustl_static.a
    227     cp "$SDIR/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/libgnustl_static.a"
    228 }
    229 
    230 
    231 
    232 for ABI in $ABIS; do
    233     build_gnustl_for_abi $ABI "$BUILD_DIR/$ABI"
    234     copy_gnustl_libs $ABI "$BUILD_DIR/$ABI"
    235 done
    236 
    237 # If needed, package files into tarballs
    238 if [ -n "$PACKAGE_DIR" ] ; then
    239     # First, the headers as a single package
    240     PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers.tar.bz2"
    241     dump "Packaging: $PACKAGE"
    242     pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/include"
    243 
    244     # Then, one package per ABI for libraries
    245     for ABI in $ABIS; do
    246         FILES=""
    247         for LIB in include/bits libsupc++.a libgnustl_static.a libstdc++.so libgnustl_shared.so; do
    248             FILES="$FILES $GNUSTL_SUBDIR/libs/$ABI/$LIB"
    249         done
    250         PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$ABI.tar.bz2"
    251         dump "Packaging: $PACKAGE"
    252         pack_archive "$PACKAGE" "$NDK_DIR" "$FILES"
    253         fail_panic "Could not package $ABI STLport binaries!"
    254     done
    255 fi
    256 
    257 if [ -z "$OPTION_BUILD_DIR" ]; then
    258     log "Cleaning up..."
    259     rm -rf $BUILD_DIR
    260 else
    261     log "Don't forget to cleanup: $BUILD_DIR"
    262 fi
    263 
    264 log "Done!"
    265