build-gnu-libstdc++.sh revision bb979c93fc536a7c8fd9e339c5545ae3faa478d5
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-version-list=<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
67VISIBLE_LIBGNUSTL_STATIC=
68register_var_option "--visible-libgnustl-static" VISIBLE_LIBGNUSTL_STATIC "Do not use hidden visibility for libgnustl_static.a"
69
70register_jobs_option
71
72extract_parameters "$@"
73
74SRCDIR=$(echo $PARAMETERS | sed 1q)
75check_toolchain_src_dir "$SRCDIR"
76
77ABIS=$(commas_to_spaces $ABIS)
78
79# Handle NDK_DIR
80if [ -z "$NDK_DIR" ] ; then
81    NDK_DIR=$ANDROID_NDK_ROOT
82    log "Auto-config: --ndk-dir=$NDK_DIR"
83else
84    if [ ! -d "$NDK_DIR" ] ; then
85        echo "ERROR: NDK directory does not exists: $NDK_DIR"
86        exit 1
87    fi
88fi
89
90if [ -z "$OPTION_BUILD_DIR" ]; then
91    BUILD_DIR=$NDK_TMPDIR/build-gnustl
92else
93    BUILD_DIR=$OPTION_BUILD_DIR
94fi
95mkdir -p "$BUILD_DIR"
96fail_panic "Could not create build directory: $BUILD_DIR"
97
98# $1: ABI name
99# $2: Build directory
100# $3: "static" or "shared"
101# $4: GCC version
102# $5: optional "thumb"
103build_gnustl_for_abi ()
104{
105    local ARCH BINPREFIX SYSROOT GNUSTL_SRCDIR
106    local ABI=$1
107    local BUILDDIR="$2"
108    local LIBTYPE="$3"
109    local GCC_VERSION="$4"
110    local THUMB="$5"
111    local DSTDIR=$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION/libs/$ABI/$THUMB
112    local SRC OBJ OBJECTS CFLAGS CXXFLAGS
113
114    prepare_target_build $ABI $PLATFORM $NDK_DIR
115    fail_panic "Could not setup target build."
116
117    INSTALLDIR=$BUILDDIR/install-$ABI-$GCC_VERSION/$THUMB
118    BUILDDIR=$BUILDDIR/$LIBTYPE-${ABI}${THUMB}-$GCC_VERSION
119
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    EXTRA_FLAGS=
163    if [ -n "$THUMB" ] ; then
164        EXTRA_FLAGS="-mthumb"
165    fi
166    export CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
167    export CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -funwind-tables -D__BIONIC__ -O2 $EXTRA_FLAGS"
168    export CPPFLAGS="$CPPFLAGS --sysroot=$SYSROOT"
169
170    export CC=${BINPREFIX}gcc
171    export CXX=${BINPREFIX}g++
172    export AS=${BINPREFIX}as
173    export LD=${BINPREFIX}ld
174    export AR=${BINPREFIX}ar
175    export RANLIB=${BINPREFIX}ranlib
176    export STRIP=${BINPREFIX}strip
177
178    setup_ccache
179
180    export LDFLAGS="-L$SYSROOT/usr/lib -lc $EXTRA_FLAGS"
181
182    if [ "$ABI" = "armeabi-v7a" ]; then
183        CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
184        LDFLAGS=$LDFLAGS" -Wl,--fix-cortex-a8"
185    fi
186
187    LIBTYPE_FLAGS=
188    if [ $LIBTYPE = "static" ]; then
189        # Ensure we disable visibility for the static library to reduce the
190        # size of the code that will be linked against it.
191        if [ -z "$VISIBLE_LIBGNUSTL_STATIC" ] ; then
192            LIBTYPE_FLAGS="--enable-static --disable-shared"
193            if [ $GCC_VERSION = "4.4.3" -o $GCC_VERSION = "4.6" ]; then
194                LIBTYPE_FLAGS=$LIBTYPE_FLAGS" --disable-visibility"
195            else
196                LIBTYPE_FLAGS=$LIBTYPE_FLAGS" --disable-libstdcxx-visibility"
197            fi
198            CXXFLAGS=$CXXFLAGS" -fvisibility=hidden -fvisibility-inlines-hidden"
199        fi
200    else
201        LIBTYPE_FLAGS="--disable-static --enable-shared"
202        #LDFLAGS=$LDFLAGS" -lsupc++"
203    fi
204
205    PROJECT="gnustl_$LIBTYPE gcc-$GCC_VERSION $ABI $THUMB"
206    echo "$PROJECT: configuring"
207    mkdir -p $BUILDDIR && rm -rf $BUILDDIR/* &&
208    cd $BUILDDIR &&
209    run $GNUSTL_SRCDIR/configure \
210        --prefix=$INSTALLDIR \
211        --host=$BUILD_HOST \
212        $LIBTYPE_FLAGS \
213        --enable-libstdcxx-time \
214        --disable-symvers \
215        --disable-multilib \
216        --disable-nls \
217        --disable-sjlj-exceptions \
218        --disable-tls \
219        --disable-libstdcxx-pch \
220        --with-gxx-include-dir=$INSTALLDIR/include/c++/$GCC_VERSION
221
222    fail_panic "Could not configure $PROJECT"
223
224    echo "$PROJECT: compiling"
225    run make -j$NUM_JOBS
226    fail_panic "Could not build $PROJECT"
227
228    echo "$PROJECT: installing"
229    run make install
230    fail_panic "Could not create $ABI $THUMB prebuilts for GNU libsupc++/libstdc++"
231}
232
233
234HAS_COMMON_HEADERS=
235
236# $1: ABI
237# $2: Build directory
238# $3: GCC_VERSION
239copy_gnustl_libs ()
240{
241    local ABI="$1"
242    local BUILDDIR="$2"
243    local ARCH=$(convert_abi_to_arch $ABI)
244    local GCC_VERSION="$3"
245    local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH)
246    PREFIX=${PREFIX%%-}
247
248    local SDIR="$BUILDDIR/install-$ABI-$GCC_VERSION"
249    local DDIR="$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION"
250
251    local GCC_VERSION_NO_DOT=$(echo $GCC_VERSION|sed 's/\./_/g')
252    # Copy the common headers only once per gcc version
253    if [ -z `var_value HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT` ]; then
254        copy_directory "$SDIR/include/c++/$GCC_VERSION" "$DDIR/include"
255        rm -rf "$DDIR/include/$PREFIX"
256	eval HAS_COMMON_HEADERS_$GCC_VERSION_NO_DOT=true
257    fi
258
259    rm -rf "$DDIR/libs/$ABI" &&
260    mkdir -p "$DDIR/libs/$ABI/include"
261
262    # Copy the ABI-specific headers
263    copy_directory "$SDIR/include/c++/$GCC_VERSION/$PREFIX/bits" "$DDIR/libs/$ABI/include/bits"
264
265    # Copy the ABI-specific libraries
266    # Note: the shared library name is libgnustl_shared.so due our custom toolchain patch
267    copy_file_list "$SDIR/lib" "$DDIR/libs/$ABI" libsupc++.a libgnustl_shared.so
268    # Note: we need to rename libgnustl_shared.a to libgnustl_static.a
269    cp "$SDIR/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/libgnustl_static.a"
270    if [ -d "$SDIR/thumb" ] ; then
271        copy_file_list "$SDIR/thumb/lib" "$DDIR/libs/$ABI/thumb" libsupc++.a libgnustl_shared.so
272        cp "$SDIR/thumb/lib/libgnustl_shared.a" "$DDIR/libs/$ABI/thumb/libgnustl_static.a"
273    fi
274}
275
276GCC_VERSION_LIST=$(commas_to_spaces $GCC_VERSION_LIST)
277for VERSION in $GCC_VERSION_LIST; do
278    for ABI in $ABIS; do
279        build_gnustl_for_abi $ABI "$BUILD_DIR" static $VERSION
280        build_gnustl_for_abi $ABI "$BUILD_DIR" shared $VERSION
281        if [ "$ABI" != "${ABI%%arm*}" ] ; then
282            build_gnustl_for_abi $ABI "$BUILD_DIR" static $VERSION thumb
283            build_gnustl_for_abi $ABI "$BUILD_DIR" shared $VERSION thumb
284        fi
285        copy_gnustl_libs $ABI "$BUILD_DIR" $VERSION
286    done
287done
288
289# If needed, package files into tarballs
290if [ -n "$PACKAGE_DIR" ] ; then
291    for VERSION in $GCC_VERSION_LIST; do
292        # First, the headers as a single package for a given gcc version
293        PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers-$VERSION.tar.bz2"
294        dump "Packaging: $PACKAGE"
295        pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/$VERSION/include"
296
297        # Then, one package per version/ABI for libraries
298        for ABI in $ABIS; do
299            FILES=""
300            for LIB in include/bits libsupc++.a libgnustl_static.a libgnustl_shared.so; do
301                FILES="$FILES $GNUSTL_SUBDIR/$VERSION/libs/$ABI/$LIB"
302                THUMB_FILE="$GNUSTL_SUBDIR/$VERSION/libs/$ABI/thumb/$LIB"
303                if [ -f "$NDK_DIR/$THUMB_FILE" ] ; then
304                    FILES="$FILES $THUMB_FILE"
305                fi
306            done
307            PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$VERSION-$ABI.tar.bz2"
308            dump "Packaging: $PACKAGE"
309            pack_archive "$PACKAGE" "$NDK_DIR" "$FILES"
310            fail_panic "Could not package $ABI STLport binaries!"
311        done
312    done
313fi
314
315if [ -z "$OPTION_BUILD_DIR" ]; then
316    log "Cleaning up..."
317    rm -rf $BUILD_DIR
318else
319    log "Don't forget to cleanup: $BUILD_DIR"
320fi
321
322log "Done!"
323