1*d0eba39bSchristos#!/usr/bin/env bash 2*d0eba39bSchristos 3*d0eba39bSchristos# ==================================================================== 4*d0eba39bSchristos# Sets the cross compile environment for Xcode/iOS 5*d0eba39bSchristos# 6*d0eba39bSchristos# Based upon OpenSSL's setenv-ios.sh by TH, JW, and SM. 7*d0eba39bSchristos# Heavily modified by JWW for Crypto++. 8*d0eba39bSchristos# Modified by JWW for Unbound. 9*d0eba39bSchristos# ==================================================================== 10*d0eba39bSchristos 11*d0eba39bSchristos######################################### 12*d0eba39bSchristos##### Some validation ##### 13*d0eba39bSchristos######################################### 14*d0eba39bSchristos 15*d0eba39bSchristos# In the past we could mostly infer arch or cpu from the SDK (and 16*d0eba39bSchristos# mostly vice-versa). Nowadays we need it set for us because Apple 17*d0eba39bSchristos# platforms can be either 32-bit or 64-bit. 18*d0eba39bSchristos 19*d0eba39bSchristosif [ -z "$IOS_SDK" ]; then 20*d0eba39bSchristos echo "IOS_SDK is not set. Please set it" 21*d0eba39bSchristos [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 22*d0eba39bSchristosfi 23*d0eba39bSchristos 24*d0eba39bSchristosif [ -z "$IOS_CPU" ]; then 25*d0eba39bSchristos echo "IOS_CPU is not set. Please set it" 26*d0eba39bSchristos [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 27*d0eba39bSchristosfi 28*d0eba39bSchristos 29*d0eba39bSchristos# cryptest-ios.sh may run this script without sourcing. 30*d0eba39bSchristosif [ "$0" = "${BASH_SOURCE[0]}" ]; then 31*d0eba39bSchristos echo "setenv-ios.sh is usually sourced, but not this time." 32*d0eba39bSchristosfi 33*d0eba39bSchristos 34*d0eba39bSchristos######################################### 35*d0eba39bSchristos##### Small Fixups, if needed ##### 36*d0eba39bSchristos######################################### 37*d0eba39bSchristos 38*d0eba39bSchristosif [[ "$IOS_SDK" == "iPhone" ]]; then 39*d0eba39bSchristos IOS_SDK=iPhoneOS 40*d0eba39bSchristosfi 41*d0eba39bSchristos 42*d0eba39bSchristosif [[ "$IOS_SDK" == "iPhoneOSSimulator" ]]; then 43*d0eba39bSchristos IOS_SDK=iPhoneSimulator 44*d0eba39bSchristosfi 45*d0eba39bSchristos 46*d0eba39bSchristosif [[ "$IOS_SDK" == "TV" || "$IOS_SDK" == "AppleTV" ]]; then 47*d0eba39bSchristos IOS_SDK=AppleTVOS 48*d0eba39bSchristosfi 49*d0eba39bSchristos 50*d0eba39bSchristosif [[ "$IOS_SDK" == "Watch" || "$IOS_SDK" == "AppleWatch" ]]; then 51*d0eba39bSchristos IOS_SDK=WatchOS 52*d0eba39bSchristosfi 53*d0eba39bSchristos 54*d0eba39bSchristosif [[ "$IOS_CPU" == "aarch64" || "$IOS_CPU" == "armv8"* ]] ; then 55*d0eba39bSchristos IOS_CPU=arm64 56*d0eba39bSchristosfi 57*d0eba39bSchristos 58*d0eba39bSchristos######################################## 59*d0eba39bSchristos##### Environment ##### 60*d0eba39bSchristos######################################## 61*d0eba39bSchristos 62*d0eba39bSchristos# The flags below were tested with Xcode 8 on Travis. If 63*d0eba39bSchristos# you use downlevel versions of Xcode, then you can push 64*d0eba39bSchristos# xxx-version-min=n lower. For example, Xcode 6 can use 65*d0eba39bSchristos# -miphoneos-version-min=5. 66*d0eba39bSchristos 67*d0eba39bSchristos# iPhones can be either 32-bit or 64-bit 68*d0eba39bSchristosif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "armv7"* ]]; then 69*d0eba39bSchristos MIN_VER=-miphoneos-version-min=6 70*d0eba39bSchristoselif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "arm64" ]]; then 71*d0eba39bSchristos MIN_VER=-miphoneos-version-min=6 72*d0eba39bSchristos 73*d0eba39bSchristos# Fixups for convenience 74*d0eba39bSchristoselif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "i386" ]]; then 75*d0eba39bSchristos IOS_SDK=iPhoneSimulator 76*d0eba39bSchristos # MIN_VER=-miphoneos-version-min=6 77*d0eba39bSchristos MIN_VER=-miphonesimulator-version-min=6 78*d0eba39bSchristoselif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "x86_64" ]]; then 79*d0eba39bSchristos IOS_SDK=iPhoneSimulator 80*d0eba39bSchristos # MIN_VER=-miphoneos-version-min=6 81*d0eba39bSchristos MIN_VER=-miphonesimulator-version-min=6 82*d0eba39bSchristos 83*d0eba39bSchristos# Simulator builds 84*d0eba39bSchristoselif [[ "$IOS_SDK" == "iPhoneSimulator" && "$IOS_CPU" == "i386" ]]; then 85*d0eba39bSchristos MIN_VER=-miphonesimulator-version-min=6 86*d0eba39bSchristoselif [[ "$IOS_SDK" == "iPhoneSimulator" && "$IOS_CPU" == "x86_64" ]]; then 87*d0eba39bSchristos MIN_VER=-miphonesimulator-version-min=6 88*d0eba39bSchristos 89*d0eba39bSchristos# Apple TV can be 32-bit Intel (1st gen), 32-bit ARM (2nd, 3rd gen) or 64-bit ARM (4th gen) 90*d0eba39bSchristoselif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "i386" ]]; then 91*d0eba39bSchristos MIN_VER=-mappletvos-version-min=6 92*d0eba39bSchristoselif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "armv7"* ]]; then 93*d0eba39bSchristos MIN_VER=-mappletvos-version-min=6 94*d0eba39bSchristoselif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "arm64" ]]; then 95*d0eba39bSchristos MIN_VER=-mappletvos-version-min=6 96*d0eba39bSchristos 97*d0eba39bSchristos# Simulator builds 98*d0eba39bSchristoselif [[ "$IOS_SDK" == "AppleTVSimulator" && "$IOS_CPU" == "i386" ]]; then 99*d0eba39bSchristos MIN_VER=-mappletvsimulator-version-min=6 100*d0eba39bSchristoselif [[ "$IOS_SDK" == "AppleTVSimulator" && "$IOS_CPU" == "x86_64" ]]; then 101*d0eba39bSchristos MIN_VER=-mappletvsimulator-version-min=6 102*d0eba39bSchristos 103*d0eba39bSchristos# Watch can be either 32-bit or 64-bit ARM. TODO: figure out which 104*d0eba39bSchristos# -mwatchos-version-min=n is needed for arm64. 9 is not enough. 105*d0eba39bSchristoselif [[ "$IOS_SDK" == "WatchOS" && "$IOS_CPU" == "armv7"* ]]; then 106*d0eba39bSchristos MIN_VER=-mwatchos-version-min=6 107*d0eba39bSchristoselif [[ "$IOS_SDK" == "WatchOS" && "$IOS_CPU" == "arm64" ]]; then 108*d0eba39bSchristos MIN_VER=-mwatchos-version-min=10 109*d0eba39bSchristos 110*d0eba39bSchristos# Simulator builds. TODO: figure out which -watchos-version-min=n 111*d0eba39bSchristos# is needed for arm64. 6 compiles and links, but is it correct? 112*d0eba39bSchristoselif [[ "$IOS_SDK" == "WatchSimulator" && "$IOS_CPU" == "i386" ]]; then 113*d0eba39bSchristos MIN_VER=-mwatchsimulator-version-min=6 114*d0eba39bSchristoselif [[ "$IOS_SDK" == "WatchSimulator" && "$IOS_CPU" == "x86_64" ]]; then 115*d0eba39bSchristos MIN_VER=-mwatchsimulator-version-min=6 116*d0eba39bSchristos 117*d0eba39bSchristos# And the final catch-all 118*d0eba39bSchristoselse 119*d0eba39bSchristos echo "IOS_SDK and IOS_CPU are not valid. Please fix them" 120*d0eba39bSchristos [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 121*d0eba39bSchristosfi 122*d0eba39bSchristos 123*d0eba39bSchristos##################################################################### 124*d0eba39bSchristos 125*d0eba39bSchristos# Xcode 6 and below cannot handle -miphonesimulator-version-min 126*d0eba39bSchristos# Fix it so the simulator will compile as expected. This trick 127*d0eba39bSchristos# may work on other SDKs, but it was not tested. 128*d0eba39bSchristos 129*d0eba39bSchristosif [ -n "$(command -v xcodebuild 2>/dev/null)" ]; then 130*d0eba39bSchristos # Output of xcodebuild is similar to "Xcode 6.2". The first cut gets 131*d0eba39bSchristos # the dotted decimal value. The second cut gets the major version. 132*d0eba39bSchristos XCODE_VERSION=$(xcodebuild -version 2>/dev/null | head -n 1 | cut -f2 -d" " | cut -f1 -d".") 133*d0eba39bSchristos if [ -z "$XCODE_VERSION" ]; then XCODE_VERSION=100; fi 134*d0eba39bSchristos 135*d0eba39bSchristos if [ "$XCODE_VERSION" -le 6 ]; then 136*d0eba39bSchristos MIN_VER="${MIN_VER//iphonesimulator/iphoneos}" 137*d0eba39bSchristos fi 138*d0eba39bSchristosfi 139*d0eba39bSchristos 140*d0eba39bSchristos##################################################################### 141*d0eba39bSchristos 142*d0eba39bSchristos# Allow a user override? I think we should be doing this. The use case is, 143*d0eba39bSchristos# move /Applications/Xcode somewhere else for a side-by-side installation. 144*d0eba39bSchristosif [ -z "${XCODE_DEVELOPER-}" ]; then 145*d0eba39bSchristos XCODE_DEVELOPER=$(xcode-select -print-path 2>/dev/null) 146*d0eba39bSchristosfi 147*d0eba39bSchristos 148*d0eba39bSchristosif [ ! -d "$XCODE_DEVELOPER" ]; then 149*d0eba39bSchristos echo "ERROR: unable to find XCODE_DEVELOPER directory." 150*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 151*d0eba39bSchristosfi 152*d0eba39bSchristos 153*d0eba39bSchristos# XCODE_DEVELOPER_SDK is the SDK location. 154*d0eba39bSchristosXCODE_DEVELOPER_SDK="$XCODE_DEVELOPER/Platforms/$IOS_SDK.platform" 155*d0eba39bSchristos 156*d0eba39bSchristosif [ ! -d "$XCODE_DEVELOPER_SDK" ]; then 157*d0eba39bSchristos echo "ERROR: unable to find XCODE_DEVELOPER_SDK directory." 158*d0eba39bSchristos echo " Is the SDK supported by Xcode and installed?" 159*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 160*d0eba39bSchristosfi 161*d0eba39bSchristos 162*d0eba39bSchristos# XCODE_TOOLCHAIN is the location of the actual compiler tools. 163*d0eba39bSchristosif [ -d "$XCODE_DEVELOPER/Toolchains/XcodeDefault.xctoolchain/usr/bin/" ]; then 164*d0eba39bSchristos XCODE_TOOLCHAIN="$XCODE_DEVELOPER/Toolchains/XcodeDefault.xctoolchain/usr/bin/" 165*d0eba39bSchristoselif [ -d "$XCODE_DEVELOPER_SDK/Developer/usr/bin/" ]; then 166*d0eba39bSchristos XCODE_TOOLCHAIN="$XCODE_DEVELOPER_SDK/Developer/usr/bin/" 167*d0eba39bSchristosfi 168*d0eba39bSchristos 169*d0eba39bSchristosif [ -z "$XCODE_TOOLCHAIN" ] || [ ! -d "$XCODE_TOOLCHAIN" ]; then 170*d0eba39bSchristos echo "ERROR: unable to find Xcode cross-compiler tools." 171*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 172*d0eba39bSchristosfi 173*d0eba39bSchristos 174*d0eba39bSchristos# XCODE_SDK is the SDK name/version being used - adjust the list as appropriate. 175*d0eba39bSchristos# For example, remove 4.3, 6.2, and 6.1 if they are not installed. We go back to 176*d0eba39bSchristos# the 1.0 SDKs because Apple WatchOS uses low numbers, like 2.0 and 2.1. 177*d0eba39bSchristosXCODE_SDK= 178*d0eba39bSchristosfor i in $(seq -f "%.1f" 30.0 -0.1 1.0) 179*d0eba39bSchristosdo 180*d0eba39bSchristos if [ -d "$XCODE_DEVELOPER_SDK/Developer/SDKs/$IOS_SDK$i.sdk" ]; then 181*d0eba39bSchristos XCODE_SDK="$IOS_SDK$i.sdk" 182*d0eba39bSchristos break 183*d0eba39bSchristos fi 184*d0eba39bSchristosdone 185*d0eba39bSchristos 186*d0eba39bSchristos# Error checking 187*d0eba39bSchristosif [ -z "$XCODE_SDK" ]; then 188*d0eba39bSchristos echo "ERROR: unable to find a SDK." 189*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 190*d0eba39bSchristosfi 191*d0eba39bSchristos 192*d0eba39bSchristosIOS_SYSROOT="$XCODE_DEVELOPER_SDK/Developer/SDKs/$XCODE_SDK" 193*d0eba39bSchristos 194*d0eba39bSchristosif [ -z "$IOS_SYSROOT" ] || [ ! -d "$IOS_SYSROOT" ]; then 195*d0eba39bSchristos echo "ERROR: unable to find IOS_SYSROOT directory." 196*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 197*d0eba39bSchristosfi 198*d0eba39bSchristos 199*d0eba39bSchristos##################################################################### 200*d0eba39bSchristos 201*d0eba39bSchristos# We want to set AR=libtool and ARFLAGS="-static -o", 202*d0eba39bSchristos# but I am not sure Autotools can handle it. 203*d0eba39bSchristosCPP=cpp; CC=clang; CXX=clang++; LD=ld 204*d0eba39bSchristosAS=as; AR=ar; RANLIB=ranlib; STRIP=strip 205*d0eba39bSchristos 206*d0eba39bSchristos# Error checking 207*d0eba39bSchristosif [ ! -e "$XCODE_TOOLCHAIN/$CC" ]; then 208*d0eba39bSchristos echo "ERROR: Failed to find iOS clang. Please edit this script." 209*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 210*d0eba39bSchristosfi 211*d0eba39bSchristos 212*d0eba39bSchristos# Error checking 213*d0eba39bSchristosif [ ! -e "$XCODE_TOOLCHAIN/$CXX" ]; then 214*d0eba39bSchristos echo "ERROR: Failed to find iOS clang++. Please edit this script." 215*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 216*d0eba39bSchristosfi 217*d0eba39bSchristos 218*d0eba39bSchristos# Error checking 219*d0eba39bSchristosif [ ! -e "$XCODE_TOOLCHAIN/$RANLIB" ]; then 220*d0eba39bSchristos echo "ERROR: Failed to find iOS ranlib. Please edit this script." 221*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 222*d0eba39bSchristosfi 223*d0eba39bSchristos 224*d0eba39bSchristos# Error checking 225*d0eba39bSchristosif [ ! -e "$XCODE_TOOLCHAIN/$AR" ]; then 226*d0eba39bSchristos echo "ERROR: Failed to find iOS ar. Please edit this script." 227*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 228*d0eba39bSchristosfi 229*d0eba39bSchristos 230*d0eba39bSchristos# Error checking 231*d0eba39bSchristosif [ ! -e "$XCODE_TOOLCHAIN/$AS" ]; then 232*d0eba39bSchristos echo "ERROR: Failed to find iOS as. Please edit this script." 233*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 234*d0eba39bSchristosfi 235*d0eba39bSchristos 236*d0eba39bSchristos# Error checking 237*d0eba39bSchristosif [ ! -e "$XCODE_TOOLCHAIN/$LD" ]; then 238*d0eba39bSchristos echo "ERROR: Failed to find iOS ld. Please edit this script." 239*d0eba39bSchristos [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1 240*d0eba39bSchristosfi 241*d0eba39bSchristos 242*d0eba39bSchristos##################################################################### 243*d0eba39bSchristos 244*d0eba39bSchristosLENGTH=${#XCODE_TOOLCHAIN} 245*d0eba39bSchristosSUBSTR=${PATH:0:$LENGTH} 246*d0eba39bSchristosif [ "$SUBSTR" != "$XCODE_TOOLCHAIN" ]; then 247*d0eba39bSchristos export PATH="$XCODE_TOOLCHAIN":"$PATH" 248*d0eba39bSchristosfi 249*d0eba39bSchristos 250*d0eba39bSchristos##################################################################### 251*d0eba39bSchristos 252*d0eba39bSchristosexport CPP CC CXX LD AS AR RANLIB STRIP 253*d0eba39bSchristosexport IOS_SYSROOT 254*d0eba39bSchristosexport CFLAGS="-arch $IOS_CPU $MIN_VER --sysroot=$IOS_SYSROOT" 255*d0eba39bSchristosexport CXXFLAGS="-arch $IOS_CPU $MIN_VER -stdlib-libc++ --sysroot=$IOS_SYSROOT" 256*d0eba39bSchristos 257*d0eba39bSchristos##################################################################### 258*d0eba39bSchristos 259*d0eba39bSchristosecho "XCODE_TOOLCHAIN: $XCODE_TOOLCHAIN" 260*d0eba39bSchristos 261*d0eba39bSchristosecho "CPP: $(command -v "$CPP")" 262*d0eba39bSchristosecho "CC: $(command -v "$CC")" 263*d0eba39bSchristosecho "CXX: $(command -v "$CXX")" 264*d0eba39bSchristosecho "LD: $(command -v "$LD")" 265*d0eba39bSchristosecho "AS: $(command -v "$AS")" 266*d0eba39bSchristosecho "AR: $(command -v "$AR")" 267*d0eba39bSchristos 268*d0eba39bSchristosecho "IOS_SYSROOT: $IOS_SYSROOT" 269*d0eba39bSchristos 270*d0eba39bSchristosecho "CPPFLAGS: $CPPFLAGS" 271*d0eba39bSchristosecho "CFLAGS: $CFLAGS" 272*d0eba39bSchristosecho "CXXFLAGS: $CXXFLAGS" 273*d0eba39bSchristos 274*d0eba39bSchristos[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0 275