• 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)
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
109# $1: ABI name
110# $2: Build directory
111# $3: "static" or "shared"
112# $4: Destination directory (optional, will default to $GNUSTL_SUBDIR/lib/$ABI)
113build_gnustl_for_abi ()
114{
115    local ARCH BINPREFIX SYSROOT
116    local ABI=$1
117    local BUILDDIR="$2"
118    local LIBTYPE="$3"
119    local DSTDIR="$4"
120    local SRC OBJ OBJECTS CFLAGS CXXFLAGS
121
122    prepare_target_build $ABI $PLATFORM $NDK_DIR
123    fail_panic "Could not setup target build."
124
125    INSTALLDIR=$BUILDDIR/install
126    BUILDDIR=$BUILDDIR/$LIBTYPE-$ABI
127
128    # If the output directory is not specified, use default location
129    if [ -z "$DSTDIR" ]; then
130        DSTDIR=$NDK_DIR/$GNUSTL_SUBDIR/libs/$ABI
131    fi
132    mkdir -p $DSTDIR
133
134    ARCH=$(convert_abi_to_arch $ABI)
135    BINPREFIX=$NDK_DIR/$(get_default_toolchain_binprefix_for_arch $ARCH)
136    SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH)
137
138    # Sanity check
139    if [ ! -f "$SYSROOT/usr/lib/libc.a" ]; then
140	echo "ERROR: Empty sysroot! you probably need to run gen-platforms.sh before this script."
141	exit 1
142    fi
143    if [ ! -f "$SYSROOT/usr/lib/libc.so" ]; then
144        echo "ERROR: Sysroot misses shared libraries! you probably need to run gen-platforms.sh"
145        echo "*without* the --minimal flag before running this script."
146        exit 1
147    fi
148
149    case $ARCH in
150        arm)
151            BUILD_HOST=arm-linux-androideabi
152            ;;
153        x86)
154            BUILD_HOST=i686-android-linux
155            ;;
156        mips)
157            BUILD_HOST=mipsel-linux-android
158            ;;
159    esac
160
161    export CFLAGS="-fPIC $CFLAGS --sysroot=$SYSROOT -fexceptions -D__BIONIC__ -O2"
162    export CXXFLAGS="-fPIC $CXXFLAGS --sysroot=$SYSROOT -fexceptions -frtti -D__BIONIC__ -O2"
163
164    export CC=${BINPREFIX}gcc
165    export CXX=${BINPREFIX}g++
166    export AS=${BINPREFIX}as
167    export LD=${BINPREFIX}ld
168    export AR=${BINPREFIX}ar
169    export RANLIB=${BINPREFIX}ranlib
170    export STRIP=${BINPREFIX}strip
171
172    setup_ccache
173
174    export LDFLAGS="-nostdinc -L$SYSROOT/usr/lib -lc"
175
176    if [ "$ABI" = "armeabi-v7a" ]; then
177        CXXFLAGS=$CXXFLAGS" -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
178        LDFLAGS=$LDFLAGS" -Wl,--fix-cortex-a8"
179    fi
180
181    if [ "$ABI" = "mips" ]; then
182        LDFLAGS=$LDFLAGS" -Wl,-T,$NDK_DIR/toolchains/mipsel-linux-android-4.4.3/mipself.xsc"
183    fi
184
185    LIBTYPE_FLAGS=
186    if [ $LIBTYPE = "static" ]; then
187        # Ensure we disable visibility for the static library to reduce the
188        # size of the code that will be linked against it.
189        LIBTYPE_FLAGS="--enable-static --disable-shared --disable-visibility"
190        CXXFLAGS=$CXXFLAGS" -fvisibility=hidden -fvisibility-inlines-hidden"
191    else
192        LIBTYPE_FLAGS="--disable-static --enable-shared"
193        #LDFLAGS=$LDFLAGS" -lsupc++"
194    fi
195
196    PROJECT="gnustl_$LIBTYPE $ABI"
197    echo "$PROJECT: configuring"
198    mkdir -p $BUILDDIR && rm -rf $BUILDDIR/* &&
199    cd $BUILDDIR &&
200    run $GNUSTL_SRCDIR/configure \
201        --prefix=$INSTALLDIR \
202        --host=$BUILD_HOST \
203        $LIBTYPE_FLAGS \
204        --disable-symvers \
205        --disable-multilib \
206        --enable-threads \
207        --disable-nls \
208        --disable-sjlj-exceptions \
209        --disable-tls \
210        --disable-libstdcxx-pch
211
212    fail_panic "Could not configure $PROJECT"
213
214    echo "$PROJECT: compiling"
215    run make -j$NUM_JOBS
216    fail_panic "Could not build $PROJECT"
217
218    echo "$PROJECT: installing"
219    run make install
220    fail_panic "Could not create $ABI prebuilts for GNU libsupc++/libstdc++"
221}
222
223
224HAS_COMMON_HEADERS=
225
226# $1: ABI
227# $2: Build directory
228copy_gnustl_libs ()
229{
230    local ABI="$1"
231    local BUILDDIR="$2"
232    local ARCH=$(convert_abi_to_arch $ABI)
233    local VERSION=$DEFAULT_GCC_VERSION
234    local PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH)
235    PREFIX=${PREFIX%%-}
236
237    local SDIR="$BUILDDIR/install"
238    local DDIR="$NDK_DIR/$GNUSTL_SUBDIR"
239
240    # Copy the common headers only the first time this function is called.
241    if [ -z "$HAS_COMMON_HEADERS" ]; then
242        copy_directory "$SDIR/include/c++/$VERSION" "$DDIR/include"
243        rm -rf "$DDIR/include/$PREFIX"
244        HAS_COMMON_HEADERS=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++/$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 ABI in $ABIS; do
263    build_gnustl_for_abi $ABI "$BUILD_DIR" static
264    build_gnustl_for_abi $ABI "$BUILD_DIR" shared
265    copy_gnustl_libs $ABI "$BUILD_DIR"
266done
267
268# If needed, package files into tarballs
269if [ -n "$PACKAGE_DIR" ] ; then
270    # First, the headers as a single package
271    PACKAGE="$PACKAGE_DIR/gnu-libstdc++-headers.tar.bz2"
272    dump "Packaging: $PACKAGE"
273    pack_archive "$PACKAGE" "$NDK_DIR" "$GNUSTL_SUBDIR/include"
274
275    # Then, one package per ABI for libraries
276    for ABI in $ABIS; do
277        FILES=""
278        for LIB in include/bits libsupc++.a libgnustl_static.a libgnustl_shared.so; do
279            FILES="$FILES $GNUSTL_SUBDIR/libs/$ABI/$LIB"
280        done
281        PACKAGE="$PACKAGE_DIR/gnu-libstdc++-libs-$ABI.tar.bz2"
282        dump "Packaging: $PACKAGE"
283        pack_archive "$PACKAGE" "$NDK_DIR" "$FILES"
284        fail_panic "Could not package $ABI STLport binaries!"
285    done
286fi
287
288if [ -z "$OPTION_BUILD_DIR" ]; then
289    log "Cleaning up..."
290    rm -rf $BUILD_DIR
291else
292    log "Don't forget to cleanup: $BUILD_DIR"
293fi
294
295log "Done!"
296