1#!/bin/bash
2#
3# setup_toolchain.sh: Sets toolchain environment variables used by other scripts.
4
5# Fail-fast if anything in the script fails.
6set -e
7
8# check that the preconditions for this script are met
9if [ $(type -t verbose) != 'function' ]; then
10  echo "ERROR: The verbose function is expected to be defined"
11  return 1
12fi
13
14if [ $(type -t exportVar) != 'function' ]; then
15  echo "ERROR: The exportVar function is expected to be defined"
16  return 1
17fi
18
19if [ $(type -t absPath) != 'function' ]; then
20  echo "ERROR: The absPath function is expected to be defined"
21  return 1
22fi
23
24if [ -z "$SCRIPT_DIR" ]; then
25  echo "ERROR: The SCRIPT_DIR variable is expected to be defined"
26  return 1
27fi
28
29function default_toolchain() {
30  NDK_REV=${NDK_REV-10exp}
31  ANDROID_ARCH=${ANDROID_ARCH-arm}
32  
33  if [[ $ANDROID_ARCH == *64* ]]; then
34    API_LEVEL=L # Experimental Android L-Release system images
35  else
36    API_LEVEL=14 # Official Android 4.0 system images  
37  fi
38
39  TOOLCHAIN_DIR=${SCRIPT_DIR}/../toolchains
40  if [ $(uname) == "Darwin" ]; then
41    verbose "Using Mac toolchain."
42    TOOLCHAIN_TYPE=ndk-r$NDK_REV-$ANDROID_ARCH-darwin_v$API_LEVEL
43  else
44    verbose "Using Linux toolchain."
45    TOOLCHAIN_TYPE=ndk-r$NDK_REV-$ANDROID_ARCH-linux_v$API_LEVEL
46  fi
47  exportVar ANDROID_TOOLCHAIN "${TOOLCHAIN_DIR}/${TOOLCHAIN_TYPE}/bin"
48
49  # if the toolchain doesn't exist on your machine then we need to fetch it
50  if [ ! -d "$ANDROID_TOOLCHAIN" ]; then
51    mkdir -p $TOOLCHAIN_DIR
52    # enter the toolchain directory then download, unpack, and remove the tarball
53    pushd $TOOLCHAIN_DIR
54    TARBALL=ndk-r$NDK_REV-v$API_LEVEL.tgz
55
56    ${SCRIPT_DIR}/download_toolchains.py \
57        http://chromium-skia-gm.commondatastorage.googleapis.com/android-toolchains/$TARBALL \
58        $TOOLCHAIN_DIR/$TARBALL
59    tar -xzf $TARBALL $TOOLCHAIN_TYPE
60    rm $TARBALL
61    popd
62  fi 
63
64  verbose "Targeting NDK API $API_LEVEL for use on Android 4.0 (NDK Revision $NDK_REV) and above"  
65}
66
67#check to see if the toolchain has been defined and if not setup the default toolchain
68if [ -z "$ANDROID_TOOLCHAIN" ]; then
69  default_toolchain
70  if [ ! -d "$ANDROID_TOOLCHAIN" ]; then
71    echo "ERROR: unable to download/setup the required toolchain (${ANDROID_TOOLCHAIN})"
72    return 1;
73  fi
74fi
75
76GCC=$(command ls $ANDROID_TOOLCHAIN/*-gcc | head -n1)
77if [ -z "$GCC" ]; then
78  echo "ERROR: Could not find Android cross-compiler in: $ANDROID_TOOLCHAIN"
79  return 1
80fi
81
82# Remove the '-gcc' at the end to get the full toolchain prefix
83ANDROID_TOOLCHAIN_PREFIX=${GCC%%-gcc}
84
85CCACHE=${ANDROID_MAKE_CCACHE-$(which ccache || true)}
86
87exportVar CC "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-gcc"
88exportVar CXX "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-g++"
89exportVar LINK "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-gcc"
90
91exportVar AR "$ANDROID_TOOLCHAIN_PREFIX-ar"
92exportVar RANLIB "$ANDROID_TOOLCHAIN_PREFIX-ranlib"
93exportVar OBJCOPY "$ANDROID_TOOLCHAIN_PREFIX-objcopy"
94exportVar STRIP "$ANDROID_TOOLCHAIN_PREFIX-strip"
95
96# Create symlinks for nm & readelf and add them to the path so that the ninja
97# build uses them instead of attempting to use the one on the system.
98# This is required to build using ninja on a Mac.
99ln -sf $ANDROID_TOOLCHAIN_PREFIX-nm $ANDROID_TOOLCHAIN/nm
100ln -sf $ANDROID_TOOLCHAIN_PREFIX-readelf $ANDROID_TOOLCHAIN/readelf
101ln -sf $ANDROID_TOOLCHAIN_PREFIX-as $ANDROID_TOOLCHAIN/as
102exportVar PATH $ANDROID_TOOLCHAIN:$PATH
103