Home | History | Annotate | Download | only in tools
      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 # gen-platforms.sh
     18 #
     19 # This tool is used when packaging a new release, or when developing
     20 # the NDK itself. It will populate DST ($NDK/platforms by default)
     21 # with the content of SRC ($NDK/../development/ndk/platforms/ by default).
     22 #
     23 # The idea is that the content of $SRC/android-N/ only contains stuff
     24 # that is relevant to API level N, and not contain anything that is already
     25 # provided by API level N-1, N-2, etc..
     26 #
     27 # More precisely, for each architecture A:
     28 #  $SRC/android-N/include        --> $DST/android-N/arch-A/usr/include
     29 #  $SRC/android-N/arch-A/include --> $DST/android-N/arch-A/usr/include
     30 #  $SRC/android-N/arch-A/lib     --> $DST/android-N/arch-A/usr/lib
     31 #
     32 # Also, we generate on-the-fly shared dynamic libraries from list of symbols:
     33 #
     34 #  $SRC/android-N/arch-A/symbols --> $DST/android-N/arch-A/usr/lib
     35 #
     36 # Repeat after that for N+1, N+2, etc..
     37 #
     38 
     39 PROGDIR=$(dirname "$0")
     40 . "$PROGDIR/prebuilt-common.sh"
     41 
     42 # Return the list of platform supported from $1/platforms
     43 # as a single space-separated sorted list of levels. (e.g. "3 4 5 8 9 14")
     44 # $1: source directory
     45 extract_platforms_from ()
     46 {
     47     if [ -d "$1" ] ; then
     48         (cd "$1/platforms" && ls -d android-*) | sed -e "s!android-!!" | sort -g | tr '\n' ' '
     49     else
     50         echo ""
     51     fi
     52 }
     53 
     54 # Override tmp file to be predictable
     55 TMPC=$TMPDIR/tmp/tests/tmp-platform.c
     56 TMPO=$TMPDIR/tmp/tests/tmp-platform.o
     57 TMPE=$TMPDIR/tmp/tests/tmp-platform$EXE
     58 
     59 SRCDIR="../development/ndk"
     60 DSTDIR="$TMPDIR"
     61 
     62 ARCHS="$DEFAULT_ARCHS"
     63 PLATFORMS=`extract_platforms_from "$SRCDIR"`
     64 NDK_DIR=$ANDROID_NDK_ROOT
     65 
     66 OPTION_HELP=no
     67 OPTION_PLATFORMS=
     68 OPTION_SRCDIR=
     69 OPTION_DSTDIR=
     70 OPTION_FAST_COPY=
     71 OPTION_MINIMAL=
     72 OPTION_ARCH=
     73 OPTION_ABI=
     74 OPTION_DEBUG_LIBS=
     75 OPTION_OVERLAY=
     76 OPTION_GCC_VERSION="default"
     77 OPTION_LLVM_VERSION=$DEFAULT_LLVM_VERSION
     78 OPTION_CASE_INSENSITIVE=no
     79 PACKAGE_DIR=
     80 
     81 VERBOSE=no
     82 
     83 for opt do
     84   optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
     85   case "$opt" in
     86   --help|-h|-\?) OPTION_HELP=yes
     87   ;;
     88   --verbose)
     89     VERBOSE=yes
     90     ;;
     91   --src-dir=*)
     92     OPTION_SRCDIR="$optarg"
     93     ;;
     94   --dst-dir=*)
     95     OPTION_DSTDIR="$optarg"
     96     ;;
     97   --ndk-dir=*)
     98     NDK_DIR=$optarg
     99     ;;
    100   --platform=*)
    101     OPTION_PLATFORM=$optarg
    102     ;;
    103   --arch=*)
    104     OPTION_ARCH=$optarg
    105     ;;
    106   --abi=*)  # We still support this for backwards-compatibility
    107     OPTION_ABI=$optarg
    108     ;;
    109   --fast-copy)
    110     OPTION_FAST_COPY=yes
    111     ;;
    112   --minimal)
    113     OPTION_MINIMAL=yes
    114     ;;
    115   --package-dir=*)
    116     PACKAGE_DIR=$optarg
    117     ;;
    118   --debug-libs)
    119     OPTION_DEBUG_LIBS=true
    120     ;;
    121   --overlay)
    122     OPTION_OVERLAY=true
    123     ;;
    124   --gcc-version=*)
    125     OPTION_GCC_VERSION=$optarg
    126     ;;
    127   --llvm-version=*)
    128     OPTION_LLVM_VERSION=$optarg
    129     ;;
    130   --case-insensitive)
    131     OPTION_CASE_INSENSITIVE=yes
    132     ;;
    133   *)
    134     echo "unknown option '$opt', use --help"
    135     exit 1
    136   esac
    137 done
    138 
    139 if [ $OPTION_HELP = "yes" ] ; then
    140     echo "Collect files from an Android NDK development tree and assemble"
    141     echo "the platform files appropriately into a final release structure."
    142     echo ""
    143     echo "options:"
    144     echo ""
    145     echo "  --help                Print this message"
    146     echo "  --verbose             Enable verbose messages"
    147     echo "  --src-dir=<path>      Source directory for development platform files [$SRCDIR]"
    148     echo "  --dst-dir=<path>      Destination directory [$DSTDIR]"
    149     echo "  --ndk-dir=<path>      Use toolchains from this NDK directory [$NDK_DIR]"
    150     echo "  --platform=<list>     List of API levels [$PLATFORMS]"
    151     echo "  --arch=<list>         List of CPU architectures [$ARCHS]"
    152     echo "  --minimal             Ignore symlinks and generated shared libs."
    153     echo "  --fast-copy           Don't create symlinks, copy files instead"
    154     echo "  --package-dir=<path>  Package platforms archive in specific path."
    155     echo "  --debug-libs          Also generate C source file for generated libraries."
    156     echo ""
    157     echo "Use the --minimal flag if you want to generate minimal sysroot directories"
    158     echo "that will be used to generate prebuilt toolchains. Otherwise, the script"
    159     echo "will require these toolchains to be pre-installed and will use them to"
    160     echo "generate shared system shared libraries from the symbol list files."
    161     exit 0
    162 fi
    163 
    164 if [ -n "$OPTION_SRCDIR" ] ; then
    165     SRCDIR="$OPTION_SRCDIR";
    166     if [ ! -d "$SRCDIR" ] ; then
    167         echo "ERROR: Source directory $SRCDIR does not exist !"
    168         exit 1
    169     fi
    170     if [ ! -d "$SRCDIR/platforms/android-3" ] ; then
    171         echo "ERROR: Invalid source directory: $SRCDIR"
    172         echo "Please make sure it contains platforms/android-3 etc..."
    173         exit 1
    174     fi
    175 else
    176     SRCDIR=`dirname $ANDROID_NDK_ROOT`/development/ndk
    177     log "Using source directory: $SRCDIR"
    178 fi
    179 
    180 if [ -n "$OPTION_PLATFORM" ] ; then
    181     PLATFORMS=$(commas_to_spaces $OPTION_PLATFORM)
    182 else
    183     # Build the list from the content of SRCDIR
    184     PLATFORMS=`extract_platforms_from "$SRCDIR"`
    185     log "Using platforms: $PLATFORMS"
    186 fi
    187 
    188 # Remove the android- prefix of any platform name
    189 PLATFORMS=$(echo $PLATFORMS | tr ' ' '\n' | sed -e 's!^android-!!g' | tr '\n' ' ')
    190 
    191 if [ -n "$OPTION_DSTDIR" ] ; then
    192     DSTDIR="$OPTION_DSTDIR"
    193 else
    194     log "Using destination directory: $DSTDIR"
    195 fi
    196 
    197 # Handle architecture list
    198 #
    199 # We support both --arch and --abi for backwards compatibility reasons
    200 # --arch is the new hotness, --abi is deprecated.
    201 #
    202 if [ -n "$OPTION_ARCH" ]; then
    203     OPTION_ARCH=$(commas_to_spaces $OPTION_ARCH)
    204 fi
    205 
    206 if [ -n "$OPTION_ABI" ] ; then
    207     echo "WARNING: --abi=<names> is deprecated. Use --arch=<names> instead!"
    208     OPTION_ABI=$(commas_to_spaces $OPTION_ABI)
    209     if [ -n "$OPTION_ARCH" -a "$OPTION_ARCH" != "$OPTION_ABI" ]; then
    210         echo "ERROR: You can't use both --abi and --arch with different values!"
    211         exit 1
    212     fi
    213     OPTION_ARCH=$OPTION_ABI
    214 fi
    215 
    216 if [ -n "$OPTION_ARCH" ] ; then
    217     ARCHS="$OPTION_ARCH"
    218 fi
    219 log "Using architectures: $(commas_to_spaces $ARCHS)"
    220 
    221 log "Checking source platforms."
    222 for PLATFORM in $PLATFORMS; do
    223     DIR="$SRCDIR/platforms/android-$PLATFORM"
    224     if [ ! -d $DIR ] ; then
    225         echo "ERROR: Directory missing: $DIR"
    226         echo "Please check your --platform=<list> option and try again."
    227         exit 2
    228     else
    229         log "  $DIR"
    230     fi
    231 done
    232 
    233 log "Checking source platform architectures."
    234 BAD_ARCHS=
    235 for ARCH in $ARCHS; do
    236     eval CHECK_$ARCH=no
    237 done
    238 for PLATFORM in $PLATFORMS; do
    239     for ARCH in $ARCHS; do
    240         DIR="$SRCDIR/platforms/android-$PLATFORM/arch-$ARCH"
    241         if [ -d $DIR ] ; then
    242             log "  $DIR"
    243             eval CHECK_$ARCH=yes
    244         fi
    245     done
    246 done
    247 
    248 if [ "$OPTION_MINIMAL" ]; then
    249     OPTION_FAST_COPY=yes
    250 fi
    251 
    252 BAD_ARCHS=
    253 for ARCH in $ARCHS; do
    254     CHECK=`var_value CHECK_$ARCH`
    255     log "  $ARCH check: $CHECK"
    256     if [ "$CHECK" = no ] ; then
    257         if [ -z "$BAD_ARCHS" ] ; then
    258             BAD_ARCHS=$ARCH
    259         else
    260             BAD_ARCHS="$BAD_ARCHS $ARCH"
    261         fi
    262     fi
    263 done
    264 
    265 if [ -n "$BAD_ARCHS" ] ; then
    266     echo "ERROR: Source directory doesn't support these ARCHs: $BAD_ARCHS"
    267     exit 3
    268 fi
    269 
    270 # $1: source directory (relative to $SRCDIR)
    271 # $2: destination directory (relative to $DSTDIR)
    272 # $3: description of directory contents (e.g. "sysroot")
    273 copy_src_directory ()
    274 {
    275     local SDIR="$SRCDIR/$1"
    276     local DDIR="$DSTDIR/$2"
    277     if [ -d "$SDIR" ] ; then
    278         log "Copying $3 from \$SRC/$1 to \$DST/$2."
    279         mkdir -p "$DDIR" && (cd "$SDIR" && 2>/dev/null tar chf - *) | (tar xf - -C "$DDIR")
    280         if [ $? != 0 ] ; then
    281             echo "ERROR: Could not copy $3 directory $SDIR into $DDIR !"
    282             exit 5
    283         fi
    284     fi
    285 }
    286 
    287 # $1: source dir
    288 # $2: destination dir
    289 # $3: reverse path
    290 #
    291 symlink_src_directory_inner ()
    292 {
    293     local files file subdir rev
    294     mkdir -p "$DSTDIR/$2"
    295     rev=$3
    296     files=$(cd $DSTDIR/$1 && ls -1p)
    297     for file in $files; do
    298         if [ "$file" = "${file%%/}" ]; then
    299             log "Link \$DST/$2/$file --> $rev/$1/$file"
    300             ln -s $rev/$1/$file $DSTDIR/$2/$file
    301         else
    302             file=${file%%/}
    303             symlink_src_directory_inner "$1/$file" "$2/$file" "$rev/.."
    304         fi
    305     done
    306 }
    307 # Create a symlink-copy of directory $1 into $2
    308 # This function is recursive.
    309 #
    310 # $1: source directory (relative to $SRCDIR)
    311 # $2: destination directory (relative to $DSTDIR)
    312 symlink_src_directory ()
    313 {
    314     symlink_src_directory_inner "$1" "$2" "$(reverse_path $1)"
    315 }
    316 
    317 # Remove unwanted symbols
    318 # $1: symbol file (one symbol per line)
    319 # $2+: Input symbol list
    320 # Out: Input symbol file, without any unwanted symbol listed by $1
    321 remove_unwanted_symbols_from ()
    322 {
    323   local SYMBOL_FILE="$1"
    324   shift
    325   if [ -f "$SYMBOL_FILE" ]; then
    326     echo "$@" | tr ' ' '\n' | grep -v -F -x -f $SYMBOL_FILE | tr '\n' ' '
    327   else
    328     echo "$@"
    329   fi
    330 }
    331 
    332 # Remove unwanted symbols from a library's functions list.
    333 # $1: Architecture name
    334 # $2: Library name (e.g. libc.so)
    335 # $3+: Input symbol list
    336 # Out: Input symbol list without any unwanted symbols.
    337 remove_unwanted_function_symbols ()
    338 {
    339   local ARCH LIBRARY SYMBOL_FILE
    340   ARCH=$1
    341   LIBRARY=$2
    342   shift; shift
    343   SYMBOL_FILE=$PROGDIR/unwanted-symbols/$ARCH/$LIBRARY.functions.txt
    344   remove_unwanted_symbols_from $SYMBOL_FILE "$@"
    345 }
    346 
    347 # Same as remove_unwanted_functions_symbols, but for variable names.
    348 #
    349 remove_unwanted_variable_symbols ()
    350 {
    351   local ARCH LIBRARY SYMBOL_FILE
    352   ARCH=$1
    353   LIBRARY=$2
    354   shift; shift
    355   SYMBOL_FILE=$PROGDIR/unwanted-symbols/$ARCH/$LIBRARY.variables.txt
    356   remove_unwanted_symbols_from $SYMBOL_FILE "$@"
    357 }
    358 
    359 # $1: Architecture
    360 # Out: compiler command
    361 get_default_compiler_for_arch()
    362 {
    363     local ARCH=$1
    364     local TOOLCHAIN_PREFIX CC GCC_VERSION
    365 
    366     if [ -n "$OPTION_GCC_VERSION" -a "$OPTION_GCC_VERSION" != "default" ]; then
    367         GCC_VERSION=$OPTION_GCC_VERSION
    368     else
    369         GCC_VERSION=$(get_default_gcc_version_for_arch $ARCH)
    370     fi
    371 
    372     for TAG in $HOST_TAG $HOST_TAG32; do
    373         TOOLCHAIN_PREFIX="$ANDROID_BUILD_TOP/prebuilts/ndk/current/$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION $TAG)"
    374         TOOLCHAIN_PREFIX=${TOOLCHAIN_PREFIX%-}
    375         CC="$TOOLCHAIN_PREFIX-gcc"
    376         if [ -f "$CC" ]; then
    377             break;
    378         fi
    379     done
    380 
    381     if [ ! -f "$CC" ]; then
    382         dump "ERROR: $ARCH toolchain not installed: $CC"
    383         dump "Important: Use the --minimal flag to use this script without generated system shared libraries."
    384         dump "This is generally useful when you want to generate the host cross-toolchain programs."
    385         exit 1
    386     fi
    387     echo "$CC"
    388 }
    389 
    390 # $1: library name
    391 # $2: functions list
    392 # $3: variables list
    393 # $4: destination file
    394 # $5: compiler command
    395 # $6: version script (optional)
    396 gen_shared_lib ()
    397 {
    398     local LIBRARY=$1
    399     local FUNCS="$2"
    400     local VARS="$3"
    401     local DSTFILE="$4"
    402     local CC="$5"
    403     local VERSION_SCRIPT="$6"
    404 
    405     # Now generate a small C source file that contains similarly-named stubs
    406     echo "/* Auto-generated file, do not edit */" > $TMPC
    407     local func var
    408     for func in $FUNCS; do
    409         echo "void $func(void) {}" >> $TMPC
    410     done
    411     for var in $VARS; do
    412         echo "int $var = 0;" >> $TMPC
    413     done
    414 
    415     # Build it with our cross-compiler. It will complain about conflicting
    416     # types for built-in functions, so just shut it up.
    417     COMMAND="$CC -Wl,-shared,-Bsymbolic -Wl,-soname,$LIBRARY -nostdlib -o $TMPO $TMPC -Wl,--exclude-libs,libgcc.a -w"
    418     if [ -n "$VERSION_SCRIPT" ]; then
    419       COMMAND="$COMMAND -Wl,--version-script=$VERSION_SCRIPT -Wl,--no-undefined-version"
    420     fi
    421     echo "## COMMAND: $COMMAND"
    422     $COMMAND
    423     if [ $? != 0 ] ; then
    424         dump "ERROR: Can't generate shared library for: $LIBRARY"
    425         dump "See the content of $TMPC for details."
    426         exit 1
    427     fi
    428 
    429     # Copy to our destination now
    430     local libdir=$(dirname "$DSTFILE")
    431     mkdir -p "$libdir" && rm -f "$DSTFILE" && cp -f $TMPO "$DSTFILE"
    432     if [ $? != 0 ] ; then
    433         dump "ERROR: Can't copy shared library for: $LIBRARY"
    434         dump "target location is: $DSTFILE"
    435         exit 1
    436     fi
    437 
    438     if [ "$OPTION_DEBUG_LIBS" ]; then
    439       cp $TMPC $DSTFILE.c
    440       echo "$FUNCS" | tr ' ' '\n' > $DSTFILE.functions.txt
    441       echo "$VARS" | tr ' ' '\n' > $DSTFILE.variables.txt
    442     fi
    443 }
    444 
    445 # $1: Architecture
    446 # $2: symbol source directory (relative to $SRCDIR)
    447 # $3: destination directory for generated libs (relative to $DSTDIR)
    448 # $4: compiler flags (optional)
    449 gen_shared_libraries ()
    450 {
    451     local ARCH=$1
    452     local SYMDIR="$SRCDIR/$2"
    453     local DSTDIR="$DSTDIR/$3"
    454     local FLAGS="$4"
    455     local CC funcs vars numfuncs numvars
    456 
    457     # Let's locate the toolchain we're going to use
    458     CC=$(get_default_compiler_for_arch $ARCH)" $FLAGS"
    459     if [ $? != 0 ]; then
    460         echo $CC
    461         exit 1
    462     fi
    463 
    464     # In certain cases, the symbols directory doesn't exist,
    465     # e.g. on x86 for PLATFORM < 9
    466     if [ ! -d "$SYMDIR" ]; then
    467         return
    468     fi
    469 
    470     # Let's list the libraries we're going to generate
    471     LIBS=$( (cd $SYMDIR && 2>/dev/null ls *.functions.txt) | sort -u | sed -e 's!\.functions\.txt$!!g')
    472 
    473     for LIB in $LIBS; do
    474         funcs=$(cat "$SYMDIR/$LIB.functions.txt" 2>/dev/null)
    475         vars=$(cat "$SYMDIR/$LIB.variables.txt" 2>/dev/null)
    476         funcs=$(remove_unwanted_function_symbols $ARCH libgcc.a $funcs)
    477         funcs=$(remove_unwanted_function_symbols $ARCH $LIB $funcs)
    478         vars=$(remove_unwanted_variable_symbols $ARCH libgcc.a $vars)
    479         vars=$(remove_unwanted_variable_symbols $ARCH $LIB $vars)
    480         numfuncs=$(echo $funcs | wc -w)
    481         numvars=$(echo $vars | wc -w)
    482         version_script=""
    483 
    484         if [ -f "$SYMDIR/$LIB.versions.txt" ]; then
    485           version_script="$SYMDIR/$LIB.versions.txt"
    486         fi
    487         log "Generating $ARCH shared library for $LIB ($numfuncs functions + $numvars variables)"
    488 
    489         gen_shared_lib $LIB "$funcs" "$vars" "$DSTDIR/$LIB" "$CC" "$version_script"
    490     done
    491 }
    492 
    493 # $1: platform number
    494 # $2: architecture name
    495 # $3: common source directory (for crtbrand.c, etc)
    496 # $4: source directory (for *.S files)
    497 # $5: destination directory
    498 # $6: flags for compiler (optional)
    499 gen_crt_objects ()
    500 {
    501     local API=$1
    502     local ARCH=$2
    503     local COMMON_SRC_DIR="$SRCDIR/$3"
    504     local SRC_DIR="$SRCDIR/$4"
    505     local DST_DIR="$DSTDIR/$5"
    506     local FLAGS="$6"
    507     local SRC_FILE DST_FILE
    508     local CC
    509 
    510     if [ ! -d "$SRC_DIR" ]; then
    511         return
    512     fi
    513 
    514     # Let's locate the toolchain we're going to use
    515     CC=$(get_default_compiler_for_arch $ARCH)" $FLAGS"
    516     if [ $? != 0 ]; then
    517         echo $CC
    518         exit 1
    519     fi
    520 
    521     CRTBRAND_S=$DST_DIR/crtbrand.s
    522     log "Generating platform $API crtbrand assembly code: $CRTBRAND_S"
    523     (cd "$COMMON_SRC_DIR" && mkdir -p `dirname $CRTBRAND_S` && $CC -DPLATFORM_SDK_VERSION=$API -fpic -S -o - crtbrand.c | \
    524         sed -e '/\.note\.ABI-tag/s/progbits/note/' > "$CRTBRAND_S")
    525     if [ $? != 0 ]; then
    526         dump "ERROR: Could not generate $CRTBRAND_S from $COMMON_SRC_DIR/crtbrand.c"
    527         exit 1
    528     fi
    529 
    530     for SRC_FILE in $(cd "$SRC_DIR" && ls crt*.[cS]); do
    531         DST_FILE=${SRC_FILE%%.c}
    532         DST_FILE=${DST_FILE%%.S}.o
    533 
    534         case "$DST_FILE" in
    535             "crtend.o")
    536                 # Special case: crtend.S must be compiled as crtend_android.o
    537                 # This is for long historical reasons, i.e. to avoid name conflicts
    538                 # in the past with other crtend.o files. This is hard-coded in the
    539                 # Android toolchain configuration, so switch the name here.
    540                 DST_FILE=crtend_android.o
    541                 ;;
    542             "crtbegin_dynamic.o"|"crtbegin_static.o")
    543                 # Add .note.ABI-tag section
    544                 SRC_FILE=$SRC_FILE" $CRTBRAND_S"
    545                 ;;
    546             "crtbegin.o")
    547                 # If we have a single source for both crtbegin_static.o and
    548                 # crtbegin_dynamic.o we generate one and make a copy later.
    549                 DST_FILE=crtbegin_dynamic.o
    550                 # Add .note.ABI-tag section
    551                 SRC_FILE=$SRC_FILE" $CRTBRAND_S"
    552                 ;;
    553         esac
    554 
    555         log "Generating $ARCH C runtime object: $DST_FILE"
    556         (cd "$SRC_DIR" && $CC \
    557                  -I$SRCDIR/../../bionic/libc/include \
    558                  -I$SRCDIR/../../bionic/libc/arch-common/bionic \
    559                  -I$SRCDIR/../../bionic/libc/arch-$ARCH/include \
    560                  -DPLATFORM_SDK_VERSION=$API \
    561                  -O2 -fpic -Wl,-r -nostdlib -o "$DST_DIR/$DST_FILE" $SRC_FILE)
    562         if [ $? != 0 ]; then
    563             dump "ERROR: Could not generate $DST_FILE from $SRC_DIR/$SRC_FILE"
    564             exit 1
    565         fi
    566         if [ ! -s "$DST_DIR/crtbegin_static.o" ]; then
    567             cp "$DST_DIR/crtbegin_dynamic.o" "$DST_DIR/crtbegin_static.o"
    568         fi
    569     done
    570     rm -f "$CRTBRAND_S"
    571 }
    572 
    573 # $1: platform number
    574 # $2: architecture
    575 # $3: target NDK directory
    576 generate_api_level ()
    577 {
    578     local API=$1
    579     local ARCH=$2
    580     local HEADER="platforms/android-$API/arch-$ARCH/usr/include/android/api-level.h"
    581     log "Generating: $HEADER"
    582     rm -f "$3/$HEADER"  # Remove symlink if any.
    583     cat > "$3/$HEADER" <<EOF
    584 /*
    585  * Copyright (C) 2008 The Android Open Source Project
    586  * All rights reserved.
    587  *
    588  * Redistribution and use in source and binary forms, with or without
    589  * modification, are permitted provided that the following conditions
    590  * are met:
    591  *  * Redistributions of source code must retain the above copyright
    592  *    notice, this list of conditions and the following disclaimer.
    593  *  * Redistributions in binary form must reproduce the above copyright
    594  *    notice, this list of conditions and the following disclaimer in
    595  *    the documentation and/or other materials provided with the
    596  *    distribution.
    597  *
    598  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    599  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    600  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    601  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    602  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    603  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    604  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
    605  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    606  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    607  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    608  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    609  * SUCH DAMAGE.
    610  */
    611 #ifndef ANDROID_API_LEVEL_H
    612 #define ANDROID_API_LEVEL_H
    613 
    614 #define __ANDROID_API__ $API
    615 
    616 #endif /* ANDROID_API_LEVEL_H */
    617 EOF
    618 }
    619 
    620 # Copy platform sysroot into your destination
    621 #
    622 
    623 # if $SRC/android-$PLATFORM/arch-$ARCH exists
    624 #   $SRC/android-$PLATFORM/include --> $DST/android-$PLATFORM/arch-$ARCH/usr/include
    625 #   $SRC/android-$PLATFORM/arch-$ARCH/include --> $DST/android-$PLATFORM/arch-$ARCH/usr/include
    626 #   $SRC/android-$PLATFORM/arch-$ARCH/lib --> $DST/android-$PLATFORM/arch-$ARCH/usr/lib
    627 #
    628 if [ -z "$OPTION_OVERLAY" ]; then
    629     rm -rf $DSTDIR/platforms && mkdir -p $DSTDIR/platforms
    630 fi
    631 for ARCH in $ARCHS; do
    632     echo "## Generating arch: $ARCH"
    633     # Find first platform for this arch
    634     PREV_SYSROOT_DST=
    635     PREV_PLATFORM_SRC_ARCH=
    636     LIBDIR=$(get_default_libdir_for_arch $ARCH)
    637 
    638     for PLATFORM in $PLATFORMS; do
    639         echo "## Generating platform: $PLATFORM"
    640         PLATFORM_DST=platforms/android-$PLATFORM   # Relative to $DSTDIR
    641         PLATFORM_SRC=$PLATFORM_DST                 # Relative to $SRCDIR
    642         SYSROOT_DST=$PLATFORM_DST/arch-$ARCH/usr
    643         # Skip over if there is no arch-specific file for this platform
    644         # and no destination platform directory was created. This is needed
    645         # because x86 and MIPS don't have files for API levels 3-8.
    646         if [ -z "$PREV_SYSROOT_DST" -a \
    647            ! -d "$SRCDIR/$PLATFORM_SRC/arch-$ARCH" ]; then
    648             log "Skipping: \$SRC/$PLATFORM_SRC/arch-$ARCH"
    649             continue
    650         fi
    651 
    652         log "Populating \$DST/platforms/android-$PLATFORM/arch-$ARCH"
    653 
    654         # If this is not the first destination directory, copy over, or
    655         # symlink the files from the previous one now.
    656         if [ "$PREV_SYSROOT_DST" ]; then
    657             if [ "$OPTION_FAST_COPY" ]; then
    658                 log "Copying \$DST/$PREV_SYSROOT_DST to \$DST/$SYSROOT_DST"
    659                 copy_directory "$DSTDIR/$PREV_SYSROOT_DST" "$DSTDIR/$SYSROOT_DST"
    660             else
    661                 log "Symlink-copying \$DST/$PREV_SYSROOT_DST to \$DST/$SYSROOT_DST"
    662                 symlink_src_directory $PREV_SYSROOT_DST $SYSROOT_DST
    663             fi
    664         fi
    665 
    666         # If this is the first destination directory, copy the common
    667         # files from previous platform directories into this one.
    668         # This helps copy the common headers from android-3 to android-8
    669         # into the x86 and mips android-9 directories.
    670         if [ -z "$PREV_SYSROOT_DST" ]; then
    671             for OLD_PLATFORM in $PLATFORMS; do
    672                 if [ "$OLD_PLATFORM" = "$PLATFORM" ]; then
    673                     break
    674                 fi
    675                 copy_src_directory platforms/android-$OLD_PLATFORM/include \
    676                                    $SYSROOT_DST/include \
    677                                    "common android-$OLD_PLATFORM headers"
    678             done
    679         fi
    680 
    681         # There are two set of bionic headers: the original ones haven't been updated since
    682         # gingerbread except for bug fixing, and the new ones in android-$FIRST_API64_LEVEL
    683         # with 64-bit support.  Before the old bionic headers are deprecated/removed, we need
    684         # to remove stale old headers when createing platform = $FIRST_API64_LEVEL
    685         if [ "$PLATFORM" = "$FIRST_API64_LEVEL" ]; then
    686             log "Removing stale bionic headers in \$DST/$SYSROOT_DST/include"
    687             nonbionic_files="android EGL GLES GLES2 GLES3 KHR media OMXAL SLES jni.h thread_db.h zconf.h zlib.h"
    688             if [ -d "$DSTDIR/$SYSROOT_DST/include/" ]; then
    689                 files=$(cd "$DSTDIR/$SYSROOT_DST/include/" && ls)
    690                 for file in $files; do
    691                     if [ "$nonbionic_files" = "${nonbionic_files%%${file}*}" ]; then
    692                         rm -rf "$DSTDIR/$SYSROOT_DST/include/$file"
    693                     fi
    694                 done
    695             fi
    696         fi
    697 
    698         # Now copy over all non-arch specific include files
    699         copy_src_directory $PLATFORM_SRC/include $SYSROOT_DST/include "common system headers"
    700         copy_src_directory $PLATFORM_SRC/arch-$ARCH/include $SYSROOT_DST/include "$ARCH system headers"
    701 
    702         generate_api_level "$PLATFORM" "$ARCH" "$DSTDIR"
    703 
    704         # If --minimal is not used, copy or generate binary files.
    705         if [ -z "$OPTION_MINIMAL" ]; then
    706             # Copy the prebuilt static libraries.  We need full set for multilib compiler for some arch
    707             case "$ARCH" in
    708                 x86_64)
    709                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib $SYSROOT_DST/lib "x86 sysroot libs"
    710                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib64 $SYSROOT_DST/lib64 "x86_64 sysroot libs"
    711                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/libx32 $SYSROOT_DST/libx32 "x32 sysroot libs"
    712                     ;;
    713                 mips64)
    714                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib $SYSROOT_DST/lib "mips -mabi=32 -mips32 sysroot libs"
    715                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/libr2 $SYSROOT_DST/libr2 "mips -mabi=32 -mips32r2 sysroot libs"
    716                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/libr6 $SYSROOT_DST/libr6 "mips -mabi=32 -mips32r6 sysroot libs"
    717                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib64r2 $SYSROOT_DST/lib64r2 "mips -mabi=64 -mips64r2 sysroot libs"
    718                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib64 $SYSROOT_DST/lib64 "mips -mabi=64 -mips64r6 sysroot libs"
    719                     ;;
    720                 mips)
    721                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib $SYSROOT_DST/lib "mips -mabi=32 -mips32 sysroot libs"
    722                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/libr2 $SYSROOT_DST/libr2 "mips -mabi=32 -mips32r2 sysroot libs"
    723                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/libr6 $SYSROOT_DST/libr6 "mips -mabi=32 -mips32r6 sysroot libs"
    724                     ;;
    725                 *)
    726                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/$LIBDIR $SYSROOT_DST/$LIBDIR "$ARCH sysroot libs"
    727                     ;;
    728             esac
    729 
    730             # Generate C runtime object files when available
    731             PLATFORM_SRC_ARCH=$PLATFORM_SRC/arch-$ARCH/src
    732             if [ ! -d "$SRCDIR/$PLATFORM_SRC_ARCH" ]; then
    733                 PLATFORM_SRC_ARCH=$PREV_PLATFORM_SRC_ARCH
    734             else
    735                 PREV_PLATFORM_SRC_ARCH=$PLATFORM_SRC_ARCH
    736             fi
    737 
    738             # Genreate crt objects
    739             case "$ARCH" in
    740                 x86_64)
    741                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/lib "-m32"
    742                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/lib64 "-m64"
    743                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/libx32 "-mx32"
    744                     ;;
    745                 mips64)
    746                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/lib "-mabi=32 -mips32"
    747                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/libr2 "-mabi=32 -mips32r2"
    748                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/libr6 "-mabi=32 -mips32r6"
    749                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/lib64r2 "-mabi=64 -mips64r2"
    750                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/lib64 "-mabi=64 -mips64r6"
    751                     ;;
    752                 mips)
    753                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/lib "-mabi=32 -mips32"
    754                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/libr2 "-mabi=32 -mips32r2"
    755                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/libr6 "-mabi=32 -mips32r6"
    756                     ;;
    757                 *)
    758                     gen_crt_objects $PLATFORM $ARCH platforms/common/src $PLATFORM_SRC_ARCH $SYSROOT_DST/$LIBDIR
    759                     ;;
    760             esac
    761 
    762             # Generate shared libraries from symbol files
    763             case "$ARCH" in
    764                 x86_64)
    765                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/lib "-m32"
    766                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/lib64 "-m64"
    767                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/libx32 "-mx32"
    768                     ;;
    769                 mips64)
    770                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/lib "-mabi=32 -mips32"
    771                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/libr2 "-mabi=32 -mips32r2"
    772                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/libr6 "-mabi=32 -mips32r6"
    773                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/lib64r2 "-mabi=64 -mips64r2"
    774                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/lib64 "-mabi=64 -mips64r6"
    775                     ;;
    776                 mips)
    777                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/lib "-mabi=32 -mips32"
    778                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/libr2 "-mabi=32 -mips32r2"
    779                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/libr6 "-mabi=32 -mips32r6"
    780                     ;;
    781                 *)
    782                     gen_shared_libraries $ARCH $PLATFORM_SRC/arch-$ARCH/symbols $SYSROOT_DST/$LIBDIR
    783                     ;;
    784             esac
    785         else
    786             # Copy the prebuilt binaries to bootstrap GCC
    787             case "$ARCH" in
    788                 x86_64)
    789                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/lib $SYSROOT_DST/lib "x86 sysroot libs (boostrap)"
    790                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/lib64 $SYSROOT_DST/lib64 "x86_64 sysroot libs (boostrap)"
    791                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/libx32 $SYSROOT_DST/libx32 "x32 sysroot libs (boostrap)"
    792                     ;;
    793                 mips64)
    794                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/lib $SYSROOT_DST/lib "mips -mabi=32 -mips32 sysroot libs (boostrap)"
    795                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/libr2 $SYSROOT_DST/libr2 "mips -mabi=32 -mips32r2 sysroot libs (boostrap)"
    796                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/libr6 $SYSROOT_DST/libr6 "mips -mabi=32 -mips32r6 sysroot libs (boostrap)"
    797                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/lib64r2 $SYSROOT_DST/lib64r2 "mips -mabi=64 -mips64r2 sysroot libs (boostrap)"
    798                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/lib64 $SYSROOT_DST/lib64 "mips -mabi=64 -mips64r6 sysroot libs (boostrap)"
    799                     ;;
    800                 mips)
    801                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/lib $SYSROOT_DST/lib "mips -mabi=32 -mips32 sysroot libs (boostrap)"
    802                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/libr2 $SYSROOT_DST/libr2 "mips -mabi=32 -mips32r2 sysroot libs (boostrap)"
    803                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap/libr6 $SYSROOT_DST/libr6 "mips -mabi=32 -mips32r6 sysroot libs (boostrap)"
    804                     ;;
    805                 *)
    806                     copy_src_directory $PLATFORM_SRC/arch-$ARCH/lib-bootstrap $SYSROOT_DST/$LIBDIR "$ARCH sysroot libs (boostrap)"
    807                     ;;
    808             esac
    809         fi
    810         PREV_SYSROOT_DST=$SYSROOT_DST
    811     done
    812 done
    813 
    814 if [ "$PACKAGE_DIR" ]; then
    815     # Remove "duplicate" files for case-insensitive platforms.
    816     if [ "$OPTION_CASE_INSENSITIVE" = "yes" ]; then
    817         find "$DSTDIR/platforms" | sort -f | uniq -di | xargs rm
    818     fi
    819 
    820     for PLATFORM in $PLATFORMS; do
    821         PLATFORM_NAME="android-$PLATFORM"
    822         make_repo_prop "$DSTDIR/platforms/$PLATFORM_NAME"
    823 
    824         NOTICE="$DSTDIR/platforms/$PLATFORM_NAME/NOTICE"
    825         cp "$ANDROID_BUILD_TOP/bionic/libc/NOTICE" $NOTICE
    826         echo >> $NOTICE
    827         cp "$ANDROID_BUILD_TOP/bionic/libm/NOTICE" $NOTICE
    828         echo >> $NOTICE
    829         cp "$ANDROID_BUILD_TOP/bionic/libdl/NOTICE" $NOTICE
    830         echo >> $NOTICE
    831         cp "$ANDROID_BUILD_TOP/bionic/libstdc++/NOTICE" $NOTICE
    832 
    833         mkdir -p "$PACKAGE_DIR"
    834         fail_panic "Could not create package directory: $PACKAGE_DIR"
    835         ARCHIVE=platform-$PLATFORM.zip
    836         dump "Packaging $ARCHIVE"
    837         pack_archive "$PACKAGE_DIR/$ARCHIVE" "$DSTDIR/platforms" "$PLATFORM_NAME"
    838         fail_panic "Could not package platform-$PLATFORM"
    839     done
    840 fi
    841 
    842 log "Done !"
    843