1#!/bin/bash -x
2# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15# ==============================================================================
16# Builds the TensorFlow core library with ARM and x86 architectures for iOS, and
17# packs them into a fat file.
18SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19source "${SCRIPT_DIR}/build_helper.subr"
20JOB_COUNT="${JOB_COUNT:-$(get_job_count)}"
21
22function less_than_required_version() {
23  echo $1 | (IFS=. read -r major minor micro
24    if [ $major -ne $2 ]; then
25      [ $major -lt $2 ]
26    elif [ $minor -ne $3 ]; then
27      [ $minor -lt $3 ]
28    else
29      [ ${micro:-0} -lt $4 ]
30    fi
31  )
32}
33
34if [[ -n MACOSX_DEPLOYMENT_TARGET ]]; then
35    export MACOSX_DEPLOYMENT_TARGET=$(sw_vers -productVersion)
36fi
37
38ACTUAL_XCODE_VERSION=$(xcodebuild -version | head -n 1 | sed 's/Xcode //')
39REQUIRED_XCODE_VERSION=7.3.0
40if less_than_required_version $ACTUAL_XCODE_VERSION 7 3 0
41then
42    echo "error: Xcode ${REQUIRED_XCODE_VERSION} or later is required."
43    exit 1
44fi
45
46usage() {
47  echo "Usage: $(basename "$0") [-a]"
48  echo "-a [build_arch] build for specified arch comma separate for multiple archs (eg: x86_64,arm64)"
49  echo "default is [i386, x86_64, armv7, armv7s, arm64]"
50  exit 1
51}
52
53BUILD_TARGET="i386 x86_64 armv7 armv7s arm64"
54while getopts "a:f:h:n:" opt_name; do
55  case "$opt_name" in
56    a) BUILD_TARGET="${OPTARG}";;
57    f) BUILD_OPT="${OPTARG}";;
58    h) NSYNC_HOST="${OPTARG}";;
59    n) NSYNC_TARGET="${OPTARG}";;
60    *) usage;;
61  esac
62done
63shift $((OPTIND - 1))
64
65IFS=' ' read -r -a build_targets <<< "${BUILD_TARGET}"
66
67SCRIPT_DIR=$(cd `dirname $0` && pwd)
68source "${SCRIPT_DIR}/build_helper.subr"
69
70
71GENDIR=tensorflow/contrib/makefile/gen/
72LIBDIR=${GENDIR}lib
73LIB_PREFIX=libtensorflow-core
74
75#remove any old artifacts
76rm -rf ${LIBDIR}/${LIB_PREFIX}.a
77
78package_tf_library() {
79    CAP_DIR=`echo $1 | tr 'a-z' 'A-Z'`
80    tf_libs="${LIBDIR}/ios_${CAP_DIR}/${LIB_PREFIX}-${1}.a"
81    if [ -f "${LIBDIR}/${LIB_PREFIX}.a" ]; then
82        tf_libs="$tf_libs ${LIBDIR}/${LIB_PREFIX}.a"
83    fi
84    lipo \
85    $tf_libs \
86    -create \
87    -output ${LIBDIR}/${LIB_PREFIX}.a
88}
89
90build_tf_target() {
91case "$1" in
92    armv7)
93        make -j"${JOB_COUNT}" -f tensorflow/contrib/makefile/Makefile \
94        TARGET=IOS IOS_ARCH=ARMV7 LIB_NAME=${LIB_PREFIX}-armv7.a \
95        OPTFLAGS="${BUILD_OPT}" HOST_NSYNC_LIB="${NSYNC_HOST}" \
96        TARGET_NSYNC_LIB="${NSYNC_TARGET}"
97        if [ $? -ne 0 ]
98        then
99          echo "armv7 compilation failed."
100          exit 1
101        fi
102        package_tf_library "armv7"
103        ;;
104    armv7s)
105        make -j"${JOB_COUNT}" -f tensorflow/contrib/makefile/Makefile \
106        TARGET=IOS IOS_ARCH=ARMV7S LIB_NAME=${LIB_PREFIX}-armv7s.a \
107        OPTFLAGS="${BUILD_OPT}" HOST_NSYNC_LIB="${NSYNC_HOST}" \
108        TARGET_NSYNC_LIB="${NSYNC_TARGET}"
109
110        if [ $? -ne 0 ]
111        then
112          echo "arm7vs compilation failed."
113          exit 1
114        fi
115        package_tf_library "armv7s"
116        ;;
117    arm64)
118        make -j"${JOB_COUNT}" -f tensorflow/contrib/makefile/Makefile \
119        TARGET=IOS IOS_ARCH=ARM64 LIB_NAME=${LIB_PREFIX}-arm64.a \
120        OPTFLAGS="${BUILD_OPT}" HOST_NSYNC_LIB="${NSYNC_HOST}" \
121        TARGET_NSYNC_LIB="${NSYNC_TARGET}"
122        if [ $? -ne 0 ]
123        then
124          echo "arm64 compilation failed."
125          exit 1
126        fi
127        package_tf_library "arm64"
128        ;;
129    i386)
130        make -j"${JOB_COUNT}" -f tensorflow/contrib/makefile/Makefile \
131        TARGET=IOS IOS_ARCH=I386 LIB_NAME=${LIB_PREFIX}-i386.a \
132        OPTFLAGS="${BUILD_OPT}" HOST_NSYNC_LIB="${NSYNC_HOST}" \
133        TARGET_NSYNC_LIB="${NSYNC_TARGET}"
134        if [ $? -ne 0 ]
135        then
136          echo "i386 compilation failed."
137          exit 1
138        fi
139        package_tf_library "i386"
140        ;;
141    x86_64)
142        make -j"${JOB_COUNT}" -f tensorflow/contrib/makefile/Makefile \
143        TARGET=IOS IOS_ARCH=X86_64 LIB_NAME=${LIB_PREFIX}-x86_64.a \
144        OPTFLAGS="${BUILD_OPT}" HOST_NSYNC_LIB="${NSYNC_HOST}" \
145        TARGET_NSYNC_LIB="${NSYNC_TARGET}"
146        if [ $? -ne 0 ]
147        then
148          echo "x86_64 compilation failed."
149          exit 1
150        fi
151        package_tf_library "x86_64"
152        ;;
153    *)
154        echo "Unknown ARCH"
155        exit 1
156esac
157}
158
159for build_tf_element in "${build_targets[@]}"
160do
161    echo "$build_tf_element"
162    build_tf_target "$build_tf_element"
163done
164
165echo "Done building and packaging TF"
166file ${LIBDIR}/${LIB_PREFIX}.a
167