• 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
34ARCH=
35register_option "--arch=<name>" do_arch "Specify target architecture" "arm"
36do_arch () { ARCH=$1; }
37
38NDK_DIR=`dirname $0`
39NDK_DIR=`dirname $NDK_DIR`
40NDK_DIR=`dirname $NDK_DIR`
41register_var_option "--ndk-dir=<path>" NDK_DIR "Take source files from NDK at <path>"
42
43# Create 32-bit host toolchain by default
44SYSTEM=$HOST_TAG32
45register_var_option "--system=<name>" SYSTEM "Specify host system"
46
47PACKAGE_DIR=/tmp/ndk-$USER
48register_var_option "--package-dir=<path>" PACKAGE_DIR "Place package file in <path>"
49
50INSTALL_DIR=
51register_var_option "--install-dir=<path>" INSTALL_DIR "Don't create package, install files to <path> instead."
52
53PLATFORM=
54register_option "--platform=<name>" do_platform "Specify target Android platform/API level." "android-3"
55do_platform () { PLATFORM=$1; }
56
57extract_parameters "$@"
58
59# Check NDK_DIR
60if [ ! -d "$NDK_DIR/build/core" ] ; then
61    echo "Invalid source NDK directory: $NDK_DIR"
62    echo "Please use --ndk-dir=<path> to specify the path of an installed NDK."
63    exit 1
64fi
65
66# Check ARCH
67if [ -z "$ARCH" ]; then
68    case $TOOLCHAIN_NAME in
69        arm-*)
70            ARCH=arm
71            ;;
72        x86-*)
73            ARCH=x86
74            ;;
75        mips*)
76            ARCH=mips
77            ;;
78        *)
79            ARCH=arm
80            ;;
81    esac
82    log "Auto-config: --arch=$ARCH"
83fi
84
85# Check toolchain name
86if [ -z "$TOOLCHAIN_NAME" ]; then
87    TOOLCHAIN_NAME=$(get_default_toolchain_name_for_arch $ARCH)
88    echo "Auto-config: --toolchain=$TOOLCHAIN_NAME"
89fi
90
91# Detect LLVM version from toolchain name
92if [ -z "$LLVM_VERSION" ]; then
93    LLVM_VERSION_EXTRACT=$(echo "$TOOLCHAIN_NAME" | grep 'clang[0-9]\.[0-9]$' | sed -e 's/.*-clang//')
94    if [ -n "$LLVM_VERSION_EXTRACT" ]; then
95        TOOLCHAIN_NAME=$(get_default_toolchain_name_for_arch $ARCH)
96        LLVM_VERSION=$LLVM_VERSION_EXTRACT
97        echo "Auto-config: --toolchain=$TOOLCHAIN_NAME, --llvm-version=$LLVM_VERSION"
98    fi
99fi
100
101# Check PLATFORM
102if [ -z "$PLATFORM" ]; then
103    case $ARCH in
104        arm) PLATFORM=android-3
105            ;;
106        x86)
107            PLATFORM=android-9
108            ;;
109        mips)
110            # Set it to android-9
111            PLATFORM=android-9
112            ;;
113    esac
114    log "Auto-config: --platform=$PLATFORM"
115fi
116
117if [ ! -d "$NDK_DIR/platforms/$PLATFORM" ] ; then
118    echo "Invalid platform name: $PLATFORM"
119    echo "Please use --platform=<name> with one of:" `(cd "$NDK_DIR/platforms" && ls)`
120    exit 1
121fi
122
123# Check toolchain name
124TOOLCHAIN_PATH="$NDK_DIR/toolchains/$TOOLCHAIN_NAME"
125if [ ! -d "$TOOLCHAIN_PATH" ] ; then
126    echo "Invalid toolchain name: $TOOLCHAIN_NAME"
127    echo "Please use --toolchain=<name> with the name of a toolchain supported by the source NDK."
128    echo "Try one of: " `(cd "$NDK_DIR/toolchains" && ls)`
129    exit 1
130fi
131
132# Extract architecture from platform name
133parse_toolchain_name $TOOLCHAIN_NAME
134
135# Check that there are any platform files for it!
136(cd $NDK_DIR/platforms && ls -d */arch-${ARCH} >/dev/null 2>&1 )
137if [ $? != 0 ] ; then
138    echo "Platform $PLATFORM doesn't have any files for this architecture: $ARCH"
139    echo "Either use --platform=<name> or --toolchain=<name> to select a different"
140    echo "platform or arch-dependent toolchain name (respectively)!"
141    exit 1
142fi
143
144# Compute source sysroot
145SRC_SYSROOT="$NDK_DIR/platforms/$PLATFORM/arch-$ARCH"
146if [ ! -d "$SRC_SYSROOT" ] ; then
147    echo "No platform files ($PLATFORM) for this architecture: $ARCH"
148    exit 1
149fi
150
151# Check that we have any prebuilts GCC toolchain here
152if [ ! -d "$TOOLCHAIN_PATH/prebuilt" ] ; then
153    echo "Toolchain is missing prebuilt files: $TOOLCHAIN_NAME"
154    echo "You must point to a valid NDK release package!"
155    exit 1
156fi
157
158if [ ! -d "$TOOLCHAIN_PATH/prebuilt/$SYSTEM" ] ; then
159    echo "Host system '$SYSTEM' is not supported by the source NDK!"
160    echo "Try --system=<name> with one of: " `(cd $TOOLCHAIN_PATH/prebuilt && ls) | grep -v gdbserver`
161    exit 1
162fi
163
164TOOLCHAIN_PATH="$TOOLCHAIN_PATH/prebuilt/$SYSTEM"
165TOOLCHAIN_GCC=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET-gcc
166
167if [ ! -f "$TOOLCHAIN_GCC" ] ; then
168    echo "Toolchain $TOOLCHAIN_GCC is missing!"
169    exit 1
170fi
171
172if [ -n "$LLVM_VERSION" ]; then
173    LLVM_TOOLCHAIN_PATH="$NDK_DIR/toolchains/llvm-$LLVM_VERSION"
174    # Check that we have any prebuilts LLVM toolchain here
175    if [ ! -d "$LLVM_TOOLCHAIN_PATH/prebuilt" ] ; then
176        echo "LLVM Toolchain is missing prebuilt files"
177        echo "You must point to a valid NDK release package!"
178        exit 1
179    fi
180
181    if [ ! -d "$LLVM_TOOLCHAIN_PATH/prebuilt/$SYSTEM" ] ; then
182        echo "Host system '$SYSTEM' is not supported by the source NDK!"
183        echo "Try --system=<name> with one of: " `(cd $LLVM_TOOLCHAIN_PATH/prebuilt && ls)`
184        exit 1
185    fi
186    LLVM_TOOLCHAIN_PATH="$LLVM_TOOLCHAIN_PATH/prebuilt/$SYSTEM"
187fi
188
189# Get GCC_BASE_VERSION.  Note that GCC_BASE_VERSION may be slightly different from GCC_VERSION.
190# eg. In gcc4.6 GCC_BASE_VERSION is "4.6.x-google"
191LIBGCC_PATH=`$TOOLCHAIN_GCC -print-libgcc-file-name`
192LIBGCC_BASE_PATH=${LIBGCC_PATH%/*}         # base path of libgcc.a
193GCC_BASE_VERSION=${LIBGCC_BASE_PATH##*/}   # stuff after the last /
194
195# Create temporary directory
196TMPDIR=$NDK_TMPDIR/standalone/$TOOLCHAIN_NAME
197
198dump "Copying prebuilt binaries..."
199# Now copy the GCC toolchain prebuilt binaries
200run copy_directory "$TOOLCHAIN_PATH" "$TMPDIR"
201
202if [ -n "$LLVM_VERSION" ]; then
203  # Copy the clang/llvm toolchain prebuilt binaries
204  run copy_directory "$LLVM_TOOLCHAIN_PATH" "$TMPDIR"
205
206  # Move clang and clang++ to clang${LLVM_VERSION} and clang${LLVM_VERSION}++,
207  # then create scripts linking them with predefined -target flag.  This is to
208  # make clang/++ easier drop-in replacement for gcc/++ in NDK standalone mode.
209  # Note that the file name of "clang" isn't important, and the trailing
210  # "++" tells clang to compile in C++ mode
211  LLVM_TARGET=
212  case "$ARCH" in
213      arm) # NOte: -target may change by clang based on the
214           #        presence of subsequent -march=armv7-a and/or -mthumb
215          LLVM_TARGET=armv5te-none-linux-androideabi
216          ;;
217      x86)
218          LLVM_TARGET=i686-none-linux-android
219          ;;
220      mips)
221          LLVM_TARGET=mipsel-none-linux-android
222          ;;
223      *)
224        dump "ERROR: Unsupported NDK architecture!"
225  esac
226  # Need to remove '.' from LLVM_VERSION when constructing new clang name,
227  # otherwise clang3.1++ may still compile *.c code as C, not C++, which
228  # is not consistent with g++
229  LLVM_VERSION_WITHOUT_DOT=$(echo "$LLVM_VERSION" | sed -e "s!\.!!")
230  mv "$TMPDIR/bin/clang${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}"
231  if [ -h "$TMPDIR/bin/clang++${HOST_EXE}" ] ; then
232    ## clang++ is a link to clang.  Remove it and reconstruct
233    rm "$TMPDIR/bin/clang++${HOST_EXE}"
234    ln -s "clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE}" "$TMPDIR/bin/clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE}"
235  else
236    mv "$TMPDIR/bin/clang++${HOST_EXE}" "$TMPDIR/bin/clang$LLVM_VERSION_WITHOUT_DOT++${HOST_EXE}"
237  fi
238
239  cat > "$TMPDIR/bin/clang" <<EOF
240if [ "\$1" != "-cc1" ]; then
241    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT -target $LLVM_TARGET "\$@"
242else
243    # target/triple already spelled out.
244    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT "\$@"
245fi
246EOF
247  cat > "$TMPDIR/bin/clang++" <<EOF
248if [ "\$1" != "-cc1" ]; then
249    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT++ -target $LLVM_TARGET "\$@"
250else
251    # target/triple already spelled out.
252    \`dirname \$0\`/clang$LLVM_VERSION_WITHOUT_DOT++ "\$@"
253fi
254EOF
255  chmod 0755 "$TMPDIR/bin/clang" "$TMPDIR/bin/clang++"
256
257  if [ -n "$HOST_EXE" ] ; then
258    cat > "$TMPDIR/bin/clang.cmd" <<EOF
259@echo off
260if "%1" == "-cc1" goto :L
261%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE} -target $LLVM_TARGET %*
262if ERRORLEVEL 1 exit /b 1
263goto :done
264:L
265rem target/triple already spelled out.
266%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}${HOST_EXE} %*
267if ERRORLEVEL 1 exit /b 1
268:done
269EOF
270    cat > "$TMPDIR/bin/clang++.cmd" <<EOF
271@echo off
272if "%1" == "-cc1" goto :L
273%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE} -target $LLVM_TARGET %*
274if ERRORLEVEL 1 exit /b 1
275goto :done
276:L
277rem target/triple already spelled out.
278%~dp0\\clang${LLVM_VERSION_WITHOUT_DOT}++${HOST_EXE} %*
279if ERRORLEVEL 1 exit /b 1
280:done
281EOF
282  fi
283fi
284
285dump "Copying sysroot headers and libraries..."
286# Copy the sysroot under $TMPDIR/sysroot. The toolchain was built to
287# expect the sysroot files to be placed there!
288run copy_directory_nolinks "$SRC_SYSROOT" "$TMPDIR/sysroot"
289
290dump "Copying libstdc++ headers and libraries..."
291
292GNUSTL_DIR=$NDK_DIR/$GNUSTL_SUBDIR/$GCC_VERSION
293GNUSTL_LIBS=$GNUSTL_DIR/libs
294
295ABI_STL="$TMPDIR/$ABI_CONFIGURE_TARGET"
296ABI_STL_INCLUDE="$TMPDIR/include/c++/$GCC_BASE_VERSION"
297
298copy_directory "$GNUSTL_DIR/include" "$ABI_STL_INCLUDE"
299ABI_STL_INCLUDE_TARGET="$ABI_STL_INCLUDE/$ABI_CONFIGURE_TARGET"
300mkdir -p "$ABI_STL_INCLUDE_TARGET"
301fail_panic "Can't create directory: $ABI_STL_INCLUDE_TARGET"
302case "$ARCH" in
303    arm)
304        copy_directory "$GNUSTL_LIBS/armeabi/include/bits" "$ABI_STL_INCLUDE_TARGET/bits"
305        copy_file_list "$GNUSTL_LIBS/armeabi" "$ABI_STL/lib" "libgnustl_shared.so"
306        copy_file_list "$GNUSTL_LIBS/armeabi" "$ABI_STL/lib" "libsupc++.a"
307        cp -p "$GNUSTL_LIBS/armeabi/libgnustl_static.a" "$ABI_STL/lib/libstdc++.a"
308
309        copy_directory "$GNUSTL_LIBS/armeabi/include/bits" "$ABI_STL_INCLUDE_TARGET/thumb/bits"
310        copy_file_list "$GNUSTL_LIBS/armeabi/thumb" "$ABI_STL/lib/thumb" "libgnustl_shared.so"
311        copy_file_list "$GNUSTL_LIBS/armeabi/thumb" "$ABI_STL/lib/thumb" "libsupc++.a"
312        cp -p "$GNUSTL_LIBS/armeabi/thumb/libgnustl_static.a" "$ABI_STL/lib/thumb/libstdc++.a"
313
314        copy_directory "$GNUSTL_LIBS/armeabi-v7a/include/bits" "$ABI_STL_INCLUDE_TARGET/armv7-a/bits"
315        copy_file_list "$GNUSTL_LIBS/armeabi-v7a" "$ABI_STL/lib/armv7-a" "libgnustl_shared.so"
316        copy_file_list "$GNUSTL_LIBS/armeabi-v7a" "$ABI_STL/lib/armv7-a" "libsupc++.a"
317        cp -p "$GNUSTL_LIBS/armeabi-v7a/libgnustl_static.a" "$ABI_STL/lib/armv7-a/libstdc++.a"
318
319        copy_directory "$GNUSTL_LIBS/armeabi-v7a/include/bits" "$ABI_STL_INCLUDE_TARGET/armv7-a/thumb/bits"
320        copy_file_list "$GNUSTL_LIBS/armeabi-v7a/thumb" "$ABI_STL/lib/armv7-a/thumb/" "libgnustl_shared.so"
321        copy_file_list "$GNUSTL_LIBS/armeabi-v7a/thumb" "$ABI_STL/lib/armv7-a/thumb/" "libsupc++.a"
322        cp -p "$GNUSTL_LIBS/armeabi-v7a/thumb/libgnustl_static.a" "$ABI_STL/lib/armv7-a//thumb/libstdc++.a"
323        ;;
324    x86)
325        copy_directory "$GNUSTL_LIBS/x86/include/bits" "$ABI_STL_INCLUDE_TARGET/bits"
326        copy_file_list "$GNUSTL_LIBS/x86" "$ABI_STL/lib" "libgnustl_shared.so"
327        copy_file_list "$GNUSTL_LIBS/x86" "$ABI_STL/lib" "libsupc++.a"
328        cp -p "$GNUSTL_LIBS/x86/libgnustl_static.a" "$ABI_STL/lib/libstdc++.a"
329        ;;
330    mips)
331        copy_directory "$GNUSTL_LIBS/mips/include/bits" "$ABI_STL_INCLUDE_TARGET/bits"
332        copy_file_list "$GNUSTL_LIBS/mips" "$ABI_STL/lib" "libgnustl_shared.so"
333        copy_file_list "$GNUSTL_LIBS/mips" "$ABI_STL/lib" "libsupc++.a"
334        cp -p "$GNUSTL_LIBS/mips/libgnustl_static.a" "$ABI_STL/lib/libstdc++.a"
335        ;;
336    *)
337        dump "ERROR: Unsupported NDK architecture!"
338esac
339
340# Install or Package
341if [ -n "$INSTALL_DIR" ] ; then
342    dump "Copying files to: $INSTALL_DIR"
343    run copy_directory "$TMPDIR" "$INSTALL_DIR"
344else
345    PACKAGE_FILE="$PACKAGE_DIR/$TOOLCHAIN_NAME.tar.bz2"
346    dump "Creating package file: $PACKAGE_FILE"
347    pack_archive "$PACKAGE_FILE" "`dirname $TMPDIR`" "$TOOLCHAIN_NAME"
348    fail_panic "Could not create tarball from $TMPDIR"
349fi
350dump "Cleaning up..."
351run rm -rf $TMPDIR
352
353dump "Done."
354