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