1#!/usr/bin/env bash 2# Copyright 2021 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# ============================================================================== 16set -ex 17 18SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 19PYTHON="${CI_BUILD_PYTHON:-python3}" 20VERSION_SUFFIX=${VERSION_SUFFIX:-} 21export TENSORFLOW_DIR="${SCRIPT_DIR}/../../../.." 22TENSORFLOW_LITE_DIR="${TENSORFLOW_DIR}/tensorflow/lite" 23TENSORFLOW_VERSION=$(grep "_VERSION = " "${TENSORFLOW_DIR}/tensorflow/tools/pip_package/setup.py" | cut -d= -f2 | sed "s/[ '-]//g") 24export PACKAGE_VERSION="${TENSORFLOW_VERSION}${VERSION_SUFFIX}" 25export PROJECT_NAME=${WHEEL_PROJECT_NAME:-tflite_runtime} 26BUILD_DIR="${SCRIPT_DIR}/gen/tflite_pip/${PYTHON}" 27TENSORFLOW_TARGET=${TENSORFLOW_TARGET:-$1} 28if [ "${TENSORFLOW_TARGET}" = "rpi" ]; then 29 export TENSORFLOW_TARGET="armhf" 30fi 31PYTHON_INCLUDE=$(${PYTHON} -c "from sysconfig import get_paths as gp; print(gp()['include'])") 32PYBIND11_INCLUDE=$(${PYTHON} -c "import pybind11; print (pybind11.get_include())") 33NUMPY_INCLUDE=$(${PYTHON} -c "import numpy; print (numpy.get_include())") 34export CROSSTOOL_PYTHON_INCLUDE_PATH=${PYTHON_INCLUDE} 35 36# Fix container image for cross build. 37if [ ! -z "${CI_BUILD_HOME}" ] && [ `pwd` = "/workspace" ]; then 38 # Fix for curl build problem in 32-bit, see https://stackoverflow.com/questions/35181744/size-of-array-curl-rule-01-is-negative 39 if [ "${TENSORFLOW_TARGET}" = "armhf" ] && [ -f /usr/include/curl/curlbuild.h ]; then 40 sudo sed -i 's/define CURL_SIZEOF_LONG 8/define CURL_SIZEOF_LONG 4/g' /usr/include/curl/curlbuild.h 41 sudo sed -i 's/define CURL_SIZEOF_CURL_OFF_T 8/define CURL_SIZEOF_CURL_OFF_T 4/g' /usr/include/curl/curlbuild.h 42 fi 43 44 # The system-installed OpenSSL headers get pulled in by the latest BoringSSL 45 # release on this configuration, so move them before we build: 46 if [ -d /usr/include/openssl ]; then 47 sudo mv /usr/include/openssl /usr/include/openssl.original 48 fi 49fi 50 51# Build source tree. 52rm -rf "${BUILD_DIR}" && mkdir -p "${BUILD_DIR}/tflite_runtime" 53cp -r "${TENSORFLOW_LITE_DIR}/tools/pip_package/debian" \ 54 "${TENSORFLOW_LITE_DIR}/tools/pip_package/MANIFEST.in" \ 55 "${TENSORFLOW_LITE_DIR}/python/interpreter_wrapper" \ 56 "${BUILD_DIR}" 57cp "${TENSORFLOW_LITE_DIR}/tools/pip_package/setup_with_binary.py" "${BUILD_DIR}/setup.py" 58cp "${TENSORFLOW_LITE_DIR}/python/interpreter.py" \ 59 "${TENSORFLOW_LITE_DIR}/python/metrics/metrics_interface.py" \ 60 "${TENSORFLOW_LITE_DIR}/python/metrics/metrics_portable.py" \ 61 "${BUILD_DIR}/tflite_runtime" 62echo "__version__ = '${PACKAGE_VERSION}'" >> "${BUILD_DIR}/tflite_runtime/__init__.py" 63echo "__git_version__ = '$(git -C "${TENSORFLOW_DIR}" describe)'" >> "${BUILD_DIR}/tflite_runtime/__init__.py" 64 65# Build python interpreter_wrapper. 66mkdir -p "${BUILD_DIR}/cmake_build" 67cd "${BUILD_DIR}/cmake_build" 68 69echo "Building for ${TENSORFLOW_TARGET}" 70case "${TENSORFLOW_TARGET}" in 71 armhf) 72 eval $(${TENSORFLOW_LITE_DIR}/tools/cmake/download_toolchains.sh "${TENSORFLOW_TARGET}") 73 ARMCC_FLAGS="${ARMCC_FLAGS} -I${PYBIND11_INCLUDE} -I${NUMPY_INCLUDE}" 74 cmake \ 75 -DCMAKE_C_COMPILER=${ARMCC_PREFIX}gcc \ 76 -DCMAKE_CXX_COMPILER=${ARMCC_PREFIX}g++ \ 77 -DCMAKE_C_FLAGS="${ARMCC_FLAGS}" \ 78 -DCMAKE_CXX_FLAGS="${ARMCC_FLAGS}" \ 79 -DCMAKE_SYSTEM_NAME=Linux \ 80 -DCMAKE_SYSTEM_PROCESSOR=armv7 \ 81 -DTFLITE_ENABLE_XNNPACK=OFF \ 82 "${TENSORFLOW_LITE_DIR}" 83 ;; 84 rpi0) 85 eval $(${TENSORFLOW_LITE_DIR}/tools/cmake/download_toolchains.sh "${TENSORFLOW_TARGET}") 86 ARMCC_FLAGS="${ARMCC_FLAGS} -I${PYBIND11_INCLUDE} -I${NUMPY_INCLUDE}" 87 cmake \ 88 -DCMAKE_C_COMPILER=${ARMCC_PREFIX}gcc \ 89 -DCMAKE_CXX_COMPILER=${ARMCC_PREFIX}g++ \ 90 -DCMAKE_C_FLAGS="${ARMCC_FLAGS}" \ 91 -DCMAKE_CXX_FLAGS="${ARMCC_FLAGS}" \ 92 -DCMAKE_SYSTEM_NAME=Linux \ 93 -DCMAKE_SYSTEM_PROCESSOR=armv6 \ 94 -DTFLITE_ENABLE_XNNPACK=OFF \ 95 "${TENSORFLOW_LITE_DIR}" 96 ;; 97 aarch64) 98 eval $(${TENSORFLOW_LITE_DIR}/tools/cmake/download_toolchains.sh "${TENSORFLOW_TARGET}") 99 ARMCC_FLAGS="${ARMCC_FLAGS} -I${PYBIND11_INCLUDE} -I${NUMPY_INCLUDE}" 100 cmake \ 101 -DCMAKE_C_COMPILER=${ARMCC_PREFIX}gcc \ 102 -DCMAKE_CXX_COMPILER=${ARMCC_PREFIX}g++ \ 103 -DCMAKE_C_FLAGS="${ARMCC_FLAGS}" \ 104 -DCMAKE_CXX_FLAGS="${ARMCC_FLAGS}" \ 105 -DCMAKE_SYSTEM_NAME=Linux \ 106 -DCMAKE_SYSTEM_PROCESSOR=aarch64 \ 107 "${TENSORFLOW_LITE_DIR}" 108 ;; 109 native) 110 BUILD_FLAGS=${BUILD_FLAGS:-"-march=native -I${PYTHON_INCLUDE} -I${PYBIND11_INCLUDE} -I${NUMPY_INCLUDE}"} 111 cmake \ 112 -DCMAKE_C_FLAGS="${BUILD_FLAGS}" \ 113 -DCMAKE_CXX_FLAGS="${BUILD_FLAGS}" \ 114 "${TENSORFLOW_LITE_DIR}" 115 ;; 116 *) 117 BUILD_FLAGS=${BUILD_FLAGS:-"-I${PYTHON_INCLUDE} -I${PYBIND11_INCLUDE} -I${NUMPY_INCLUDE}"} 118 cmake \ 119 -DCMAKE_C_FLAGS="${BUILD_FLAGS}" \ 120 -DCMAKE_CXX_FLAGS="${BUILD_FLAGS}" \ 121 "${TENSORFLOW_LITE_DIR}" 122 ;; 123esac 124 125cmake --build . --verbose -j ${BUILD_NUM_JOBS} -t _pywrap_tensorflow_interpreter_wrapper 126cd "${BUILD_DIR}" 127 128case "${TENSORFLOW_TARGET}" in 129 windows) 130 LIBRARY_EXTENSION=".pyd" 131 ;; 132 *) 133 LIBRARY_EXTENSION=".so" 134 ;; 135esac 136 137cp "${BUILD_DIR}/cmake_build/_pywrap_tensorflow_interpreter_wrapper${LIBRARY_EXTENSION}" \ 138 "${BUILD_DIR}/tflite_runtime" 139# Bazel generates the wrapper library with r-x permissions for user. 140# At least on Windows, we need write permissions to delete the file. 141# Without this, setuptools fails to clean the build directory. 142chmod u+w "${BUILD_DIR}/tflite_runtime/_pywrap_tensorflow_interpreter_wrapper${LIBRARY_EXTENSION}" 143 144# Build python wheel. 145cd "${BUILD_DIR}" 146case "${TENSORFLOW_TARGET}" in 147 armhf) 148 WHEEL_PLATFORM_NAME="${WHEEL_PLATFORM_NAME:-linux-armv7l}" 149 ${PYTHON} setup.py bdist --plat-name=${WHEEL_PLATFORM_NAME} \ 150 bdist_wheel --plat-name=${WHEEL_PLATFORM_NAME} 151 ;; 152 rpi0) 153 WHEEL_PLATFORM_NAME="${WHEEL_PLATFORM_NAME:-linux-armv6l}" 154 ${PYTHON} setup.py bdist --plat-name=${WHEEL_PLATFORM_NAME} \ 155 bdist_wheel --plat-name=${WHEEL_PLATFORM_NAME} 156 ;; 157 aarch64) 158 WHEEL_PLATFORM_NAME="${WHEEL_PLATFORM_NAME:-linux-aarch64}" 159 ${PYTHON} setup.py bdist --plat-name=${WHEEL_PLATFORM_NAME} \ 160 bdist_wheel --plat-name=${WHEEL_PLATFORM_NAME} 161 ;; 162 *) 163 if [[ -n "${WHEEL_PLATFORM_NAME}" ]]; then 164 ${PYTHON} setup.py bdist --plat-name=${WHEEL_PLATFORM_NAME} \ 165 bdist_wheel --plat-name=${WHEEL_PLATFORM_NAME} 166 else 167 ${PYTHON} setup.py bdist bdist_wheel 168 fi 169 ;; 170esac 171 172echo "Output can be found here:" 173find "${BUILD_DIR}/dist" 174 175# Build debian package. 176if [[ "${BUILD_DEB}" != "y" ]]; then 177 exit 0 178fi 179 180PYTHON_VERSION=$(${PYTHON} -c "import sys;print(sys.version_info.major)") 181if [[ ${PYTHON_VERSION} != 3 ]]; then 182 echo "Debian package can only be generated for python3." >&2 183 exit 1 184fi 185 186DEB_VERSION=$(dpkg-parsechangelog --show-field Version | cut -d- -f1) 187if [[ "${DEB_VERSION}" != "${PACKAGE_VERSION}" ]]; then 188 cat << EOF > "${BUILD_DIR}/debian/changelog" 189tflite-runtime (${PACKAGE_VERSION}-1) unstable; urgency=low 190 191 * Bump version to ${PACKAGE_VERSION}. 192 193 -- TensorFlow team <packages@tensorflow.org> $(date -R) 194 195$(<"${BUILD_DIR}/debian/changelog") 196EOF 197fi 198 199case "${TENSORFLOW_TARGET}" in 200 armhf) 201 dpkg-buildpackage -b -rfakeroot -us -uc -tc -d -a armhf 202 ;; 203 rpi0) 204 dpkg-buildpackage -b -rfakeroot -us -uc -tc -d -a armel 205 ;; 206 aarch64) 207 dpkg-buildpackage -b -rfakeroot -us -uc -tc -d -a arm64 208 ;; 209 *) 210 dpkg-buildpackage -b -rfakeroot -us -uc -tc -d 211 ;; 212esac 213 214cat "${BUILD_DIR}/debian/changelog" 215 216