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