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