#!/bin/sh # # Copyright (C) 2009 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # build-ndk-sysroot.sh # # collect files from an Android tree to assemble a sysroot suitable for # building a standable toolchain. # # after that, you may use build/tools/package-ndk-sysroot.sh to package # the resulting files for distribution. # # NOTE: this is different from the Android toolchain original build-sysroot.sh # script because we place target files differently. # # WARNING: For now, only a single target ABI/Architecture us supported # . `dirname $0`/ndk-common.sh # PLATFORM is the name of the current Android system platform PLATFORM=android-3 # ABI is the target ABI name for the NDK ABI=arm OPTION_HELP=no OPTION_BUILD_OUT= OPTION_PLATFORM= OPTION_PACKAGE=no OPTION_ABI= for opt do optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` case "$opt" in --help|-h|-\?) OPTION_HELP=yes ;; --verbose) VERBOSE=yes ;; --platform=*) OPTION_PLATFORM=$optarg ;; --build-out=*) OPTION_BUILD_OUT=$optarg ;; --package) OPTION_PACKAGE=yes ;; --abi=*) OPTION_ABI=$optarg ;; *) echo "unknown option '$opt', use --help" exit 1 esac done if [ $OPTION_HELP = "yes" ] ; then echo "Collect files from an Android build tree and assembles a sysroot" echo "suitable for building a standalone toolchain or be used by the" echo "Android NDK." echo "" echo "options:" echo "" echo " --help print this message" echo " --verbose enable verbose messages" echo " --platform=<name> generate sysroot for platform <name> (default is $PLATFORM)" echo " --abi=<name> generate sysroot for abi <name> (default is $ABI)" echo " --build-out=<path> set Android build out directory" echo " --package generate sysroot package tarball" echo "" exit 0 fi if [ -n "$OPTION_PLATFORM" ] ; then PLATFORM=$OPTION_PLATFORM fi if [ -n "$OPTION_ABI" ] ; then ABI=$OPTION_ABI fi case "$ABI" in arm*) ARCH=arm ;; *) ARCH=$ABI ;; esac # Get the root of the NDK from the current program location NDK_ROOT=`dirname $0` NDK_ROOT=`dirname $NDK_ROOT` NDK_ROOT=`dirname $NDK_ROOT` # Get the Android out directory if [ -z "$OPTION_BUILD_OUT" ] ; then if [ -z "$ANDROID_PRODUCT_OUT" ] ; then echo "ANDROID_PRODUCT_OUT is not defined in your environment. Aborting" exit 1 fi if [ ! -d $ANDROID_PRODUCT_OUT ] ; then echo "ANDROID_PRODUCT_OUT does not point to a valid directory. Aborting" exit 1 fi else ANDROID_PRODUCT_OUT=$OPTION_BUILD_OUT if [ ! -d $ANDROID_PRODUCT_OUT ] ; then echo "The build out path is not a valid directory: $OPTION_BUILD_OUT" exit 1 fi fi PRODUCT_DIR=$ANDROID_PRODUCT_OUT SYSROOT=$NDK_ROOT/build/platforms/$PLATFORM/arch-$ABI COMMON_ROOT=$NDK_ROOT/build/platforms/$PLATFORM/common # clean up everything in existing sysroot rm -rf $SYSROOT mkdir -p $SYSROOT rm -rf $COMMON_ROOT mkdir -p $COMMON_ROOT LIB_ROOT=$SYSROOT/usr/lib install_file () { mkdir -p $2/`dirname $1` cp -fp $1 $2/$1 } install_helper () { (cd $1 && find . -type f | while read ff; do install_file $ff $2; done) } TOP=$PRODUCT_DIR/../../../.. # CRT objects that need to be copied CRT_OBJS_DIR=$PRODUCT_DIR/obj/lib CRT_OBJS="$CRT_OBJS_DIR/crtbegin_static.o \ $CRT_OBJS_DIR/crtbegin_dynamic.o \ $CRT_OBJS_DIR/crtend_android.o" # static libraries that need to be copied. STATIC_LIBS_DIR=$PRODUCT_DIR/obj/STATIC_LIBRARIES STATIC_LIBS="$STATIC_LIBS_DIR/libc_intermediates/libc.a \ $STATIC_LIBS_DIR/libm_intermediates/libm.a \ $STATIC_LIBS_DIR/libstdc++_intermediates/libstdc++.a $STATIC_LIBS_DIR/libthread_db_intermediates/libthread_db.a" # dynamic libraries that need to be copied. DYNAMIC_LIBS_DIR=$PRODUCT_DIR/symbols/system/lib DYNAMIC_LIBS="$DYNAMIC_LIBS_DIR/libdl.so \ $DYNAMIC_LIBS_DIR/libc.so \ $DYNAMIC_LIBS_DIR/libm.so \ $DYNAMIC_LIBS_DIR/libstdc++.so \ $DYNAMIC_LIBS_DIR/libthread_db.so" # Copy all CRT objects and libraries rm -rf $LIB_ROOT mkdir -p $LIB_ROOT cp -f $CRT_OBJS $STATIC_LIBS $DYNAMIC_LIBS $LIB_ROOT # Check $TOP/bionic to see if this is new source layout. if [ -d $TOP/bionic ] ;then BIONIC_ROOT=$TOP/bionic LIBC_ROOT=$BIONIC_ROOT/libc else BIONIC_ROOT=$TOP/system LIBC_ROOT=$BIONIC_ROOT/bionic fi # Copy headers. This need to be done in the reverse order of inclusion # in case there are different headers with the same name. ARCH_INCLUDE=$SYSROOT/usr/include rm -rf $ARCH_INCLUDE mkdir -p $ARCH_INCLUDE COMMON_INCLUDE=$COMMON_ROOT/include rm -rf $COMMON_INCLUDE mkdir -p $COMMON_INCLUDE # Install a common header and create the appropriate arch-specific # directory for it. # # $1: source directory # $2: header path, relative to source directory # common_header () { echo "Copy: $COMMON_INCLUDE/$2" mkdir -p `dirname $COMMON_INCLUDE/$2` install $1/$2 $COMMON_INCLUDE/$2 # just to be safe chmod a-x $COMMON_INCLUDE/$2 # the link prefix, used to point to common/ # from arch-$ARCH/usr/ link_prefix=../../common/include # we need to count the number of directory separators in $2 # for each one of them, we're going to prepend ../ to the # link prefix for item in `echo $2 | tr '/' ' '`; do link_prefix=../$link_prefix done echo "Link: $ARCH_INCLUDE/$2" mkdir -p `dirname $ARCH_INCLUDE/$2` ln -s $link_prefix/$2 $ARCH_INCLUDE/$2 } common_headers () { srcs=`cd $1 && find . -type f` # remove leading ./ srcs=`echo $srcs | sed -e "s%\./%%g"` for src in $srcs; do common_header $1 $src done } arch_header () { echo "Copy: $ARCH_INCLUDE/$2" mkdir -p `dirname $ARCH_INCLUDE/$2` install $1/$2 $ARCH_INCLUDE/$2 # just to be safe chmod a-x $ARCH_INCLUDE/$2 } arch_headers () { srcs=`cd $1 && find . -type f` # remove leading ./ srcs=`echo $srcs | sed -e "s%\./%%g"` for src in $srcs; do arch_header $1 $src done } # ZLib headers common_header $TOP/external/zlib zlib.h common_header $TOP/external/zlib zconf.h # Jni header common_header $TOP/libnativehelper/include/nativehelper jni.h # libthread_db headers, not sure if this is needed for the NDK common_headers $BIONIC_ROOT/libthread_db/include # for libm, just copy math.h and fenv.h common_header $BIONIC_ROOT/libm/include math.h if [ "$ARCH" = "x86" ]; then arch_header $BIONIC_ROOT/libm/include i387/fenv.h else arch_header $BIONIC_ROOT/libm/include $ARCH/fenv.h fi # our tiny C++ standard library common_headers $BIONIC_ROOT/libstdc++/include # C library kernel headers common_headers $LIBC_ROOT/kernel/common arch_headers $LIBC_ROOT/kernel/arch-$ARCH # C library headers common_headers $LIBC_ROOT/include arch_headers $LIBC_ROOT/arch-$ARCH/include # Do we need to package the result if [ $OPTION_PACKAGE = yes ] ; then DATE=`date +%Y%m%d` PKGFILE=$TMPDIR/android-ndk-sysroot-$DATE.tar.bz2 tar cjf $PKGFILE build/platforms/$PLATFORM/arch-$ARCH echo "Packaged in $PKGFILE" fi