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