1#!/usr/bin/env bash 2################################################################################ 3# THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY # 4# Read the zproject/README.md for information about making permanent changes. # 5################################################################################ 6# 7# Courtesy of Joe Eli McIlvain; original code at: 8# https://github.com/jemc/android_build_helper 9# android_build_helper.sh 10# 11# The following is a helper script for setting up android builds for 12# "native" libraries maintained with an autotools build system. 13# It merely helps to create the proper cross-compile environment. 14# It makes no attempt to wrap the library or make it accessible to Java code; 15# the intention is to make the bare library available to other "native" code. 16# 17# To get the latest version of this script, please download from: 18# https://github.com/jemc/android_build_helper 19# 20# You are free to modify and redistribute this script, but if you add 21# improvements, please consider submitting a pull request or patch to the 22# aforementioned upstream repository for the benefit of other users. 23# 24# This script is provided with no express or implied warranties. 25# 26 27# Get directory of current script (if not already set) 28# This directory is also the basis for the build directories the get created. 29if [ -z "$ANDROID_BUILD_DIR" ]; then 30 ANDROID_BUILD_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 31fi 32 33# Set up a variable to hold the global failure reasons, separated by newlines 34# (Empty string indicates no failure) 35ANDROID_BUILD_FAIL=() 36 37function android_build_check_fail { 38 if [ ! ${#ANDROID_BUILD_FAIL[@]} -eq 0 ]; then 39 echo "Android (${TOOLCHAIN_ARCH}) build failed for the following reasons:" 40 for reason in "${ANDROID_BUILD_FAIL[@]}"; do 41 local formatted_reason=" ${reason}" 42 echo "${formatted_reason}" 43 done 44 exit 1 45 fi 46} 47 48function android_build_set_env { 49 BUILD_ARCH=$1 50 51 export TOOLCHAIN_PATH="${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_PLATFORM}/bin" 52 53 # Set variables for each architecture 54 if [ $BUILD_ARCH == "arm" ]; then 55 export TOOLCHAIN_HOST="arm-linux-androideabi" 56 export TOOLCHAIN_COMP="armv7a-linux-androideabi${MIN_SDK_VERSION}" 57 export TOOLCHAIN_ABI="armeabi-v7a" 58 export TOOLCHAIN_ARCH="arm" 59 elif [ $BUILD_ARCH == "x86" ]; then 60 export TOOLCHAIN_HOST="i686-linux-android" 61 export TOOLCHAIN_COMP="i686-linux-android${MIN_SDK_VERSION}" 62 export TOOLCHAIN_ABI="x86" 63 export TOOLCHAIN_ARCH="x86" 64 elif [ $BUILD_ARCH == "arm64" ]; then 65 export TOOLCHAIN_HOST="aarch64-linux-android" 66 export TOOLCHAIN_COMP="aarch64-linux-android${MIN_SDK_VERSION}" 67 export TOOLCHAIN_ABI="arm64-v8a" 68 export TOOLCHAIN_ARCH="arm64" 69 elif [ $BUILD_ARCH == "x86_64" ]; then 70 export TOOLCHAIN_HOST="x86_64-linux-android" 71 export TOOLCHAIN_COMP="x86_64-linux-android${MIN_SDK_VERSION}" 72 export TOOLCHAIN_ABI="x86_64" 73 export TOOLCHAIN_ARCH="x86_64" 74 fi 75 76 export ANDROID_BUILD_SYSROOT="${ANDROID_NDK_ROOT}/platforms/android-${MIN_SDK_VERSION}/arch-${TOOLCHAIN_ARCH}" 77 export ANDROID_BUILD_PREFIX="${ANDROID_BUILD_DIR}/prefix/${TOOLCHAIN_ARCH}" 78} 79 80function android_build_env { 81 ## 82 # Check that necessary environment variables are set 83 84 if [ -z "$ANDROID_NDK_ROOT" ]; then 85 ANDROID_BUILD_FAIL+=("Please set the ANDROID_NDK_ROOT environment variable") 86 ANDROID_BUILD_FAIL+=(" (eg. \"/home/user/android/android-ndk-r21\")") 87 fi 88 89 if [ -z "$TOOLCHAIN_PATH" ]; then 90 ANDROID_BUILD_FAIL+=("Please set the TOOLCHAIN_PATH environment variable") 91 ANDROID_BUILD_FAIL+=(" (eg. \"/home/user/android/android-ndk-r21/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin\")") 92 fi 93 94 if [ -z "$TOOLCHAIN_HOST" ]; then 95 ANDROID_BUILD_FAIL+=("Please set the TOOLCHAIN_HOST environment variable") 96 ANDROID_BUILD_FAIL+=(" (eg. \"arm-linux-androideabi\")") 97 fi 98 99 if [ -z "$TOOLCHAIN_COMP" ]; then 100 ANDROID_BUILD_FAIL+=("Please set the TOOLCHAIN_COMP environment variable") 101 ANDROID_BUILD_FAIL+=(" (eg. \"armv7a-linux-androideabi\")") 102 fi 103 104 if [ -z "$TOOLCHAIN_ABI" ]; then 105 ANDROID_BUILD_FAIL+=("Please set the TOOLCHAIN_ABI environment variable") 106 ANDROID_BUILD_FAIL+=(" (eg. \"armeabi-v7a\")") 107 fi 108 109 if [ -z "$TOOLCHAIN_ARCH" ]; then 110 ANDROID_BUILD_FAIL+=("Please set the TOOLCHAIN_ARCH environment variable") 111 ANDROID_BUILD_FAIL+=(" (eg. \"arm\")") 112 fi 113 114 android_build_check_fail 115 116 ## 117 # Check that directories given by environment variables exist 118 119 if [ ! -d "$ANDROID_NDK_ROOT" ]; then 120 ANDROID_BUILD_FAIL+=("The ANDROID_NDK_ROOT directory does not exist") 121 ANDROID_BUILD_FAIL+=(" ${ANDROID_NDK_ROOT}") 122 fi 123 124 if [ ! -d "$TOOLCHAIN_PATH" ]; then 125 ANDROID_BUILD_FAIL+=("The TOOLCHAIN_PATH directory does not exist") 126 ANDROID_BUILD_FAIL+=(" ${TOOLCHAIN_PATH}") 127 fi 128 129 ## 130 # Set up some local variables and check them 131 132 if [ ! -d "$ANDROID_BUILD_SYSROOT" ]; then 133 ANDROID_BUILD_FAIL+=("The ANDROID_BUILD_SYSROOT directory does not exist") 134 ANDROID_BUILD_FAIL+=(" ${ANDROID_BUILD_SYSROOT}") 135 fi 136 137 mkdir -p "$ANDROID_BUILD_PREFIX" || { 138 ANDROID_BUILD_FAIL+=("Failed to make ANDROID_BUILD_PREFIX directory") 139 ANDROID_BUILD_FAIL+=(" ${ANDROID_BUILD_PREFIX}") 140 } 141 142 android_build_check_fail 143} 144 145function _android_build_opts_process_binaries { 146 local TOOLCHAIN="${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_PLATFORM}" 147 local CC="${TOOLCHAIN_PATH}/${TOOLCHAIN_COMP}-clang" 148 local CXX="${TOOLCHAIN_PATH}/${TOOLCHAIN_COMP}-clang++" 149 local LD="${TOOLCHAIN_PATH}/${TOOLCHAIN_HOST}-ld" 150 local AS="${TOOLCHAIN_PATH}/${TOOLCHAIN_HOST}-as" 151 local AR="${TOOLCHAIN_PATH}/${TOOLCHAIN_HOST}-ar" 152 local RANLIB="${TOOLCHAIN_PATH}/${TOOLCHAIN_HOST}-ranlib" 153 local STRIP="${TOOLCHAIN_PATH}/${TOOLCHAIN_HOST}-strip" 154 155 if [ ! -x "${CC}" ]; then 156 ANDROID_BUILD_FAIL+=("The CC binary does not exist or is not executable") 157 ANDROID_BUILD_FAIL+=(" ${CC}") 158 fi 159 160 if [ ! -x "${CXX}" ]; then 161 ANDROID_BUILD_FAIL+=("The CXX binary does not exist or is not executable") 162 ANDROID_BUILD_FAIL+=(" ${CXX}") 163 fi 164 165 if [ ! -x "${LD}" ]; then 166 ANDROID_BUILD_FAIL+=("The LD binary does not exist or is not executable") 167 ANDROID_BUILD_FAIL+=(" ${LD}") 168 fi 169 170 if [ ! -x "${AS}" ]; then 171 ANDROID_BUILD_FAIL+=("The AS binary does not exist or is not executable") 172 ANDROID_BUILD_FAIL+=(" ${AS}") 173 fi 174 175 if [ ! -x "${AR}" ]; then 176 ANDROID_BUILD_FAIL+=("The AR binary does not exist or is not executable") 177 ANDROID_BUILD_FAIL+=(" ${AR}") 178 fi 179 180 if [ ! -x "${RANLIB}" ]; then 181 ANDROID_BUILD_FAIL+=("The RANLIB binary does not exist or is not executable") 182 ANDROID_BUILD_FAIL+=(" ${RANLIB}") 183 fi 184 185 if [ ! -x "${STRIP}" ]; then 186 ANDROID_BUILD_FAIL+=("The STRIP binary does not exist or is not executable") 187 ANDROID_BUILD_FAIL+=(" ${STRIP}") 188 fi 189 190 ANDROID_BUILD_OPTS+=("TOOLCHAIN=${TOOLCHAIN}") 191 ANDROID_BUILD_OPTS+=("CC=${CC}") 192 ANDROID_BUILD_OPTS+=("CXX=${CXX}") 193 ANDROID_BUILD_OPTS+=("LD=${LD}") 194 ANDROID_BUILD_OPTS+=("AS=${AS}") 195 ANDROID_BUILD_OPTS+=("AR=${AR}") 196 ANDROID_BUILD_OPTS+=("RANLIB=${RANLIB}") 197 ANDROID_BUILD_OPTS+=("STRIP=${STRIP}") 198 199 android_build_check_fail 200} 201 202# Set the ANDROID_BUILD_OPTS variable to a bash array of configure options 203function android_build_opts { 204 ANDROID_BUILD_OPTS=() 205 206 _android_build_opts_process_binaries 207 208 local LIBS="-lc -lgcc -ldl -lm -llog -lc++_shared" 209 local LDFLAGS="-L${ANDROID_BUILD_PREFIX}/lib" 210 LDFLAGS+=" -L${ANDROID_NDK_ROOT}/sources/cxx-stl/llvm-libc++/libs/${TOOLCHAIN_ABI}" 211 CFLAGS+=" -D_GNU_SOURCE -D_REENTRANT -D_THREAD_SAFE" 212 CPPFLAGS+=" -I${ANDROID_BUILD_PREFIX}/include" 213 214 ANDROID_BUILD_OPTS+=("CFLAGS=${CFLAGS} ${ANDROID_BUILD_EXTRA_CFLAGS}") 215 ANDROID_BUILD_OPTS+=("CPPFLAGS=${CPPFLAGS} ${ANDROID_BUILD_EXTRA_CPPFLAGS}") 216 ANDROID_BUILD_OPTS+=("CXXFLAGS=${CXXFLAGS} ${ANDROID_BUILD_EXTRA_CXXFLAGS}") 217 ANDROID_BUILD_OPTS+=("LDFLAGS=${LDFLAGS} ${ANDROID_BUILD_EXTRA_LDFLAGS}") 218 ANDROID_BUILD_OPTS+=("LIBS=${LIBS} ${ANDROID_BUILD_EXTRA_LIBS}") 219 220 ANDROID_BUILD_OPTS+=("PKG_CONFIG_LIBDIR=${ANDROID_NDK_ROOT}/prebuilt/${HOST_PLATFORM}/lib/pkgconfig") 221 ANDROID_BUILD_OPTS+=("PKG_CONFIG_PATH=${ANDROID_BUILD_PREFIX}/lib/pkgconfig") 222 ANDROID_BUILD_OPTS+=("PKG_CONFIG_SYSROOT_DIR=${ANDROID_BUILD_SYSROOT}") 223 ANDROID_BUILD_OPTS+=("PKG_CONFIG_DIR=") 224 ANDROID_BUILD_OPTS+=("--with-sysroot=${ANDROID_BUILD_SYSROOT}") 225 ANDROID_BUILD_OPTS+=("--host=${TOOLCHAIN_HOST}") 226 ANDROID_BUILD_OPTS+=("--prefix=${ANDROID_BUILD_PREFIX}") 227 228 android_build_check_fail 229} 230 231# Parse readelf output to verify the correct linking of libraries. 232# The first argument should be the soname of the newly built library. 233# The rest of the arguments should be the sonames of dependencies. 234# All sonames should be unversioned for android (no trailing numbers). 235function android_build_verify_so { 236 local soname="$1" 237 shift # Get rid of first argument - the rest represent dependencies 238 239 local sofile="${ANDROID_BUILD_PREFIX}/lib/${soname}" 240 if [ ! -f "${sofile}" ]; then 241 ANDROID_BUILD_FAIL+=("Found no library named ${soname}") 242 ANDROID_BUILD_FAIL+=(" ${sofile}") 243 fi 244 android_build_check_fail 245 246 local READELF="${TOOLCHAIN_PATH}/${TOOLCHAIN_HOST}-readelf" 247 if command -v ${READELF} >/dev/null 2>&1 ; then 248 local readelf_bin="${READELF}" 249 elif command -v readelf >/dev/null 2>&1 ; then 250 local readelf_bin="readelf" 251 elif command -v greadelf >/dev/null 2>&1 ; then 252 local readelf_bin="greadelf" 253 else 254 ANDROID_BUILD_FAIL+=("Could not find any of readelf, greadelf, or ${READELF}") 255 fi 256 android_build_check_fail 257 258 local elfoutput=$(LC_ALL=C $readelf_bin -d ${sofile}) 259 260 local soname_regexp='soname: \[([[:alnum:]\.]+)\]' 261 if [[ $elfoutput =~ $soname_regexp ]]; then 262 local parsed_soname="${BASH_REMATCH[1]}" 263 if [ "${parsed_soname}" != "${soname}" ]; then 264 ANDROID_BUILD_FAIL+=("Actual soname of library ${soname} is incorrect (or versioned):") 265 ANDROID_BUILD_FAIL+=(" ${parsed_soname}") 266 fi 267 else 268 ANDROID_BUILD_FAIL+=("Failed to meaningfully parse readelf output for library ${soname}:") 269 ANDROID_BUILD_FAIL+=(" ${elfoutput}") 270 fi 271 272 for dep_soname do 273 if [[ $elfoutput != *"library: [${dep_soname}]"* ]]; then 274 ANDROID_BUILD_FAIL+=("Library ${soname} was expected to be linked to library with soname:") 275 ANDROID_BUILD_FAIL+=(" ${dep_soname}") 276 fi 277 done 278 279 android_build_check_fail 280} 281 282################################################################################ 283# THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY # 284# Read the zproject/README.md for information about making permanent changes. # 285################################################################################ 286