• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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