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
39PROGDIR=$(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
45extract_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
55TMPC=$TMPDIR/tmp/tests/tmp-platform.c
56TMPO=$TMPDIR/tmp/tests/tmp-platform.o
57TMPE=$TMPDIR/tmp/tests/tmp-platform$EXE
58
59SRCDIR="../development/ndk"
60DSTDIR="$TMPDIR"
61
62ARCHS="$DEFAULT_ARCHS"
63PLATFORMS=`extract_platforms_from "$SRCDIR"`
64NDK_DIR=$ANDROID_NDK_ROOT
65
66OPTION_HELP=no
67OPTION_PLATFORMS=
68OPTION_SRCDIR=
69OPTION_DSTDIR=
70OPTION_FAST_COPY=
71OPTION_MINIMAL=
72OPTION_ARCH=
73OPTION_ABI=
74OPTION_DEBUG_LIBS=
75OPTION_OVERLAY=
76OPTION_GCC_VERSION="default"
77OPTION_LLVM_VERSION=$DEFAULT_LLVM_VERSION
78OPTION_CASE_INSENSITIVE=no
79PACKAGE_DIR=
80
81VERBOSE=no
82
83for 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
137done
138
139if [ $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
162fi
163
164if [ -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
175else
176    SRCDIR=`dirname $ANDROID_NDK_ROOT`/development/ndk
177    log "Using source directory: $SRCDIR"
178fi
179
180if [ -n "$OPTION_PLATFORM" ] ; then
181    PLATFORMS=$(commas_to_spaces $OPTION_PLATFORM)
182else
183    # Build the list from the content of SRCDIR
184    PLATFORMS=`extract_platforms_from "$SRCDIR"`
185    log "Using platforms: $PLATFORMS"
186fi
187
188# Remove the android- prefix of any platform name
189PLATFORMS=$(echo $PLATFORMS | tr ' ' '\n' | sed -e 's!^android-!!g' | tr '\n' ' ')
190
191if [ -n "$OPTION_DSTDIR" ] ; then
192    DSTDIR="$OPTION_DSTDIR"
193else
194    log "Using destination directory: $DSTDIR"
195fi
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#
202if [ -n "$OPTION_ARCH" ]; then
203    OPTION_ARCH=$(commas_to_spaces $OPTION_ARCH)
204fi
205
206if [ -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
214fi
215
216if [ -n "$OPTION_ARCH" ] ; then
217    ARCHS="$OPTION_ARCH"
218fi
219log "Using architectures: $(commas_to_spaces $ARCHS)"
220
221log "Checking source platforms."
222for 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
231done
232
233log "Checking source platform architectures."
234BAD_ARCHS=
235for ARCH in $ARCHS; do
236    eval CHECK_$ARCH=no
237done
238for 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
246done
247
248if [ "$OPTION_MINIMAL" ]; then
249    OPTION_FAST_COPY=yes
250fi
251
252BAD_ARCHS=
253for 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
263done
264
265if [ -n "$BAD_ARCHS" ] ; then
266    echo "ERROR: Source directory doesn't support these ARCHs: $BAD_ARCHS"
267    exit 3
268fi
269
270# $1: source directory (relative to $SRCDIR)
271# $2: destination directory (relative to $DSTDIR)
272# $3: description of directory contents (e.g. "sysroot")
273copy_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#
291symlink_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)
312symlink_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
321remove_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.
337remove_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#
349remove_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
361get_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)
396gen_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)
449gen_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)
499gen_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
576generate_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 */
617EOF
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#
628if [ -z "$OPTION_OVERLAY" ]; then
629    rm -rf $DSTDIR/platforms && mkdir -p $DSTDIR/platforms
630fi
631for 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
812done
813
814if [ "$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
840fi
841
842log "Done !"
843