1#!/bin/sh
2#
3# Copyright (C) 2010 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 gdbserver binary from
18#  the Android NDK's prebuilt binaries.
19#
20
21# include common function and variable definitions
22. `dirname $0`/prebuilt-common.sh
23
24PROGRAM_PARAMETERS="<src-dir> <ndk-dir> <toolchain>"
25
26PROGRAM_DESCRIPTION=\
27"Rebuild the gdbserver prebuilt binary for the Android NDK toolchain.
28
29Where <src-dir> is the location of the gdbserver sources,
30<ndk-dir> is the top-level NDK installation path and <toolchain>
31is the name of the toolchain to use (e.g. arm-linux-androideabi-4.8).
32
33The final binary is placed under:
34
35    <ndk-dir>/toolchains <toolchain>/prebuilt/gdbserver
36
37NOTE: The --platform option is ignored if --sysroot is used."
38
39VERBOSE=no
40
41OPTION_BUILD_OUT=
42BUILD_OUT=/tmp/ndk-$USER/build/gdbserver
43register_option "--build-out=<path>" do_build_out "Set temporary build directory"
44do_build_out () { OPTION_BUILD_OUT="$1"; }
45
46register_var_option "--platform=<name>"  PLATFORM "Target specific platform"
47
48SYSROOT=
49register_var_option "--sysroot=<path>" SYSROOT "Specify sysroot directory directly"
50
51NOTHREADS=no
52register_var_option "--disable-threads" NOTHREADS "Disable threads support"
53
54GDB_VERSION=
55register_var_option "--gdb-version=<name>" GDB_VERSION "Use specific gdb version."
56
57PACKAGE_DIR=
58register_var_option "--package-dir=<path>" PACKAGE_DIR "Archive binary into specific directory"
59
60register_jobs_option
61
62register_try64_option
63
64extract_parameters "$@"
65
66setup_default_log_file
67
68set_parameters ()
69{
70    SRC_DIR="$1"
71    NDK_DIR="$2"
72    TOOLCHAIN="$3"
73    GDBVER=
74
75    # Check source directory
76    #
77    if [ -z "$SRC_DIR" ] ; then
78        echo "ERROR: Missing source directory parameter. See --help for details."
79        exit 1
80    fi
81
82    if [ -n "$GDB_VERSION" ]; then
83        GDBVER=$GDB_VERSION
84    else
85        GDBVER=$(get_default_gdbserver_version_for_gcc $TOOLCHAIN)
86    fi
87
88    SRC_DIR2="$SRC_DIR/gdb/gdb-$GDBVER/gdb/gdbserver"
89    if [ -d "$SRC_DIR2" ] ; then
90        SRC_DIR="$SRC_DIR2"
91        log "Found gdbserver source directory: $SRC_DIR"
92    fi
93
94    if [ ! -f "$SRC_DIR/gdbreplay.c" ] ; then
95        echo "ERROR: Source directory does not contain gdbserver sources: $SRC_DIR"
96        exit 1
97    fi
98
99    log "Using source directory: $SRC_DIR"
100
101    # Check NDK installation directory
102    #
103    if [ -z "$NDK_DIR" ] ; then
104        echo "ERROR: Missing NDK directory parameter. See --help for details."
105        exit 1
106    fi
107
108    if [ ! -d "$NDK_DIR" ] ; then
109        echo "ERROR: NDK directory does not exist: $NDK_DIR"
110        exit 1
111    fi
112
113    log "Using NDK directory: $NDK_DIR"
114
115    # Check toolchain name
116    #
117    if [ -z "$TOOLCHAIN" ] ; then
118        echo "ERROR: Missing toolchain name parameter. See --help for details."
119        exit 1
120    fi
121}
122
123set_parameters $PARAMETERS
124
125if [ "$PACKAGE_DIR" ]; then
126    mkdir -p "$PACKAGE_DIR"
127    fail_panic "Could not create package directory: $PACKAGE_DIR"
128fi
129
130prepare_target_build
131
132parse_toolchain_name $TOOLCHAIN
133check_toolchain_install $NDK_DIR $TOOLCHAIN
134
135if [ -z "$PLATFORM" ]; then
136    PLATFORM="android-"$(get_default_api_level_for_arch $ARCH)
137fi
138
139# Check build directory
140#
141fix_sysroot "$SYSROOT"
142log "Using sysroot: $SYSROOT"
143
144if [ -n "$OPTION_BUILD_OUT" ] ; then
145    BUILD_OUT="$OPTION_BUILD_OUT"
146fi
147log "Using build directory: $BUILD_OUT"
148run rm -rf "$BUILD_OUT"
149run mkdir -p "$BUILD_OUT"
150
151# Copy the sysroot to a temporary build directory
152BUILD_SYSROOT="$BUILD_OUT/sysroot"
153run mkdir -p "$BUILD_SYSROOT"
154run cp -RHL "$SYSROOT"/* "$BUILD_SYSROOT"
155
156LIBDIR=$(get_default_libdir_for_arch $ARCH)
157
158# Remove libthread_db to ensure we use exactly the one we want.
159rm -f $BUILD_SYSROOT/usr/$LIBDIR/libthread_db*
160rm -f $BUILD_SYSROOT/usr/include/thread_db.h
161
162if [ "$NOTHREADS" != "yes" ] ; then
163    # We're going to rebuild libthread_db.o from its source
164    # that is under sources/android/libthread_db and place its header
165    # and object file into the build sysroot.
166    LIBTHREAD_DB_DIR=$ANDROID_NDK_ROOT/sources/android/libthread_db/gdb-$GDBVER
167    if [ ! -d "$LIBTHREAD_DB_DIR" ] ; then
168        dump "ERROR: Missing directory: $LIBTHREAD_DB_DIR"
169        exit 1
170    fi
171
172    run cp $LIBTHREAD_DB_DIR/thread_db.h $BUILD_SYSROOT/usr/include/
173    run $TOOLCHAIN_PREFIX-gcc --sysroot=$BUILD_SYSROOT -o $BUILD_SYSROOT/usr/$LIBDIR/libthread_db.o -c $LIBTHREAD_DB_DIR/libthread_db.c
174    run $TOOLCHAIN_PREFIX-ar -rD $BUILD_SYSROOT/usr/$LIBDIR/libthread_db.a $BUILD_SYSROOT/usr/$LIBDIR/libthread_db.o
175    if [ $? != 0 ] ; then
176        dump "ERROR: Could not compile libthread_db.c!"
177        exit 1
178    fi
179fi
180
181log "Using build sysroot: $BUILD_SYSROOT"
182
183# configure the gdbserver build now
184dump "Configure: $TOOLCHAIN gdbserver-$GDBVER build with $PLATFORM"
185
186case "$GDBVER" in
187    6.6)
188        CONFIGURE_FLAGS="--with-sysroot=$BUILD_SYSROOT"
189        ;;
190    7.3.x|7.6|7.7)
191        # This flag is required to link libthread_db statically to our
192        # gdbserver binary. Otherwise, the program will try to dlopen()
193        # the threads binary, which is not possible since we build a
194        # static executable.
195        CONFIGURE_FLAGS="--with-libthread-db=$BUILD_SYSROOT/usr/$LIBDIR/libthread_db.a"
196        # Disable libinproctrace.so which needs crtbegin_so.o and crtbend_so.o instead of
197        # CRTBEGIN/END above.  Clean it up and re-enable it in the future.
198        CONFIGURE_FLAGS=$CONFIGURE_FLAGS" --disable-inprocess-agent"
199        ;;
200    *)
201        CONFIGURE_FLAGS=""
202esac
203
204cd $BUILD_OUT &&
205export CC="$TOOLCHAIN_PREFIX-gcc --sysroot=$BUILD_SYSROOT" &&
206export CFLAGS="-O2 $GDBSERVER_CFLAGS"  &&
207export LDFLAGS="-static -Wl,-z,nocopyreloc -Wl,--no-undefined" &&
208run $SRC_DIR/configure \
209--host=$GDBSERVER_HOST \
210$CONFIGURE_FLAGS
211if [ $? != 0 ] ; then
212    dump "Could not configure gdbserver build. See $TMPLOG"
213    exit 1
214fi
215
216# build gdbserver
217dump "Building : $TOOLCHAIN gdbserver."
218cd $BUILD_OUT &&
219run make -j$NUM_JOBS
220if [ $? != 0 ] ; then
221    dump "Could not build $TOOLCHAIN gdbserver. Use --verbose to see why."
222    exit 1
223fi
224
225# install gdbserver
226#
227# note that we install it in the toolchain bin directory
228# not in $SYSROOT/usr/bin
229#
230if [ "$NOTHREADS" = "yes" ] ; then
231    DSTFILE="gdbserver-nothreads"
232else
233    DSTFILE="gdbserver"
234fi
235dump "Install  : $TOOLCHAIN $DSTFILE."
236DEST=$ANDROID_NDK_ROOT/prebuilt/android-$ARCH/gdbserver
237mkdir -p $DEST &&
238run $TOOLCHAIN_PREFIX-objcopy --strip-unneeded $BUILD_OUT/gdbserver $DEST/$DSTFILE
239if [ $? != 0 ] ; then
240    dump "Could not install $DSTFILE. See $TMPLOG"
241    exit 1
242fi
243
244if [ "$PACKAGE_DIR" ]; then
245    ARCHIVE=$ARCH-gdbserver.tar.bz2
246    dump "Packaging: $ARCHIVE"
247    pack_archive "$PACKAGE_DIR/$ARCHIVE" "$ANDROID_NDK_ROOT" "prebuilt/android-$ARCH/gdbserver/$DSTFILE"
248fi
249
250log "Cleaning up."
251if [ -z "$OPTION_BUILD_OUT" ] ; then
252    run rm -rf $BUILD_OUT
253fi
254
255dump "Done."
256