1# Copyright 2015 Google Inc.
2#
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6#!/bin/bash
7#
8# setup_toolchain.sh: Sets toolchain environment variables used by other scripts.
9
10# Fail-fast if anything in the script fails.
11set -e
12
13# check that the preconditions for this script are met
14if [ $(type -t verbose) != 'function' ]; then
15  echo "ERROR: The verbose function is expected to be defined"
16  return 1
17fi
18
19if [ $(type -t exportVar) != 'function' ]; then
20  echo "ERROR: The exportVar function is expected to be defined"
21  return 1
22fi
23
24if [ $(type -t absPath) != 'function' ]; then
25  echo "ERROR: The absPath function is expected to be defined"
26  return 1
27fi
28
29if [ -z "$SCRIPT_DIR" ]; then
30  echo "ERROR: The SCRIPT_DIR variable is expected to be defined"
31  return 1
32fi
33
34function default_toolchain() {
35  TOOLCHAINS=${SCRIPT_DIR}/../toolchains
36
37  ANDROID_ARCH=${ANDROID_ARCH-arm}
38  LLVM=3.6
39  NDK=r10e
40
41  if [[ $ANDROID_ARCH == *64* ]]; then
42      API=21  # Android 5.0
43  else
44      API=14  # Android 4.0
45  fi
46
47  TOOLCHAIN=$ANDROID_ARCH-$NDK-$API
48  HOST=`uname | tr '[A-Z]' '[a-z]'`
49
50  exportVar ANDROID_TOOLCHAIN "${TOOLCHAINS}/${TOOLCHAIN}/bin"
51
52  if [ ! -d "$ANDROID_TOOLCHAIN" ]; then
53    mkdir -p $TOOLCHAINS
54    pushd $TOOLCHAINS
55    curl -o $NDK.bin https://dl.google.com/android/ndk/android-ndk-$NDK-$HOST-x86_64.bin
56    chmod +x $NDK.bin
57    ./$NDK.bin -y
58    ./android-ndk-$NDK/build/tools/make-standalone-toolchain.sh \
59        --arch=$ANDROID_ARCH    \
60        --llvm-version=$LLVM    \
61        --platform=android-$API \
62        --install_dir=$TOOLCHAIN
63    cp android-ndk-$NDK/prebuilt/android-$ANDROID_ARCH/gdbserver/gdbserver $TOOLCHAIN
64    rm $NDK.bin
65    rm -rf android-ndk-$NDK
66    popd
67  fi
68
69  verbose "Targeting NDK API $API (NDK Revision $NDK)"
70}
71
72#check to see if the toolchain has been defined and if not setup the default toolchain
73if [ -z "$ANDROID_TOOLCHAIN" ]; then
74  default_toolchain
75  if [ ! -d "$ANDROID_TOOLCHAIN" ]; then
76    echo "ERROR: unable to download/setup the required toolchain (${ANDROID_TOOLCHAIN})"
77    return 1;
78  fi
79fi
80
81GCC=$(command ls $ANDROID_TOOLCHAIN/*-gcc | head -n1)
82if [ -z "$GCC" ]; then
83  echo "ERROR: Could not find Android cross-compiler in: $ANDROID_TOOLCHAIN"
84  return 1
85fi
86
87# Remove the '-gcc' at the end to get the full toolchain prefix
88ANDROID_TOOLCHAIN_PREFIX=${GCC%%-gcc}
89
90CCACHE=${ANDROID_MAKE_CCACHE-$(which ccache || true)}
91
92# Cross compiling Android on Mac is not currently supported by gyp.
93# It doesn't appear to be supported on Windows either.
94# As of now, we will only support cross compiling on Linux.
95# libjpeg-turbo assembly code for x86 and x86-64 Android devices
96# must be disabled for Android on non-Linux platforms because
97# of this issue.  We still support compiling on Mac and other
98# variants for local development, but shipping versions of Skia
99# should be compiled on Linux for performance reasons.
100# TODO (msarett): Collect more information about this.
101if [ $(uname) == "Linux" ]; then
102  if [ -z $USE_CLANG ]; then
103    exportVar CC_target "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-gcc"
104    exportVar CXX_target "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-g++"
105    exportVar LINK_target "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-gcc"
106    exportVar CC_host "$CCACHE cc"
107    exportVar CXX_host "$CCACHE c++"
108    exportVar LINK_host "$CCACHE cc"
109  else
110    # temporarily disable ccache as it is generating errors
111    CCACHE=""
112    exportVar CC_target "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-clang"
113    exportVar CXX_target "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-clang++"
114    exportVar LINK_target "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-clang"
115    exportVar CC_host "$CCACHE clang"
116    exportVar CXX_host "$CCACHE clang++"
117    exportVar LINK_host "$CCACHE clang"
118  fi
119
120  exportVar AR_target "$ANDROID_TOOLCHAIN_PREFIX-ar"
121  exportVar RANLIB_target "$ANDROID_TOOLCHAIN_PREFIX-ranlib"
122  exportVar OBJCOPY_target "$ANDROID_TOOLCHAIN_PREFIX-objcopy"
123  exportVar STRIP_target "$ANDROID_TOOLCHAIN_PREFIX-strip"
124  exportVar AR_host "ar"
125  exportVar RANLIB_host "ranlib"
126  exportVar OBJCOPY_host "objcopy"
127  exportVar STRIP_host "strip"
128else
129  if [ -z $USE_CLANG ]; then
130    exportVar CC "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-gcc"
131    exportVar CXX "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-g++"
132    exportVar LINK "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-gcc"
133  else
134    # temporarily disable ccache as it is generating errors
135    CCACHE=""
136    exportVar CC "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-clang"
137    exportVar CXX "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-clang++"
138    exportVar LINK "$CCACHE $ANDROID_TOOLCHAIN_PREFIX-clang"
139  fi
140
141  exportVar AR "$ANDROID_TOOLCHAIN_PREFIX-ar"
142  exportVar RANLIB "$ANDROID_TOOLCHAIN_PREFIX-ranlib"
143  exportVar OBJCOPY "$ANDROID_TOOLCHAIN_PREFIX-objcopy"
144  exportVar STRIP "$ANDROID_TOOLCHAIN_PREFIX-strip"
145fi
146
147# Create symlinks for nm & readelf and add them to the path so that the ninja
148# build uses them instead of attempting to use the one on the system.
149# This is required to build using ninja on a Mac.
150if [ $(uname) == "Darwin" ]; then
151  ln -sf $ANDROID_TOOLCHAIN_PREFIX-nm $ANDROID_TOOLCHAIN/nm
152  ln -sf $ANDROID_TOOLCHAIN_PREFIX-readelf $ANDROID_TOOLCHAIN/readelf
153  ln -sf $ANDROID_TOOLCHAIN_PREFIX-as $ANDROID_TOOLCHAIN/as
154fi
155
156exportVar PATH $ANDROID_TOOLCHAIN:$PATH
157