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     esac
    157 
    158     export CXXFLAGS="$CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -D__BIONIC__ -O2"
    159 
    160     export CC=${BINPREFIX}gcc
    161     export CXX=${BINPREFIX}g++
    162     export AS=${BINPREFIX}as
    163     export LD=${BINPREFIX}ld
    164     export AR=${BINPREFIX}ar
    165     export RANLIB=${BINPREFIX}ranlib
    166     export STRIP=${BINPREFIX}strip
    167 
    168     setup_ccache
    169 
    170     export LDFLAGS="-nostdinc -L$SYSROOT/usr/lib -lc"
    171 
    172     LIBTYPE_FLAGS=
    173     if [ $LIBTYPE = "static" ]; then
    174         # Ensure we disable visibility for the static library to reduce the
    175         # size of the code that will be linked against it.
    176         LIBTYPE_FLAG="--enable-static --disable-shared --disable-visibility"
    177         CXXFLAGS=$CXXFLAGS" -fvisibility=hidden -fvisibility-inlines-hidden"
    178     else
    179         LIBTYPE_FLAG="--disable-static --enable-shared"
    180         #LDFLAGS=$LDFLAGS" -lsupc++"
    181     fi
    182 
    183     PROJECT="gnustl_$LIBTYPE $ABI"
    184     echo "$PROJECT: configuring"
    185     mkdir -p $BUILDDIR && rm -rf $BUILDDIR/* &&
    186     cd $BUILDDIR &&
    187     run $GNUSTL_SRCDIR/configure \
    188         --prefix=$INSTALLDIR \
    189         --host=$BUILD_HOST \
    190         $LIBTYPE_FLAGS \
    191         --disable-symvers \
    192         --disable-multilib \
    193         --enable-threads \
    194         --disable-nls \
    195         --disable-sjlj-exceptions \
    196         --disable-tls \
    197         --disable-libstdcxx-pch
    198 
    199     fail_panic "Could not configure $PROJECT"
    200 
    201     echo "$PROJECT: compiling"
    202     run make -j$NUM_JOBS
    203     fail_panic "Could not build $PROJECT"
    204 
    205     echo "$PROJECT: installing"
    206     run make install
    207     fail_panic "Could not create $ABI prebuilts for GNU libsupc++/libstdc++"
    208 }
    209 
    210 
    211 HAS_COMMON_HEADERS=
    212 
    213 # $1: ABI
    214 # $2: Build directory
    215 copy_gnustl_libs ()
    216 {
    217     local ABI="$1"
    218     local BUILDDIR="$2"
    219     local ARCH=$(convert_abi_to_arch $ABI)
    220     local VERSION=$DEFAULT_GCC_VERSION
    221     local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH)
    222     PREFIX=${PREFIX%%-}
    223 
    224     local SDIR="$BUILDDIR/install"
    225     local DDIR="$NDK_DIR/$GNUSTL_SUBDIR"
    226 
    227     # Copy the common headers only the first time this function is called.
    228     if [ -z "$HAS_COMMON_HEADERS" ]; then
    229         copy_directory "$SDIR/include/c++/$VERSION" "$DDIR/include"
    230         rm -rf "$DDIR/include/$PREFIX"
    231         HAS_COMMON_HEADERS=true
    232     fi
    233 
    234     rm -rf "$DIR/libs/$ABI" && 
    235     mkdir -p "$DDIR/libs/$ABI/include"
    236 
    237     # Copy the ABI-specific headers
    238     copy_directory "$SDIR/include/c++/$VERSION/$PREFIX/bits" "$DDIR/libs/$ABI/include/bits"
    239 
    240     # Copy the ABI-specific libraries
    241     # Note: the shared library name is libgnustl_shared.so due our custom toolchain patch
    242     # We need to copy libstdc++.so which is identical to libgnustl_shared.so except for the DT_LIBRARY entry
    243     # within the ELF file, since it will be needed by the standalone toolchain installation later.
    244     copy_file_list "$SDIR/lib" "$DDIR/libs/$ABI" libsupc++.a libstdc++.so libgnustl_shared.so
    245     # Note: we need to rename libgnustl_shared.a to libgnustl_static.a
    246     cp "$SDIR/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/libgnustl_static.a"
    247 }
    248 
    249 
    250 
    251 for ABI in $ABIS; do
    252     build_gnustl_for_abi $ABI "$BUILD_DIR" static
    253     build_gnustl_for_abi $ABI "$BUILD_DIR" shared
    254     copy_gnustl_libs $ABI "$BUILD_DIR"
    255 done
    256 
    257 # If needed, package files into tarballs
    258 if [ -n "$PACKAGE_DIR" ] ; then
    259     # First, the headers as a single package
    260     PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers.tar.bz2"
    261     dump "Packaging: $PACKAGE"
    262     pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/include"
    263 
    264     # Then, one package per ABI for libraries
    265     for ABI in $ABIS; do
    266         FILES=""
    267         for LIB in include/bits libsupc++.a libgnustl_static.a libstdc++.so libgnustl_shared.so; do
    268             FILES="$FILES $GNUSTL_SUBDIR/libs/$ABI/$LIB"
    269         done
    270         PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$ABI.tar.bz2"
    271         dump "Packaging: $PACKAGE"
    272         pack_archive "$PACKAGE" "$NDK_DIR" "$FILES"
    273         fail_panic "Could not package $ABI STLport binaries!"
    274     done
    275 fi
    276 
    277 if [ -z "$OPTION_BUILD_DIR" ]; then
    278     log "Cleaning up..."
    279     rm -rf $BUILD_DIR
    280 else
    281     log "Don't forget to cleanup: $BUILD_DIR"
    282 fi
    283 
    284 log "Done!"
    285