1#!/bin/bash
2# Copyright (C) 2010 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17# Create a standalone toolchain package for Android.
18
19. `dirname $0`/prebuilt-common.sh
20
21PROGRAM_PARAMETERS=""
22PROGRAM_DESCRIPTION=\
23"Generate a customized Android toolchain installation that includes
24a working sysroot. The result is something that can more easily be
25used as a standalone cross-compiler, e.g. to run configure and
26make scripts."
27
28# For now, this is the only toolchain that works reliably.
29TOOLCHAIN_NAME=
30register_var_option "--toolchain=<name>" TOOLCHAIN_NAME "Specify toolchain name"
31
32USE_LLVM=no
33do_option_use_llvm ()
34{
35    USE_LLVM=yes
36}
37register_option "--use-llvm" do_option_use_llvm "Use LLVM."
38
39STL=gnustl
40register_var_option "--stl=<name>" STL "Specify C++ STL"
41
42ARCH=
43register_var_option "--arch=<name>" ARCH "Specify target architecture"
44
45# Grab the ABIs that match the architecture.
46ABIS=
47register_var_option "--abis=<list>" ABIS "Specify list of target ABIs."
48
49NDK_DIR=`dirname $0`
50NDK_DIR=`dirname $NDK_DIR`
51NDK_DIR=`dirname $NDK_DIR`
52register_var_option "--ndk-dir=<path>" NDK_DIR "Take source files from NDK at <path>"
53
54PACKAGE_DIR=$TMPDIR
55register_var_option "--package-dir=<path>" PACKAGE_DIR "Place package file in <path>"
56
57INSTALL_DIR=
58register_var_option "--install-dir=<path>" INSTALL_DIR "Don't create package, install files to <path> instead."
59
60PLATFORM=
61register_option "--platform=<name>" do_platform "Specify target Android platform/API level." "android-3"
62do_platform () {
63    PLATFORM=$1;
64    if [ "$PLATFORM" = "android-L" ]; then
65        echo "WARNING: android-L is renamed as android-21"
66        PLATFORM=android-21
67    fi
68}
69
70extract_parameters "$@"
71
72# Check NDK_DIR
73if [ ! -d "$NDK_DIR/build/core" ] ; then
74    echo "Invalid source NDK directory: $NDK_DIR"
75    echo "Please use --ndk-dir=<path> to specify the path of an installed NDK."
76    exit 1
77fi
78
79# Check TOOLCHAIN_NAME
80ARCH_BY_TOOLCHAIN_NAME=
81if [ -n "$TOOLCHAIN_NAME" ]; then
82    case $TOOLCHAIN_NAME in
83        arm-*)
84            ARCH_BY_TOOLCHAIN_NAME=arm
85            ;;
86        x86-*)
87            ARCH_BY_TOOLCHAIN_NAME=x86
88            ;;
89        mipsel-*)
90            ARCH_BY_TOOLCHAIN_NAME=mips
91            ;;
92        aarch64-*)
93            ARCH_BY_TOOLCHAIN_NAME=arm64
94            ;;
95        x86_64-linux-android-*)
96            ARCH_BY_TOOLCHAIN_NAME=x86_64
97            TOOLCHAIN_NAME=$(echo "$TOOLCHAIN_NAME" | sed -e 's/-linux-android//')
98            echo "Auto-truncate: --toolchain=$TOOLCHAIN_NAME"
99            ;;
100        x86_64-*)
101            ARCH_BY_TOOLCHAIN_NAME=x86_64
102            ;;
103        mips64el-*)
104            ARCH_BY_TOOLCHAIN_NAME=mips64
105            ;;
106        *)
107            echo "Invalid toolchain $TOOLCHAIN_NAME"
108            exit 1
109            ;;
110    esac
111fi
112# Check ARCH
113if [ -z "$ARCH" ]; then
114    ARCH=$ARCH_BY_TOOLCHAIN_NAME
115    if [ -z "$ARCH" ]; then
116        ARCH=arm
117    fi
118    echo "Auto-config: --arch=$ARCH"
119fi
120
121if [ -z "$ABIS" ]; then
122    ABIS=$(convert_arch_to_abi $ARCH)
123fi
124
125if [ -z "$ABIS" ]; then
126    dump "ERROR: No ABIS. Possibly unsupported NDK architecture $ARCH?"
127    exit 1
128fi
129
130# Check toolchain name
131if [ -z "$TOOLCHAIN_NAME" ]; then
132    TOOLCHAIN_NAME=$(get_default_toolchain_name_for_arch $ARCH)
133    echo "Auto-config: --toolchain=$TOOLCHAIN_NAME"
134fi
135
136# Detect LLVM version from toolchain name with *clang*
137TOOLCHAIN_LLVM=$(echo "$TOOLCHAIN_NAME" | grep clang)
138if [ -n "$TOOLCHAIN_LLVM" ]; then
139    USE_LLVM=yes
140    DEFAULT_GCC_VERSION=$(get_default_gcc_version_for_arch $ARCH)
141    NEW_TOOLCHAIN_NAME=${TOOLCHAIN_NAME%-clang}-${DEFAULT_GCC_VERSION}
142    TOOLCHAIN_NAME=$NEW_TOOLCHAIN_NAME
143fi
144
145# Check PLATFORM
146if [ -z "$PLATFORM" ] ; then
147    case $ARCH in
148        arm) PLATFORM=android-3
149            ;;
150        x86|mips)
151            PLATFORM=android-9
152            ;;
153        arm64|x86_64|mips64)
154            PLATFORM=android-$FIRST_API64_LEVEL
155            ;;
156        *)
157            dump "ERROR: Unsupported NDK architecture $ARCH!"
158    esac
159    echo "Auto-config: --platform=$PLATFORM"
160fi
161
162if [ ! -d "$NDK_DIR/platforms/$PLATFORM" ] ; then
163    echo "Invalid platform name: $PLATFORM"
164    echo "Please use --platform=<name> with one of:" `(cd "$NDK_DIR/platforms" && ls)`
165    exit 1
166fi
167
168if [ -d "$NDK_DIR/prebuilt/$HOST_TAG" ]; then
169    SYSTEM=$HOST_TAG
170else
171    SYSTEM=$HOST_TAG32
172fi
173
174# Check toolchain name
175TOOLCHAIN_PATH="$NDK_DIR/toolchains/$TOOLCHAIN_NAME/prebuilt/$SYSTEM"
176if [ ! -d "$TOOLCHAIN_PATH" ] ; then
177    echo "Could not find toolchain: $TOOLCHAIN_PATH"
178    echo "Please use --toolchain=<name> with the name of a toolchain supported by the source NDK."
179    echo "Try one of: " `(cd "$NDK_DIR/toolchains" && ls)`
180    exit 1
181fi
182
183# Extract architecture from platform name
184parse_toolchain_name $TOOLCHAIN_NAME
185
186case "$TOOLCHAIN_NAME" in
187  *4.9l)
188    GCC_VERSION=4.9l
189    ;;
190  *4.8l)
191    GCC_VERSION=4.8l
192    ;;
193esac
194
195# Check that there are any platform files for it!
196(cd $NDK_DIR/platforms && ls -d */arch-$ARCH >/dev/null 2>&1 )
197if [ $? != 0 ] ; then
198    echo "Platform $PLATFORM doesn't have any files for this architecture: $ARCH"
199    echo "Either use --platform=<name> or --toolchain=<name> to select a different"
200    echo "platform or arch-dependent toolchain name (respectively)!"
201    exit 1
202fi
203
204# Compute source sysroot
205SRC_SYSROOT_INC="$NDK_DIR/platforms/$PLATFORM/arch-$ARCH/usr/include"
206SRC_SYSROOT_LIB="$NDK_DIR/platforms/$PLATFORM/arch-$ARCH/usr/lib"
207if [ ! -d "$SRC_SYSROOT_INC" -o ! -d "$SRC_SYSROOT_LIB" ] ; then
208    echo "No platform files ($PLATFORM) for this architecture: $ARCH"
209    exit 1
210fi
211
212# Check that we have any prebuilts GCC toolchain here
213if [ ! -d "$TOOLCHAIN_PATH" ]; then
214    echo "Toolchain is missing prebuilt files: $TOOLCHAIN_NAME"
215    echo "You must point to a valid NDK release package!"
216    exit 1
217fi
218
219TOOLCHAIN_PATH="$TOOLCHAIN_PATH"
220TOOLCHAIN_GCC=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET-gcc
221
222if [ ! -f "$TOOLCHAIN_GCC" ] ; then
223    echo "Toolchain $TOOLCHAIN_GCC is missing!"
224    exit 1
225fi
226
227if [ "$USE_LLVM" = "yes" ]; then
228    LLVM_TOOLCHAIN_PATH="$NDK_DIR/toolchains/llvm/prebuilt/$SYSTEM"
229    # Check that we have any prebuilts LLVM toolchain here
230    if [ ! -d "$LLVM_TOOLCHAIN_PATH" ] ; then
231        echo "LLVM Toolchain is missing prebuilt files"
232        echo "You must point to a valid NDK release package!"
233        exit 1
234    fi
235    LLVM_TOOLCHAIN_PATH="$LLVM_TOOLCHAIN_PATH"
236fi
237
238# Get GCC_BASE_VERSION.  Note that GCC_BASE_VERSION may be slightly different from GCC_VERSION.
239# eg. In gcc4.9 GCC_BASE_VERSION is "4.9.x-google"
240LIBGCC_PATH=`$TOOLCHAIN_GCC -print-libgcc-file-name`
241LIBGCC_BASE_PATH=${LIBGCC_PATH%/*}         # base path of libgcc.a
242GCC_BASE_VERSION=${LIBGCC_BASE_PATH##*/}   # stuff after the last /
243
244# Create temporary directory
245TMPDIR=$NDK_TMPDIR/standalone/$TOOLCHAIN_NAME
246
247dump "Copying prebuilt binaries..."
248# Now copy the GCC toolchain prebuilt binaries
249copy_directory "$TOOLCHAIN_PATH" "$TMPDIR"
250
251# Copy python-related to for gdb.exe
252PYTHON=python
253PYTHON_x=python$(echo "$DEFAULT_PYTHON_VERSION" | cut -d . -f 1)
254PYTHON_xdotx=python$(echo "$DEFAULT_PYTHON_VERSION" | cut -d . -f 1-2)
255copy_directory "$NDK_DIR/prebuilt/$SYSTEM/include/$PYTHON_xdotx" "$TMPDIR/include/$PYTHON_xdotx"
256copy_directory "$NDK_DIR/prebuilt/$SYSTEM/lib/$PYTHON_xdotx" "$TMPDIR/lib/$PYTHON_xdotx"
257copy_file_list "$NDK_DIR/prebuilt/$SYSTEM/bin" "$TMPDIR/bin" "$PYTHON$HOST_EXE" "$PYTHON_x$HOST_EXE" "$PYTHON_xdotx$HOST_EXE"
258if [ "$HOST_TAG32" = "windows" ]; then
259  copy_file_list "$NDK_DIR/prebuilt/$SYSTEM/bin" "$TMPDIR/bin" lib$PYTHON_xdotx.dll
260fi
261
262# Copy yasm for x86
263if [ "$ARCH" = "x86" ]; then
264  copy_file_list "$NDK_DIR/prebuilt/$SYSTEM/bin" "$TMPDIR/bin" "yasm$HOST_EXE"
265fi
266
267# Clang stuff
268
269if [ "$USE_LLVM" = "yes" ]; then
270  # Copy the clang/llvm toolchain prebuilt binaries
271  copy_directory "$LLVM_TOOLCHAIN_PATH" "$TMPDIR"
272
273  # Move clang and clang++ to clang${LLVM_VERSION} and clang${LLVM_VERSION}++,
274  # then create scripts linking them with predefined -target flag.  This is to
275  # make clang/++ easier drop-in replacement for gcc/++ in NDK standalone mode.
276  # Note that the file name of "clang" isn't important, and the trailing
277  # "++" tells clang to compile in C++ mode
278  LLVM_TARGET=
279  case "$ARCH" in
280      arm)
281          # Note: -target may change by clang based on the presence of
282          # subsequent -march=armv5te and/or -mthumb.
283          LLVM_TARGET=armv7a-none-linux-androideabi
284          TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm
285          ;;
286      x86)
287          LLVM_TARGET=i686-none-linux-android
288          TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86
289          ;;
290      mips)
291          LLVM_TARGET=mipsel-none-linux-android
292          TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips
293          ;;
294      arm64)
295          LLVM_TARGET=aarch64-none-linux-android
296          TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm64
297          ;;
298      x86_64)
299          LLVM_TARGET=x86_64-none-linux-android
300          TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86_64
301          ;;
302      mips64)
303          LLVM_TARGET=mips64el-none-linux-android
304          TOOLCHAIN_PREFIX=$DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips64
305          ;;
306      *)
307        dump "ERROR: Unsupported NDK architecture $ARCH!"
308  esac
309
310  # We need to copy clang and clang++ to some other named binary because clang
311  # and clang++ are going to be the shell scripts with the prefilled target. We
312  # have the version info available, and that's a typical alternate name (and is
313  # what we historically used).
314  LLVM_VERSION=$(cat $LLVM_TOOLCHAIN_PATH/AndroidVersion.txt | \
315      egrep -o '[[:digit:]]+\.[[:digit:]]')
316
317  # Need to remove '.' from LLVM_VERSION when constructing new clang name,
318  # otherwise clang3.3++ may still compile *.c code as C, not C++, which
319  # is not consistent with g++
320  LLVM_VERSION_WITHOUT_DOT=$(echo "$LLVM_VERSION" | sed -e "s!\.!!")
321  mv "$TMPDIR/bin/clang${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}"
322  if [ -h "$TMPDIR/bin/clang++${HOST_EXE}" ] ; then
323    ## clang++ is a link to clang.  Remove it and reconstruct
324    rm "$TMPDIR/bin/clang++${HOST_EXE}"
325    ln -sf "clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE}"
326  else
327    mv "$TMPDIR/bin/clang++${HOST_EXE}" "$TMPDIR/bin/clang$LLVM_VERSION_WITHOUT_DOT++${HOST_EXE}"
328  fi
329
330  TARGET_FLAG="-target $LLVM_TARGET"
331  CLANG_FLAGS="$TARGET_FLAG --sysroot \`dirname \$0\`/../sysroot"
332
333  cat > "$TMPDIR/bin/clang" <<EOF
334#!/bin/bash
335if [ "\$1" != "-cc1" ]; then
336    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT $CLANG_FLAGS "\$@"
337else
338    # target/triple already spelled out.
339    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT "\$@"
340fi
341EOF
342  cat > "$TMPDIR/bin/clang++" <<EOF
343#!/bin/bash
344if [ "\$1" != "-cc1" ]; then
345    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT++ $CLANG_FLAGS "\$@"
346else
347    # target/triple already spelled out.
348    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT++ "\$@"
349fi
350EOF
351  chmod 0755 "$TMPDIR/bin/clang" "$TMPDIR/bin/clang++"
352  cp -a "$TMPDIR/bin/clang" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang"
353  cp -a "$TMPDIR/bin/clang++" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang++"
354
355  if [ -n "$HOST_EXE" ] ; then
356    CLANG_FLAGS="$TARGET_FLAG --sysroot %~dp0\\..\\sysroot"
357    cat > "$TMPDIR/bin/clang.cmd" <<EOF
358@echo off
359if "%1" == "-cc1" goto :L
360%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE} $CLANG_FLAGS %*
361if ERRORLEVEL 1 exit /b 1
362goto :done
363:L
364rem target/triple already spelled out.
365%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE} %*
366if ERRORLEVEL 1 exit /b 1
367:done
368EOF
369    cat > "$TMPDIR/bin/clang++.cmd" <<EOF
370@echo off
371if "%1" == "-cc1" goto :L
372%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE} $CLANG_FLAGS %*
373if ERRORLEVEL 1 exit /b 1
374goto :done
375:L
376rem target/triple already spelled out.
377%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE} %*
378if ERRORLEVEL 1 exit /b 1
379:done
380EOF
381    chmod 0755 "$TMPDIR/bin/clang.cmd" "$TMPDIR/bin/clang++.cmd"
382    cp -a "$TMPDIR/bin/clang.cmd" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang.cmd"
383    cp -a "$TMPDIR/bin/clang++.cmd" "$TMPDIR/bin/$TOOLCHAIN_PREFIX-clang++.cmd"
384  fi
385fi
386
387dump "Copying sysroot headers and libraries..."
388# Copy the sysroot under $TMPDIR/sysroot. The toolchain was built to
389# expect the sysroot files to be placed there!
390copy_directory_nolinks "$SRC_SYSROOT_INC" "$TMPDIR/sysroot/usr/include"
391copy_directory_nolinks "$SRC_SYSROOT_LIB" "$TMPDIR/sysroot/usr/lib"
392case "$ARCH" in
393# x86_64 and mips* toolchain are built multilib.
394    x86_64)
395        copy_directory_nolinks "$SRC_SYSROOT_LIB/../lib64" "$TMPDIR/sysroot/usr/lib64"
396        copy_directory_nolinks "$SRC_SYSROOT_LIB/../libx32" "$TMPDIR/sysroot/usr/libx32"
397        ;;
398    mips64)
399        copy_directory_nolinks "$SRC_SYSROOT_LIB/../libr2" "$TMPDIR/sysroot/usr/libr2"
400        copy_directory_nolinks "$SRC_SYSROOT_LIB/../libr6" "$TMPDIR/sysroot/usr/libr6"
401        copy_directory_nolinks "$SRC_SYSROOT_LIB/../lib64" "$TMPDIR/sysroot/usr/lib64"
402        copy_directory_nolinks "$SRC_SYSROOT_LIB/../lib64r2" "$TMPDIR/sysroot/usr/lib64r2"
403        ;;
404    mips)
405        copy_directory_nolinks "$SRC_SYSROOT_LIB/../libr2" "$TMPDIR/sysroot/usr/libr2"
406        copy_directory_nolinks "$SRC_SYSROOT_LIB/../libr6" "$TMPDIR/sysroot/usr/libr6"
407        ;;
408esac
409
410GNUSTL_DIR=$NDK_DIR/$GNUSTL_SUBDIR/4.9
411GNUSTL_LIBS=$GNUSTL_DIR/libs
412
413STLPORT_DIR=$NDK_DIR/$STLPORT_SUBDIR
414STLPORT_LIBS=$STLPORT_DIR/libs
415
416LIBCXX_DIR=$NDK_DIR/$LIBCXX_SUBDIR
417LIBCXX_LIBS=$LIBCXX_DIR/libs
418LIBCXX_SUPPORT_LIB=libc++abi
419
420SUPPORT_DIR=$NDK_DIR/$SUPPORT_SUBDIR
421
422COMPILER_RT_DIR=$NDK_DIR/$COMPILER_RT_SUBDIR
423COMPILER_RT_LIBS=$COMPILER_RT_DIR/libs
424
425if [ "$STL" = "libcxx" -o "$STL" = "libc++" ]; then
426    dump "Copying c++ runtime headers and libraries (with $LIBCXX_SUPPORT_LIB)..."
427else
428    dump "Copying c++ runtime headers and libraries..."
429fi
430
431ABI_STL="$TMPDIR/$ABI_CONFIGURE_TARGET"
432ABI_STL_INCLUDE="$TMPDIR/include/c++/$GCC_BASE_VERSION"
433ABI_STL_INCLUDE_TARGET="$ABI_STL_INCLUDE/$ABI_CONFIGURE_TARGET"
434
435# $1: filenames of headers
436copy_abi_headers () {
437  local ABI_NAME=$1
438  shift
439
440  for header in $@; do
441    (set -e; cd $ABI_STL_INCLUDE && cp -a ../../$ABI_NAME/include/$header $header) || exit 1
442  done
443}
444
445# Copy common STL headers (i.e. the non-arch-specific ones)
446copy_stl_common_headers () {
447    case $STL in
448        gnustl)
449            copy_directory "$GNUSTL_DIR/include" "$ABI_STL_INCLUDE"
450            ;;
451        libcxx|libc++)
452            copy_directory "$LIBCXX_DIR/libcxx/include" "$ABI_STL_INCLUDE"
453            copy_directory "$SUPPORT_DIR/include" "$ABI_STL_INCLUDE"
454            if [ "$LIBCXX_SUPPORT_LIB" = "gabi++" ]; then
455                copy_directory "$STLPORT_DIR/../gabi++/include" "$ABI_STL_INCLUDE/../../gabi++/include"
456                copy_abi_headers gabi++ cxxabi.h unwind.h unwind-arm.h unwind-itanium.h gabixx_config.h
457            elif [ "$LIBCXX_SUPPORT_LIB" = "libc++abi" ]; then
458                copy_directory "$LIBCXX_DIR/../llvm-libc++abi/libcxxabi/include" "$ABI_STL_INCLUDE/../../llvm-libc++abi/include"
459                copy_abi_headers llvm-libc++abi cxxabi.h libunwind.h unwind.h
460            else
461                dump "ERROR: Unknown libc++ support lib: $LIBCXX_SUPPORT_LIB"
462                exit 1
463            fi
464            ;;
465        stlport)
466            copy_directory "$STLPORT_DIR/stlport" "$ABI_STL_INCLUDE"
467            copy_directory "$STLPORT_DIR/../gabi++/include" "$ABI_STL_INCLUDE/../../gabi++/include"
468            copy_abi_headers gabi++ cxxabi.h unwind.h unwind-arm.h unwind-itanium.h gabixx_config.h
469            ;;
470    esac
471}
472
473# $1: Source ABI (e.g. 'armeabi')
474# #2  Optional destination path of additional header to copy (eg. include/bits), default to empty
475# $3: Optional source path of additional additional header to copy, default to empty
476# $4: Optional destination directory, default to empty (e.g. "", "thumb", "armv7-a/thumb")
477# $5: Optional source directory, default to empty (e.g. "", "thumb", "armv7-a/thumb")
478copy_stl_libs () {
479    local ABI=$1
480    local HEADER_DST=$2
481    local HEADER_SRC=$3
482    local DEST_DIR=$4
483    local SRC_DIR=$5
484    local ABI_SRC_DIR=$ABI
485
486    if [ -n "$SRC_DIR" ]; then
487        ABI_SRC_DIR=$ABI/$SRC_DIR
488    else
489        if [ "$DEST_DIR" != "${DEST_DIR%%/*}" ] ; then
490            ABI_SRC_DIR=$ABI/`basename $DEST_DIR`
491        fi
492    fi
493
494    case $STL in
495        gnustl)
496            if [ "$HEADER_SRC" != "" ]; then
497                copy_directory "$GNUSTL_LIBS/$ABI/include/$HEADER_SRC" "$ABI_STL_INCLUDE_TARGET/$HEADER_DST"
498            fi
499            copy_file_list "$GNUSTL_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libgnustl_shared.so"
500            copy_file_list "$GNUSTL_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libsupc++.a"
501            cp -p "$GNUSTL_LIBS/$ABI_SRC_DIR/libgnustl_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
502            ;;
503        libcxx|libc++)
504            copy_file_list "$LIBCXX_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libc++_shared.so"
505            cp -p "$LIBCXX_LIBS/$ABI_SRC_DIR/libc++_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
506            ;;
507        stlport)
508            copy_file_list "$STLPORT_LIBS/$ABI_SRC_DIR" "$ABI_STL/lib/$DEST_DIR" "libstlport_shared.so"
509            cp -p "$STLPORT_LIBS/$ABI_SRC_DIR/libstlport_static.a" "$ABI_STL/lib/$DEST_DIR/libstdc++.a"
510            ;;
511        *)
512            dump "ERROR: Unsupported STL: $STL"
513            exit 1
514            ;;
515    esac
516}
517
518# $1: Source ABI (e.g. 'armeabi')
519copy_stl_libs_for_abi () {
520    local ABI=$1
521
522    if [ "$(convert_abi_to_arch "$ABI")" != "$ARCH" ]; then
523        dump "ERROR: ABI '$ABI' does not match ARCH '$ARCH'"
524        exit 1
525    fi
526
527    case $ABI in
528        armeabi)
529            copy_stl_libs armeabi          "bits"                "bits"
530            copy_stl_libs armeabi          "thumb/bits"          "bits"       "/thumb"
531            ;;
532        armeabi-v7a)
533            copy_stl_libs armeabi-v7a      "armv7-a/bits"        "bits"       "armv7-a"
534            copy_stl_libs armeabi-v7a      "armv7-a/thumb/bits"  "bits"       "armv7-a/thumb"
535            ;;
536        armeabi-v7a-hard)
537            copy_stl_libs armeabi-v7a-hard ""                    ""           "armv7-a/hard"       "."
538            copy_stl_libs armeabi-v7a-hard ""                    ""           "armv7-a/thumb/hard" "thumb"
539            ;;
540        x86_64)
541            if [ "$STL" = "gnustl" ]; then
542                copy_stl_libs x86_64       "32/bits"             "32/bits"    ""                   "lib"
543                copy_stl_libs x86_64       "bits"                "bits"       "../lib64"           "lib64"
544                copy_stl_libs x86_64       "x32/bits"            "x32/bits"   "../libx32"          "libx32"
545            else
546                copy_stl_libs x86_64       ""                    ""           "../lib64"           "."
547            fi
548            ;;
549        mips64)
550            if [ "$STL" = "gnustl" ]; then
551                copy_stl_libs mips64       "32/mips-r1/bits"     "32/mips-r1/bits"  ""             "lib"
552                copy_stl_libs mips64       "32/mips-r2/bits"     "32/mips-r2/bits"  "../libr2"     "libr2"
553                copy_stl_libs mips64       "32/mips-r6/bits"     "32/mips-r6/bits"  "../libr6"     "libr6"
554                copy_stl_libs mips64       "bits"                "bits"             "../lib64"     "lib64"
555            else
556                copy_stl_libs mips64       ""                    ""                 "../lib64"     "."
557            fi
558            ;;
559        mips|mips32r6)
560            if [ "$STL" = "gnustl" ]; then
561                copy_stl_libs mips         "bits"                "bits"             "../lib"       "lib"
562                copy_stl_libs mips         "mips-r2/bits"        "mips-r2/bits"     "../libr2"     "libr2"
563                copy_stl_libs mips         "mips-r6/bits"        "mips-r6/bits"     "../libr6"     "libr6"
564            else
565                copy_stl_libs mips         "bits"                "bits"
566            fi
567            ;;
568        *)
569            copy_stl_libs "$ABI"           "bits"                "bits"
570            ;;
571    esac
572}
573
574mkdir -p "$ABI_STL_INCLUDE_TARGET"
575fail_panic "Can't create directory: $ABI_STL_INCLUDE_TARGET"
576copy_stl_common_headers
577for ABI in $(echo "$ABIS" | tr ',' ' '); do
578  copy_stl_libs_for_abi "$ABI"
579done
580
581# Install or Package
582if [ -n "$INSTALL_DIR" ] ; then
583    dump "Copying files to: $INSTALL_DIR"
584    if [ ! -d "$INSTALL_DIR" ]; then
585        move_directory "$TMPDIR" "$INSTALL_DIR"
586    else
587        copy_directory "$TMPDIR" "$INSTALL_DIR"
588    fi
589else
590    PACKAGE_FILE="$PACKAGE_DIR/$TOOLCHAIN_NAME.tar.bz2"
591    dump "Creating package file: $PACKAGE_FILE"
592    pack_archive "$PACKAGE_FILE" "`dirname $TMPDIR`" "$TOOLCHAIN_NAME"
593    fail_panic "Could not create tarball from $TMPDIR"
594fi
595dump "Cleaning up..."
596rm -rf $TMPDIR
597
598dump "Done."
599