1#!/usr/bin/env bash
2
3# ====================================================================
4# Sets the cross compile environment for Android
5#
6# Based upon OpenSSL's setenv-android.sh by TH, JW, and SM.
7# Heavily modified by JWW for Crypto++.
8# Updated by Skycoder42 for current recommendations for Android.
9# Modified by JWW for LDNS.
10# ====================================================================
11
12#########################################
13#####        Some validation        #####
14#########################################
15
16if [ -z "$ANDROID_API" ]; then
17    echo "ANDROID_API is not set. Please set it"
18    [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
19fi
20
21if [ -z "$ANDROID_CPU" ]; then
22    echo "ANDROID_CPU is not set. Please set it"
23    [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
24fi
25
26if [ ! -d "$ANDROID_NDK_ROOT" ]; then
27    echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
28    echo "NDK root is $ANDROID_NDK_ROOT"
29    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
30fi
31
32# cryptest-android.sh may run this script without sourcing.
33if [ "$0" = "${BASH_SOURCE[0]}" ]; then
34    echo "setenv-android.sh is usually sourced, but not this time."
35fi
36
37#####################################################################
38
39# Need to set THIS_HOST to darwin-x86_64, linux-x86_64,
40# windows, or windows-x86_64
41
42if [[ "$(uname -s | grep -i -c darwin)" -ne 0 ]]; then
43    THIS_HOST=darwin-x86_64
44elif [[ "$(uname -s | grep -i -c linux)" -ne 0 ]]; then
45    THIS_HOST=linux-x86_64
46else
47    echo "ERROR: Unknown host"
48    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
49fi
50
51ANDROID_TOOLCHAIN="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$THIS_HOST/bin"
52ANDROID_SYSROOT="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$THIS_HOST/sysroot"
53
54# Error checking
55if [ ! -d "$ANDROID_TOOLCHAIN" ]; then
56    echo "ERROR: ANDROID_TOOLCHAIN is not a valid path. Please set it."
57    echo "Path is $ANDROID_TOOLCHAIN"
58    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
59fi
60
61# Error checking
62if [ ! -d "$ANDROID_SYSROOT" ]; then
63    echo "ERROR: ANDROID_SYSROOT is not a valid path. Please set it."
64    echo "Path is $ANDROID_SYSROOT"
65    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
66fi
67
68#####################################################################
69
70THE_ARCH=$(tr '[:upper:]' '[:lower:]' <<< "$ANDROID_CPU")
71
72# https://developer.android.com/ndk/guides/abis.html
73case "$THE_ARCH" in
74  armv7*|armeabi*)
75    CC="armv7a-linux-androideabi$ANDROID_API-clang"
76    CXX="armv7a-linux-androideabi$ANDROID_API-clang++"
77    LD="arm-linux-androideabi-ld"
78    AS="arm-linux-androideabi-as"
79    AR="arm-linux-androideabi-ar"
80    RANLIB="arm-linux-androideabi-ranlib"
81    STRIP="arm-linux-androideabi-strip"
82
83    CFLAGS="-march=armv7-a -mthumb -mfloat-abi=softfp -funwind-tables -fexceptions"
84    CXXFLAGS="-march=armv7-a -mthumb -mfloat-abi=softfp -funwind-tables -fexceptions -frtti"
85    ;;
86
87  armv8*|aarch64|arm64)
88    CC="aarch64-linux-android$ANDROID_API-clang"
89    CXX="aarch64-linux-android$ANDROID_API-clang++"
90    LD="aarch64-linux-android-ld"
91    AS="aarch64-linux-android-as"
92    AR="aarch64-linux-android-ar"
93    RANLIB="aarch64-linux-android-ranlib"
94    STRIP="aarch64-linux-android-strip"
95
96    CFLAGS="-funwind-tables -fexceptions"
97    CXXFLAGS="-funwind-tables -fexceptions -frtti"
98    ;;
99
100  x86)
101    CC="i686-linux-android$ANDROID_API-clang"
102    CXX="i686-linux-android$ANDROID_API-clang++"
103    LD="i686-linux-android-ld"
104    AS="i686-linux-android-as"
105    AR="i686-linux-android-ar"
106    RANLIB="i686-linux-android-ranlib"
107    STRIP="i686-linux-android-strip"
108
109    CFLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions"
110    CXXFLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions -frtti"
111    ;;
112
113  x86_64|x64)
114    CC="x86_64-linux-android$ANDROID_API-clang"
115    CXX="x86_64-linux-android$ANDROID_API-clang++"
116    LD="x86_64-linux-android-ld"
117    AS="x86_64-linux-android-as"
118    AR="x86_64-linux-android-ar"
119    RANLIB="x86_64-linux-android-ranlib"
120    STRIP="x86_64-linux-android-strip"
121
122    CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions"
123    CXXFLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions -frtti"
124    ;;
125
126  *)
127    echo "ERROR: Unknown architecture $ANDROID_CPU"
128    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
129    ;;
130esac
131
132#####################################################################
133
134# Error checking
135if [ ! -e "$ANDROID_TOOLCHAIN/$CC" ]; then
136    echo "ERROR: Failed to find Android clang. Please edit this script."
137    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
138fi
139
140# Error checking
141if [ ! -e "$ANDROID_TOOLCHAIN/$CXX" ]; then
142    echo "ERROR: Failed to find Android clang++. Please edit this script."
143    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
144fi
145
146# Error checking
147if [ ! -e "$ANDROID_TOOLCHAIN/$RANLIB" ]; then
148    echo "ERROR: Failed to find Android ranlib. Please edit this script."
149    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
150fi
151
152# Error checking
153if [ ! -e "$ANDROID_TOOLCHAIN/$AR" ]; then
154    echo "ERROR: Failed to find Android ar. Please edit this script."
155    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
156fi
157
158# Error checking
159if [ ! -e "$ANDROID_TOOLCHAIN/$AS" ]; then
160    echo "ERROR: Failed to find Android as. Please edit this script."
161    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
162fi
163
164# Error checking
165if [ ! -e "$ANDROID_TOOLCHAIN/$LD" ]; then
166    echo "ERROR: Failed to find Android ld. Please edit this script."
167    [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
168fi
169
170#####################################################################
171
172LENGTH=${#ANDROID_TOOLCHAIN}
173SUBSTR=${PATH:0:$LENGTH}
174if [ "$SUBSTR" != "$ANDROID_TOOLCHAIN" ]; then
175    export PATH="$ANDROID_TOOLCHAIN:$PATH"
176fi
177
178#####################################################################
179
180export CPP CC CXX LD AS AR RANLIB STRIP
181export ANDROID_SYSROOT="$AOSP_SYSROOT"
182export CPPFLAGS="-D__ANDROID_API__=$ANDROID_API"
183export CFLAGS="$CFLAGS --sysroot=$AOSP_SYSROOT"
184export CXXFLAGS="$CXXFLAGS -stdlib=libc++ --sysroot=$AOSP_SYSROOT"
185
186#####################################################################
187
188echo "ANDROID_TOOLCHAIN: $ANDROID_TOOLCHAIN"
189
190echo "CPP: $(command -v "$CPP")"
191echo "CC: $(command -v "$CC")"
192echo "CXX: $(command -v "$CXX")"
193echo "LD: $(command -v "$LD")"
194echo "AS: $(command -v "$AS")"
195echo "AR: $(command -v "$AR")"
196
197echo "ANDROID_SYSROOT: $ANDROID_SYSROOT"
198
199echo "CPPFLAGS: $CPPFLAGS"
200echo "CFLAGS: $CFLAGS"
201echo "CXXFLAGS: $CXXFLAGS"
202
203[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
204