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