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 25PROGRAM_PARAMETERS="<src-dir>" 26 27PROGRAM_DESCRIPTION=\ 28"Rebuild the prebuilt GNU libsupc++ / libstdc++ binaries for the Android NDK. 29 30This script is called when packaging a new NDK release. It will simply 31rebuild the GNU libsupc++ and libstdc++ static and shared libraries from 32sources. 33 34This requires a temporary NDK installation containing platforms and 35toolchain binaries for all target architectures, as well as the path to 36the corresponding gcc source tree. 37 38By default, this will try with the current NDK directory, unless 39you use the --ndk-dir=<path> option. 40 41The 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> 43option. 44" 45GCC_VERSION_LIST=$DEFAULT_GCC_VERSION_LIST 46register_var_option "--gcc-ver=<vers>" GCC_VERSION_LIST "List of GCC versions" 47 48PACKAGE_DIR= 49register_var_option "--package-dir=<path>" PACKAGE_DIR "Put prebuilt tarballs into <path>." 50 51NDK_DIR= 52register_var_option "--ndk-dir=<path>" NDK_DIR "Specify NDK root path for the build." 53 54BUILD_DIR= 55OPTION_BUILD_DIR= 56register_var_option "--build-dir=<path>" OPTION_BUILD_DIR "Specify temporary build dir." 57 58OUT_DIR= 59register_var_option "--out-dir=<path>" OUT_DIR "Specify output directory directly." 60 61ABIS=$(spaces_to_commas $PREBUILT_ABIS) 62register_var_option "--abis=<list>" ABIS "Specify list of target ABIs." 63 64NO_MAKEFILE= 65register_var_option "--no-makefile" NO_MAKEFILE "Do not use makefile to speed-up build" 66 67register_jobs_option 68 69extract_parameters "$@" 70 71SRCDIR=$(echo $PARAMETERS | sed 1q) 72check_toolchain_src_dir "$SRCDIR" 73 74ABIS=$(commas_to_spaces $ABIS) 75 76# Handle NDK_DIR 77if [ -z "$NDK_DIR" ] ; then 78 NDK_DIR=$ANDROID_NDK_ROOT 79 log "Auto-config: --ndk-dir=$NDK_DIR" 80else 81 if [ ! -d "$NDK_DIR" ] ; then 82 echo "ERROR: NDK directory does not exists: $NDK_DIR" 83 exit 1 84 fi 85fi 86 87if [ -z "$OPTION_BUILD_DIR" ]; then 88 BUILD_DIR=$NDK_TMPDIR/build-gnustl 89else 90 BUILD_DIR=$OPTION_BUILD_DIR 91fi 92mkdir -p "$BUILD_DIR" 93fail_panic "Could not create build directory: $BUILD_DIR" 94 95# $1: ABI name 96# $2: Build directory 97# $3: "static" or "shared" 98# $4: GCC version 99# $5: Destination directory (optional, will default to $GNUSTL_SUBDIR/<gcc-version>/lib/$ABI) 100build_gnustl_for_abi () 101{ 102 local ARCH BINPREFIX SYSROOT GNUSTL_SRCDIR 103 local ABI=$1 104 local BUILDDIR="$2" 105 local LIBTYPE="$3" 106 local GCC_VERSION="$4" 107 local DSTDIR="$5" 108 local SRC OBJ OBJECTS CFLAGS CXXFLAGS 109 110 prepare_target_build $ABI $PLATFORM $NDK_DIR 111 fail_panic "Could not setup target build." 112 113 INSTALLDIR=$BUILDDIR/install 114 BUILDDIR=$BUILDDIR/$LIBTYPE-$ABI-$GCC_VERSION 115 116 # If the output directory is not specified, use default location 117 if [ -z "$DSTDIR" ]; then 118 DSTDIR=$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION/libs/$ABI 119 fi 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 export CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -funwind-tables -D__BIONIC__ -O2" 163 export CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -funwind-tables -D__BIONIC__ -O2" 164 165 export CC=${BINPREFIX}gcc 166 export CXX=${BINPREFIX}g++ 167 export AS=${BINPREFIX}as 168 export LD=${BINPREFIX}ld 169 export AR=${BINPREFIX}ar 170 export RANLIB=${BINPREFIX}ranlib 171 export STRIP=${BINPREFIX}strip 172 173 setup_ccache 174 175 export LDFLAGS="-nostdinc -L$SYSROOT/usr/lib -lc" 176 177 if [ "$ABI" = "armeabi-v7a" ]; then 178 CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16" 179 LDFLAGS=$LDFLAGS" -Wl,--fix-cortex-a8" 180 fi 181 182 LIBTYPE_FLAGS= 183 if [ $LIBTYPE = "static" ]; then 184 # Ensure we disable visibility for the static library to reduce the 185 # size of the code that will be linked against it. 186 LIBTYPE_FLAGS="--enable-static --disable-shared --disable-visibility" 187 CXXFLAGS=$CXXFLAGS" -fvisibility=hidden -fvisibility-inlines-hidden" 188 else 189 LIBTYPE_FLAGS="--disable-static --enable-shared" 190 #LDFLAGS=$LDFLAGS" -lsupc++" 191 fi 192 193 PROJECT="gnustl_$LIBTYPE gcc-$GCC_VERSION $ABI" 194 echo "$PROJECT: configuring" 195 mkdir -p $BUILDDIR && rm -rf $BUILDDIR/* && 196 cd $BUILDDIR && 197 run $GNUSTL_SRCDIR/configure \ 198 --prefix=$INSTALLDIR \ 199 --host=$BUILD_HOST \ 200 $LIBTYPE_FLAGS \ 201 --disable-symvers \ 202 --disable-multilib \ 203 --enable-threads \ 204 --disable-nls \ 205 --disable-sjlj-exceptions \ 206 --disable-tls \ 207 --disable-libstdcxx-pch \ 208 --with-gxx-include-dir=$INSTALLDIR/include/c++/$GCC_VERSION 209 210 fail_panic "Could not configure $PROJECT" 211 212 echo "$PROJECT: compiling" 213 run make -j$NUM_JOBS 214 fail_panic "Could not build $PROJECT" 215 216 echo "$PROJECT: installing" 217 run make install 218 fail_panic "Could not create $ABI prebuilts for GNU libsupc++/libstdc++" 219} 220 221 222HAS_COMMON_HEADERS= 223 224# $1: ABI 225# $2: Build directory 226# $3: GCC_VERSION 227copy_gnustl_libs () 228{ 229 local ABI="$1" 230 local BUILDDIR="$2" 231 local ARCH=$(convert_abi_to_arch $ABI) 232 local GCC_VERSION="$3" 233 local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH) 234 PREFIX=${PREFIX%%-} 235 236 local SDIR="$BUILDDIR/install" 237 local DDIR="$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION" 238 239 local GCC_VERSION_NO_DOT=$(echo $GCC_VERSION|sed 's/\./_/g') 240 # Copy the common headers only once per gcc version 241 if [ -z `var_value HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT` ]; then 242 copy_directory "$SDIR/include/c++/$GCC_VERSION" "$DDIR/include" 243 rm -rf "$DDIR/include/$PREFIX" 244 eval HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT=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++/$GCC_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 262for VERSION in $GCC_VERSION_LIST; do 263 for ABI in $ABIS; do 264 build_gnustl_for_abi $ABI "$BUILD_DIR" static $VERSION 265 build_gnustl_for_abi $ABI "$BUILD_DIR" shared $VERSION 266 copy_gnustl_libs $ABI "$BUILD_DIR" $VERSION 267 done 268done 269 270# If needed, package files into tarballs 271if [ -n "$PACKAGE_DIR" ] ; then 272 for VERSION in $GCC_VERSION_LIST; do 273 # First, the headers as a single package for a given gcc version 274 PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers-$VERSION.tar.bz2" 275 dump "Packaging: $PACKAGE" 276 pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/$VERSION/include" 277 278 # Then, one package per version/ABI for libraries 279 for ABI in $ABIS; do 280 FILES="" 281 for LIB in include/bits libsupc++.a libgnustl_static.a libgnustl_shared.so; do 282 FILES="$FILES $GNUSTL_SUBDIR/$VERSION/libs/$ABI/$LIB" 283 done 284 PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$VERSION-$ABI.tar.bz2" 285 dump "Packaging: $PACKAGE" 286 pack_archive "$PACKAGE" "$NDK_DIR" "$FILES" 287 fail_panic "Could not package $ABI STLport binaries!" 288 done 289 done 290fi 291 292if [ -z "$OPTION_BUILD_DIR" ]; then 293 log "Cleaning up..." 294 rm -rf $BUILD_DIR 295else 296 log "Don't forget to cleanup: $BUILD_DIR" 297fi 298 299log "Done!" 300