1#!/bin/sh
2#
3# Copyright (C) 2009-2010 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# This script is used to package complete Android NDK release packages.
18#
19# You will need prebuilt toolchain binary tarballs or a previous
20# NDK release package to do that.
21#
22# See make-release.sh if you want to make a new release completely from
23# scratch.
24#
25
26. `dirname $0`/prebuilt-common.sh
27
28NDK_ROOT_DIR="$ANDROID_NDK_ROOT"
29
30# the list of platforms / API levels we want to package in
31# this release. This can be overriden with the --platforms
32# option, see below.
33#
34PLATFORMS="$API_LEVELS"
35
36# the default release name (use today's date)
37RELEASE=`date +%Y%m%d`
38register_var_option "--release=<name>" RELEASE "Specify release name"
39
40# the directory containing all prebuilts
41PREBUILT_DIR=
42register_var_option "--prebuilt-dir=<path>" PREBUILT_DIR "Specify prebuilt directory"
43
44# a prebuilt NDK archive (.zip file). empty means don't use any
45PREBUILT_NDK=
46register_var_option "--prebuilt-ndk=<file>" PREBUILT_NDK "Specify prebuilt ndk package"
47
48# the list of supported host development systems
49SYSTEMS=$DEFAULT_SYSTEMS
50register_var_option "--systems=<list>" SYSTEMS "Specify host systems"
51
52# ARCH to build for
53ARCHS=$DEFAULT_ARCHS
54register_var_option "--arch=<arch>" ARCHS "Specify target architecture(s)"
55
56# set to 'yes' if we should use 'git ls-files' to list the files to
57# be copied into the archive.
58NO_GIT=no
59register_var_option "--no-git" NO_GIT "Don't use git to list input files, take all of them."
60
61# set of toolchain prebuilts we need to package
62TOOLCHAINS=$(get_toolchain_name_list_for_arch arm)
63OPTION_TOOLCHAINS=$TOOLCHAINS
64register_var_option "--toolchains=<list>" OPTION_TOOLCHAINS "Specify list of toolchains."
65
66# set of platforms to package (all by default)
67register_var_option "--platforms=<list>" PLATFORMS "Specify API levels"
68
69# the package prefix
70PREFIX=android-ndk
71register_var_option "--prefix=<name>" PREFIX "Specify package prefix"
72
73# default location for generated packages
74OUT_DIR=/tmp/ndk-$USER/release
75OPTION_OUT_DIR=
76register_var_option "--out-dir=<path>" OPTION_OUT_DIR "Specify output package directory" "$OUT_DIR"
77
78# Find the location of the platforms root directory
79DEVELOPMENT_ROOT=`dirname $ANDROID_NDK_ROOT`/development/ndk
80register_var_option "--development-root=<path>" DEVELOPMENT_ROOT "Specify platforms/samples directory"
81
82LLVM_VERSION_LIST=$DEFAULT_LLVM_VERSION_LIST
83register_var_option "--llvm=<versions>" LLVM_VERSION_LIST "List of LLVM release versions"
84
85PROGRAM_PARAMETERS=
86PROGRAM_DESCRIPTION=\
87"Package a new set of release packages for the Android NDK.
88
89You will need to have generated one or more prebuilt binary tarballs
90with the build/tools/rebuild-all-prebuilts.sh script. These files should
91be named like <toolname>-<system>.tar.bz2, where <toolname> is an arbitrary
92tool name, and <system> is one of: $SYSTEMS
93
94Use the --prebuilt-dir=<path> option to build release packages from the
95binary tarballs stored in <path>.
96
97Alternatively, you can use --prebuilt-ndk=<file> where <file> is the path
98to a previous NDK release package. It will be used to extract the toolchain
99binaries and copy them to your new release. Only use this for experimental
100package releases.
101
102The generated release packages will be stored in a temporary directory that
103will be printed at the end of the generation process.
104"
105
106extract_parameters "$@"
107
108# Ensure that SYSTEMS is space-separated
109SYSTEMS=$(commas_to_spaces $SYSTEMS)
110
111# Do we need to support x86?
112ARCHS=$(commas_to_spaces $ARCHS)
113echo "$ARCHS" | tr ' ' '\n' | grep -q x86
114if [ $? = 0 ] ; then
115    TRY_X86=yes
116else
117    TRY_X86=no
118fi
119# Do we need to support mips?
120echo "$ARCHS" | tr ' ' '\n' | grep -q mips
121if [ $? = 0 ] ; then
122    TRY_mips=yes
123else
124    TRY_mips=no
125fi
126
127# Compute ABIS from ARCHS
128ABIS=
129for ARCH in $ARCHS; do
130    DEFAULT_ABIS=$(get_default_abis_for_arch $ARCH)
131    if [ -z "$ABIS" ]; then
132        ABIS=$DEFAULT_ABIS
133    else
134        ABIS=$ABIS" $DEFAULT_ABIS"
135    fi
136done
137
138# Convert comma-separated list to space-separated list
139LLVM_VERSION_LIST=$(commas_to_spaces $LLVM_VERSION_LIST)
140
141# If --arch is used to list x86 as a target architecture, Add x86-4.4.3 to
142# the list of default toolchains to package. That is, unless you also
143# explicitely use --toolchains=<list>
144#
145# Ensure that TOOLCHAINS is space-separated after this.
146#
147if [ "$OPTION_TOOLCHAINS" != "$TOOLCHAINS" ]; then
148    TOOLCHAINS=$(commas_to_spaces $OPTION_TOOLCHAINS)
149else
150    if [ "$TRY_X86" = "yes" ]; then
151        TOOLCHAINS=$TOOLCHAINS" "$(get_toolchain_name_list_for_arch x86)
152    fi
153    if [ "$TRY_mips" = "yes" ]; then
154        TOOLCHAINS=$TOOLCHAINS" "$(get_toolchain_name_list_for_arch mips)
155    fi
156    TOOLCHAINS=$(commas_to_spaces $TOOLCHAINS)
157fi
158
159# Check the prebuilt path
160#
161if [ -n "$PREBUILT_NDK" -a -n "$PREBUILT_DIR" ] ; then
162    echo "ERROR: You cannot use both --prebuilt-ndk and --prebuilt-dir at the same time."
163    exit 1
164fi
165
166if [ -z "$PREBUILT_DIR" -a -z "$PREBUILT_NDK" ] ; then
167    echo "ERROR: You must use one of --prebuilt-dir or --prebuilt-ndk. See --help for details."
168    exit 1
169fi
170
171# Check the option directory.
172if [ -n "$OPTION_OUT_DIR" ] ; then
173    OUT_DIR="$OPTION_OUT_DIR"
174    mkdir -p $OUT_DIR
175    if [ $? != 0 ] ; then
176        echo "ERROR: Could not create output directory: $OUT_DIR"
177        exit 1
178    fi
179else
180    rm -rf $OUT_DIR && mkdir -p $OUT_DIR
181fi
182
183# Handle the prebuilt binaries now
184#
185if [ -n "$PREBUILT_DIR" ] ; then
186    if [ ! -d "$PREBUILT_DIR" ] ; then
187        echo "ERROR: the --prebuilt-dir argument is not a directory: $PREBUILT_DIR"
188        exit 1
189    fi
190    if [ -z "$SYSTEMS" ] ; then
191        echo "ERROR: Your systems list is empty, use --systems=LIST to specify a different one."
192        exit 1
193    fi
194    # Check the toolchain prebuilts
195    #
196    for TC in $TOOLCHAINS; do
197        for SYS in $SYSTEMS; do
198            if [ ! -f "$PREBUILT_DIR/$TC-$SYS.tar.bz2" ] ; then
199                echo "ERROR: Missing prebuilt file $TC-$SYS.tar.bz2 in: $PREBUILT_DIR"
200                exit 1
201            fi
202        done
203    done
204    for ARCH in $ARCHS; do
205        if [ ! -f "$PREBUILT_DIR/$ARCH-gdbserver.tar.bz2" ] ; then
206            echo "ERROR: Missing prebuilt file $ARCH-gdbserver.tar.bz2 in: $PREBUILT_DIR"
207            exit 1
208        fi
209    done
210else
211    if [ ! -f "$PREBUILT_NDK" ] ; then
212        echo "ERROR: the --prebuilt-ndk argument is not a file: $PREBUILT_NDK"
213        exit 1
214    fi
215    # Check that the name ends with the proper host tag
216    HOST_NDK_SUFFIX="$HOST_TAG.zip"
217    echo "$PREBUILT_NDK" | grep -q "$HOST_NDK_SUFFIX"
218    fail_panic "The name of the prebuilt NDK must end in $HOST_NDK_SUFFIX"
219    SYSTEMS=$HOST_TAG
220fi
221
222echo "Architectures: $ARCHS"
223echo "CPU ABIs: $ABIS"
224echo "Toolchains: $TOOLCHAINS"
225echo "Host systems: $SYSTEMS"
226
227
228# The list of git files to copy into the archives
229if [ "$NO_GIT" != "yes" ] ; then
230    echo "Collecting sources from git (use --no-git to copy all files instead)."
231    GIT_FILES=`cd $NDK_ROOT_DIR && git ls-files`
232else
233    echo "Collecting all sources files under tree."
234    # Cleanup everything that is likely to not be part of the final NDK
235    # i.e. generated files...
236    rm -rf $NDK_ROOT_DIR/samples/*/obj
237    rm -rf $NDK_ROOT_DIR/samples/*/libs
238    # Get all files under the NDK root
239    GIT_FILES=`cd $NDK_ROOT_DIR && find .`
240    GIT_FILES=`echo $GIT_FILES | sed -e "s!\./!!g"`
241fi
242
243# temporary directory used for packaging
244TMPDIR=$NDK_TMPDIR
245
246RELEASE_PREFIX=$PREFIX-$RELEASE
247
248# ensure that the generated files are ug+rx
249umask 0022
250
251# Unpack a prebuilt into the destination directory ($DSTDIR)
252# $1: prebuilt name, relative to $PREBUILT_DIR
253# $2: optional, destination directory
254unpack_prebuilt ()
255{
256    local PREBUILT=$1
257    local DDIR="${2:-$DSTDIR}"
258    echo "Unpacking $PREBUILT"
259    if [ -f "$PREBUILT_DIR/$PREBUILT" ] ; then
260        unpack_archive "$PREBUILT_DIR/$PREBUILT" "$DDIR"
261        fail_panic "Could not unpack prebuilt $PREBUILT. Aborting."
262    else
263        echo "WARNING: Could not find $PREBUILT in $PREBUILT_DIR"
264    fi
265}
266
267# Copy a prebuilt directory from the previous
268# $1: Source directory relative to
269copy_prebuilt ()
270{
271    local SUBDIR="$1"
272    if [ -d "$1" ] ; then
273        echo "Copying: $SUBDIR"
274        copy_directory "$SUBDIR" "$DSTDIR/$2"
275    else
276        echo "Ignored: $SUBDIR"
277    fi
278}
279
280
281rm -rf $TMPDIR && mkdir -p $TMPDIR
282
283# Unpack the previous NDK package if any
284if [ -n "$PREBUILT_NDK" ] ; then
285    echo "Unpacking prebuilt toolchains from $PREBUILT_NDK"
286    UNZIP_DIR=$TMPDIR/prev-ndk
287    rm -rf $UNZIP_DIR && mkdir -p $UNZIP_DIR
288    fail_panic "Could not create temporary directory: $UNZIP_DIR"
289    unpack_archive "$PREBUILT_NDK" "$UNZIP_DIR"
290    fail_panic "Could not unzip NDK package $PREBUILT_NDK"
291fi
292
293# first create the reference ndk directory from the git reference
294echo "Creating reference from source files"
295REFERENCE=$TMPDIR/reference && rm -rf $REFERENCE/* &&
296copy_file_list "$NDK_ROOT_DIR" "$REFERENCE" $GIT_FILES &&
297rm -f $REFERENCE/Android.mk
298fail_panic "Could not create reference. Aborting."
299
300# Copy platform and sample files
301if [ "$PREBUILT_DIR" ]; then
302    echo "Unpacking platform files" &&
303    unpack_archive "$PREBUILT_DIR/platforms.tar.bz2" "$REFERENCE" &&
304    echo "Unpacking samples files" &&
305    unpack_archive "$PREBUILT_DIR/samples.tar.bz2" "$REFERENCE"
306    fail_panic "Could not unpack platform and sample files"
307elif [ "$PREBUILT_NDK" ]; then
308    echo "ERROR: NOT IMPLEMENTED!"
309    exit 1
310else
311    # copy platform and sample files
312    echo "Copying platform and sample files"
313    FLAGS="--src-dir=$DEVELOPMENT_ROOT --dst-dir=$REFERENCE"
314    if [ "$VERBOSE2" = "yes" ] ; then
315        FLAGS="$FLAGS --verbose"
316    fi
317
318    FLAGS="$FLAGS --platform=$(spaces_to_commas $PLATFORMS)"
319    FLAGS="$FLAGS --arch=$(spaces_to_commas $ARCHS)"
320    $NDK_ROOT_DIR/build/tools/gen-platforms.sh $FLAGS
321    fail_panic "Could not copy platform files. Aborting."
322fi
323
324# Remove the source for host tools to make the final package smaller
325rm -rf $REFERENCE/sources/host-tools
326
327# Remove leftovers, just in case...
328rm -rf $REFERENCE/samples/*/{obj,libs,build.xml,local.properties,Android.mk} &&
329rm -rf $REFERENCE/tests/build/*/{obj,libs} &&
330rm -rf $REFERENCE/tests/device/*/{obj,libs}
331
332# copy sources files
333if [ -d $DEVELOPMENT_ROOT/sources ] ; then
334    echo "Copying NDK sources files"
335    copy_file_list "$DEVELOPMENT_ROOT" "$REFERENCE" "sources"
336    fail_panic "Could not copy sources. Aborting."
337fi
338
339# Unpack prebuilt C++ runtimes headers and libraries
340if [ -z "$PREBUILT_NDK" ]; then
341    # Unpack gdbserver
342    for ARCH in $ARCHS; do
343        unpack_prebuilt $ARCH-gdbserver.tar.bz2 "$REFERENCE"
344    done
345    # Unpack C++ runtimes
346    for VERSION in $DEFAULT_GCC_VERSION_LIST; do
347        unpack_prebuilt gnu-libstdc++-headers-$VERSION.tar.bz2 "$REFERENCE"
348    done
349    for ABI in $ABIS; do
350        unpack_prebuilt gabixx-libs-$ABI.tar.bz2 "$REFERENCE"
351        unpack_prebuilt stlport-libs-$ABI.tar.bz2 "$REFERENCE"
352        for VERSION in $DEFAULT_GCC_VERSION_LIST; do
353            unpack_prebuilt gnu-libstdc++-libs-$VERSION-$ABI.tar.bz2 "$REFERENCE"
354        done
355    done
356fi
357
358# create a release file named 'RELEASE.TXT' containing the release
359# name. This is used by the build script to detect whether you're
360# invoking the NDK from a release package or from the development
361# tree.
362#
363echo "$RELEASE" > $REFERENCE/RELEASE.TXT
364
365# Remove un-needed files
366rm -f $REFERENCE/CleanSpec.mk
367
368# now, for each system, create a package
369#
370for SYSTEM in $SYSTEMS; do
371    echo "Preparing package for system $SYSTEM."
372    BIN_RELEASE=$RELEASE_PREFIX-$SYSTEM
373    DSTDIR=$TMPDIR/$RELEASE_PREFIX
374    rm -rf $DSTDIR &&
375    copy_directory "$REFERENCE" "$DSTDIR"
376    fail_panic "Could not copy reference. Aborting."
377
378    if [ "$PREBUILT_NDK" ]; then
379        cd $UNZIP_DIR/android-ndk-* && cp -rP toolchains/* $DSTDIR/toolchains/
380        fail_panic "Could not copy toolchain files from $PREBUILT_NDK"
381
382        if [ -d "$DSTDIR/$GABIXX_SUBDIR" ]; then
383            GABIXX_ABIS=$PREBUILT_ABIS
384            for GABIXX_ABI in $GABIXX_ABIS; do
385                copy_prebuilt "$GABIXX_SUBDIR/libs/$GABIXX_ABI" "$GABIXX_SUBDIR/libs"
386            done
387        else
388            echo "WARNING: Could not find GAbi++ source tree!"
389        fi
390
391        if [ -d "$DSTDIR/$STLPORT_SUBDIR" ] ; then
392            STLPORT_ABIS=$PREBUILT_ABIS
393            for STL_ABI in $STLPORT_ABIS; do
394                copy_prebuilt "$STLPORT_SUBDIR/libs/$STL_ABI" "$STLPORT_SUBDIR/libs"
395            done
396        else
397            echo "WARNING: Could not find STLport source tree!"
398        fi
399
400        for VERSION in $DEFAULT_GCC_VERSION_LIST; do
401            copy_prebuilt "$GNUSTL_SUBDIR/$VERSION/include" "$GNUSTL_SUBDIR/$VERSION/"
402            for STL_ABI in $PREBUILT_ABIS; do
403                copy_prebuilt "$GNUSTL_SUBDIR/$VERSION/libs/$STL_ABI" "$GNUSTL_SUBDIR/$VERSION/libs"
404            done
405        done
406    else
407        # Unpack gdbserver
408        for TC in $TOOLCHAINS; do
409            unpack_prebuilt $TC-$SYSTEM.tar.bz2
410            echo "Removing sysroot for $TC"
411            rm -rf $DSTDIR/toolchains/$TC/prebuilt/$SYSTEM/sysroot
412        done
413
414        # Unpack llvm and clang
415        for LLVM_VERSION in $LLVM_VERSION_LIST; do
416            unpack_prebuilt llvm-$LLVM_VERSION-$SYSTEM.tar.bz2
417        done
418
419        # Unpack prebuilt ndk-stack and other host tools
420        unpack_prebuilt ndk-stack-$SYSTEM.tar.bz2
421        unpack_prebuilt ndk-make-$SYSTEM.tar.bz2
422        unpack_prebuilt ndk-sed-$SYSTEM.tar.bz2
423        unpack_prebuilt ndk-awk-$SYSTEM.tar.bz2
424
425        if [ "$SYSTEM" = "windows" ]; then
426            unpack_prebuilt toolbox-$SYSTEM.tar.bz2
427        fi
428    fi
429
430    # Create an archive for the final package. Extension depends on the
431    # host system.
432    case "$SYSTEM" in
433        windows)
434            ARCHIVE="$BIN_RELEASE.zip"
435            ;;
436        *)
437            ARCHIVE="$BIN_RELEASE.tar.bz2"
438            ;;
439    esac
440    echo "Creating $ARCHIVE"
441    # make all file universally readable, and all executable (including directory)
442    # universally executable, punt intended
443    find $DSTDIR -exec chmod a+r {} \;
444    find $DSTDIR -executable -exec chmod a+x {} \;
445    pack_archive "$OUT_DIR/$ARCHIVE" "$TMPDIR" "$RELEASE_PREFIX"
446    fail_panic "Could not create archive: $OUT_DIR/$ARCHIVE"
447#    chmod a+r $TMPDIR/$ARCHIVE
448done
449
450echo "Cleaning up."
451rm -rf $TMPDIR/reference
452rm -rf $TMPDIR/prev-ndk
453
454echo "Done, please see packages in $OUT_DIR:"
455ls -l $OUT_DIR
456