1#!/bin/sh
2#
3# Copyright (C) 2009 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# build-ndk-sysroot.sh
18#
19# collect files from an Android tree to assemble a sysroot suitable for
20# building a standable toolchain.
21#
22# after that, you may use build/tools/package-ndk-sysroot.sh to package
23# the resulting files for distribution.
24#
25# NOTE: this is different from the Android toolchain original build-sysroot.sh
26#       script because we place target files differently.
27#
28# WARNING: For now, only a single target ABI/Architecture us supported
29#
30
31. `dirname $0`/ndk-common.sh
32
33# PLATFORM is the name of the current Android system platform
34PLATFORM=android-3
35
36# ABI is the target ABI name for the NDK
37ABI=arm
38
39OPTION_HELP=no
40OPTION_BUILD_OUT=
41OPTION_PLATFORM=
42OPTION_PACKAGE=no
43OPTION_ABI=
44
45for opt do
46  optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
47  case "$opt" in
48  --help|-h|-\?) OPTION_HELP=yes
49  ;;
50  --verbose)
51    if [ "$VERBOSE" = "yes" ] ; then
52        VERBOSE2=yes
53    else
54        VERBOSE=yes
55    fi
56    ;;
57  --platform=*)
58    OPTION_PLATFORM=$optarg
59    ;;
60  --build-out=*)
61    OPTION_BUILD_OUT=$optarg
62    ;;
63  --package)
64    OPTION_PACKAGE=yes
65    ;;
66  --abi=*)
67    OPTION_ABI=$optarg
68    ;;
69  *)
70    echo "unknown option '$opt', use --help"
71    exit 1
72  esac
73done
74
75if [ $OPTION_HELP = "yes" ] ; then
76    echo "Collect files from an Android build tree and assembles a sysroot"
77    echo "suitable for building a standalone toolchain or be used by the"
78    echo "Android NDK."
79    echo ""
80    echo "options:"
81    echo ""
82    echo "  --help             print this message"
83    echo "  --verbose          enable verbose messages"
84    echo "  --platform=<name>  generate sysroot for platform <name> (default is $PLATFORM)"
85    echo "  --abi=<name>       generate sysroot for abi <name> (default is $ABI)"
86    echo "  --build-out=<path> set Android build out directory"
87    echo "  --package          generate sysroot package tarball"
88    echo ""
89    exit 0
90fi
91
92if [ -n "$OPTION_PLATFORM" ] ; then
93    PLATFORM=$OPTION_PLATFORM
94fi
95
96if [ -n "$OPTION_ABI" ] ; then
97    ABI=$OPTION_ABI
98fi
99
100case "$ABI" in
101arm*)
102    ARCH=arm
103    ;;
104*)
105    ARCH=$ABI
106    ;;
107esac
108
109
110# Get the root of the NDK from the current program location
111NDK_ROOT=`dirname $0`
112NDK_ROOT=`dirname $NDK_ROOT`
113NDK_ROOT=`dirname $NDK_ROOT`
114
115# Get the Android out directory
116if [ -z "$OPTION_BUILD_OUT" ] ; then
117    if [ -z "$ANDROID_PRODUCT_OUT" ] ; then
118        echo "ANDROID_PRODUCT_OUT is not defined in your environment. Aborting"
119        exit 1
120    fi
121    if [ ! -d $ANDROID_PRODUCT_OUT ] ; then
122        echo "ANDROID_PRODUCT_OUT does not point to a valid directory. Aborting"
123        exit 1
124    fi
125else
126    ANDROID_PRODUCT_OUT=$OPTION_BUILD_OUT
127    if [ ! -d $ANDROID_PRODUCT_OUT ] ; then
128        echo "The build out path is not a valid directory: $OPTION_BUILD_OUT"
129        exit 1
130    fi
131fi
132
133PRODUCT_DIR=$ANDROID_PRODUCT_OUT
134SYSROOT=$NDK_ROOT/build/platforms/$PLATFORM/arch-$ABI
135COMMON_ROOT=$NDK_ROOT/build/platforms/$PLATFORM/common
136
137# clean up everything in existing sysroot
138rm -rf $SYSROOT
139mkdir -p $SYSROOT
140
141rm -rf $COMMON_ROOT
142mkdir -p $COMMON_ROOT
143
144LIB_ROOT=$SYSROOT/usr/lib
145INCLUDE_ROOT=$SYSROOT/usr/include
146
147install_file ()
148{
149    mkdir -p $2/`dirname $1`
150    cp -fp $1 $2/$1
151}
152
153install_helper ()
154{
155  (cd $1 && find . -type f | while read ff; do install_file $ff $2; done)
156}
157
158TOP=$PRODUCT_DIR/../../../..
159
160# CRT objects that need to be copied
161CRT_OBJS_DIR=$PRODUCT_DIR/obj/lib
162CRT_OBJS="$CRT_OBJS_DIR/crtbegin_static.o \
163$CRT_OBJS_DIR/crtbegin_dynamic.o \
164$CRT_OBJS_DIR/crtend_android.o"
165
166# static libraries that need to be copied.
167STATIC_LIBS_DIR=$PRODUCT_DIR/obj/STATIC_LIBRARIES
168STATIC_LIBS="$STATIC_LIBS_DIR/libc_intermediates/libc.a \
169$STATIC_LIBS_DIR/libm_intermediates/libm.a \
170$STATIC_LIBS_DIR/libstdc++_intermediates/libstdc++.a
171$STATIC_LIBS_DIR/libthread_db_intermediates/libthread_db.a"
172
173# dynamic libraries that need to be copied.
174DYNAMIC_LIBS_DIR=$PRODUCT_DIR/symbols/system/lib
175DYNAMIC_LIBS="$DYNAMIC_LIBS_DIR/libdl.so \
176$DYNAMIC_LIBS_DIR/libc.so \
177$DYNAMIC_LIBS_DIR/libm.so \
178$DYNAMIC_LIBS_DIR/libstdc++.so \
179$DYNAMIC_LIBS_DIR/libthread_db.so"
180
181# Copy all CRT objects and libraries
182rm -rf $LIB_ROOT
183mkdir -p $LIB_ROOT
184cp -f $CRT_OBJS $STATIC_LIBS $DYNAMIC_LIBS $LIB_ROOT
185
186# Check $TOP/bionic to see if this is new source layout.
187if [ -d $TOP/bionic ] ;then
188  BIONIC_ROOT=$TOP/bionic
189  LIBC_ROOT=$BIONIC_ROOT/libc
190else
191  BIONIC_ROOT=$TOP/system
192  LIBC_ROOT=$BIONIC_ROOT/bionic
193fi
194
195# Copy headers.  This need to be done in the reverse order of inclusion
196# in case there are different headers with the same name.
197ARCH_INCLUDE=$SYSROOT/usr/include
198rm -rf $ARCH_INCLUDE
199mkdir -p $ARCH_INCLUDE
200
201COMMON_INCLUDE=$COMMON_ROOT/include
202rm -rf $COMMON_INCLUDE
203mkdir -p $COMMON_INCLUDE
204
205# Install a common header and create the appropriate arch-specific
206# directory for it.
207#
208# $1: source directory
209# $2: header path, relative to source directory
210#
211common_header ()
212{
213    echo "Copy: $COMMON_INCLUDE/$2"
214    mkdir -p `dirname $COMMON_INCLUDE/$2`
215    install $1/$2 $COMMON_INCLUDE/$2
216    # just to be safe
217    chmod a-x $COMMON_INCLUDE/$2
218
219    # the link prefix, used to point to common/
220    # from arch-$ARCH/usr/
221    link_prefix=../../common/include
222
223    # we need to count the number of directory separators in $2
224    # for each one of them, we're going to prepend ../ to the
225    # link prefix
226    for item in `echo $2 | tr '/' ' '`; do
227        link_prefix=../$link_prefix
228    done
229
230    echo "Link: $ARCH_INCLUDE/$2"
231    mkdir -p `dirname $ARCH_INCLUDE/$2`
232    ln -s $link_prefix/$2 $ARCH_INCLUDE/$2
233}
234
235common_headers ()
236{
237    srcs=`cd $1 && find . -type f`
238    # remove leading ./
239    srcs=`echo $srcs | sed -e "s%\./%%g"`
240
241    for src in $srcs; do
242        common_header $1 $src
243    done
244}
245
246arch_header ()
247{
248    echo "Copy: $ARCH_INCLUDE/$2"
249    mkdir -p `dirname $ARCH_INCLUDE/$2`
250    install $1/$2 $ARCH_INCLUDE/$2
251    # just to be safe
252    chmod a-x $ARCH_INCLUDE/$2
253}
254
255arch_headers ()
256{
257    srcs=`cd $1 && find . -type f`
258    # remove leading ./
259    srcs=`echo $srcs | sed -e "s%\./%%g"`
260
261    for src in $srcs; do
262        arch_header $1 $src
263    done
264}
265
266# ZLib headers
267common_header  $TOP/external/zlib zlib.h
268common_header  $TOP/external/zlib zconf.h
269
270# Jni header
271common_header  $TOP/libnativehelper/include/nativehelper jni.h
272
273# libthread_db headers, not sure if this is needed for the NDK
274common_headers $BIONIC_ROOT/libthread_db/include
275
276# for libm, just copy math.h and fenv.h
277common_header $BIONIC_ROOT/libm/include math.h
278if [ "$ARCH" = "x86" ]; then
279    arch_header   $BIONIC_ROOT/libm/include i387/fenv.h
280else
281    arch_header   $BIONIC_ROOT/libm/include $ARCH/fenv.h
282fi
283
284# our tiny C++ standard library
285common_headers $BIONIC_ROOT/libstdc++/include
286
287# C library kernel headers
288common_headers $LIBC_ROOT/kernel/common
289arch_headers   $LIBC_ROOT/kernel/arch-$ARCH
290
291# C library headers
292common_headers $LIBC_ROOT/include
293arch_headers   $LIBC_ROOT/arch-$ARCH/include
294
295# Do we need to package the result
296if [ $OPTION_PACKAGE = yes ] ; then
297    DATE=`date +%Y%m%d`
298    PKGFILE=/tmp/ndk-$USER/android-ndk-sysroot-$DATE.tar.bz2
299    tar cjf $PKGFILE build/platforms/$PLATFORM/arch-$ARCH
300    echo "Packaged in $PKGFILE"
301fi
302