1#!/bin/bash 2# 3# Copyright © 2022 Arm Ltd and Contributors. All rights reserved. 4# SPDX-License-Identifier: MIT 5# 6 7# Script which downloads and builds Arm NN dependencies 8# Perquisite to running build-armnn.sh 9 10set -o nounset # Catch references to undefined variables. 11set -o pipefail # Catch non zero exit codes within pipelines. 12set -o errexit # Catch and propagate non zero exit codes. 13 14rel_path=$(dirname "$0") # relative path from where script is executed to script location 15 16# Download an archive using wget and extract using tar 17# Takes three arguments: 18# 1. Name of dependency being downloaded e.g. Flatbuffers 19# 2. Link to archive 20# 3. Filename given to archive upon downloading 21download_and_extract() 22{ 23 cd "$SOURCE_DIR" 24 25 echo -e "\n***** Downloading $1 *****\n" 26 wget -O "$3" "$2" 27 28 echo -e "\n***** Extracting archive *****" 29 tar -xzf "$3" 30 31 echo -e "\n***** Removing archive *****" 32 rm "$3" 33 34 echo -e "\n***** $1 downloaded *****" 35} 36 37download_protobuf() 38{ 39 download_and_extract \ 40 "Protobuf" \ 41 "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz" \ 42 "protobuf-all-$PROTOBUF_VERSION.tar.gz" 43} 44 45build_protobuf() 46{ 47 local native_build=$1 48 local build_dir="$PROTOBUF_BUILD_TARGET" 49 local cmake_flags="" 50 local target_arch="$TARGET_ARCH" 51 local additional_cmds="" 52 53 if [ "$native_build" -eq 0 ]; then 54 mkdir -p "$PROTOBUF_BUILD_TARGET" 55 additional_cmds+="--with-protoc=$PROTOCOL_COMPILER_HOST " 56 if [ "$TARGET_ARCH" == "aarch64" ]; then 57 cmake_flags+="$AARCH64_COMPILER_FLAGS" 58 additional_cmds+="--host=aarch64-linux " 59 fi 60 else 61 target_arch="$HOST_ARCH" 62 mkdir -p "$PROTOBUF_BUILD_HOST" 63 build_dir="$PROTOBUF_BUILD_HOST" 64 fi 65 66 echo -e "\n***** Building Protobuf for $target_arch ***** " 67 68 cd "$PROTOBUF_BUILD_ROOT" 69 70 # Cleanup any previous cmake files, except actual builds which we keep 71 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} + 72 73 eval "$cmake_flags" \ 74 "$PROTOBUF_SRC"/configure --prefix="$build_dir" "$additional_cmds" 75 make install -j "$NUM_THREADS" 76 77 echo -e "\n***** Protobuf built for $target_arch ***** " 78} 79 80download_flatbuffers() 81{ 82 download_and_extract \ 83 "Flatbuffers" \ 84 "https://github.com/google/flatbuffers/archive/v$FLATBUFFERS_VERSION.tar.gz" \ 85 "flatbuffers-$FLATBUFFERS_VERSION.tar.gz" 86} 87 88build_flatbuffers() 89{ 90 local native_build=$1 91 local build_dir="$FLATBUFFERS_BUILD_TARGET" 92 local target_arch="$TARGET_ARCH" 93 94 local cmake_flags="CXXFLAGS=-fPIC " 95 96 if [ "$native_build" -eq 0 ]; then 97 mkdir -p "$FLATBUFFERS_BUILD_TARGET" 98 if [ "$TARGET_ARCH" == "aarch64" ]; then 99 cmake_flags+="$AARCH64_COMPILER_FLAGS" 100 fi 101 else 102 target_arch="$HOST_ARCH" 103 mkdir -p "$FLATBUFFERS_BUILD_HOST" 104 build_dir="$FLATBUFFERS_BUILD_HOST" 105 fi 106 107 echo -e "\n***** Building flatbuffers for $target_arch *****" 108 109 mkdir -p "$FLATBUFFERS_BUILD_ROOT" 110 cd "$FLATBUFFERS_BUILD_ROOT" 111 112 # Cleanup any previous cmake files, except actual builds which we keep 113 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} + 114 115 eval "$cmake_flags" \ 116 cmake -DFLATBUFFERS_BUILD_FLATC="$native_build" \ 117 -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \ 118 -DFLATBUFFERS_BUILD_TESTS=0 \ 119 "$FLATBUFFERS_SRC" 120 make all install -j "$NUM_THREADS" 121 122 echo -e "\n***** Built flatbuffers for $target_arch *****" 123} 124 125download_tensorflow() 126{ 127 cd "$SOURCE_DIR" 128 129 echo -e "\n***** Downloading TensorFlow *****" 130 git clone https://github.com/tensorflow/tensorflow.git 131 cd "$TENSORFLOW_SRC" 132 133 git checkout "$TENSORFLOW_VERSION" 134 echo -e "\n***** TensorFlow downloaded *****" 135} 136 137build_tflite() 138{ 139 mkdir -p "$TFLITE_BUILD_TARGET" 140 cd "$TFLITE_BUILD_TARGET" 141 142 local target_arch_cmd="" # default is native, no command needed 143 local cmake_flags="" 144 145 case "$TARGET_ARCH" in 146 "aarch64") 147 cmake_flags+="$AARCH64_COMPILER_FLAGS" 148 target_arch_cmd="-DCMAKE_SYSTEM_PROCESSOR=aarch64 \ 149 -DCMAKE_SYSTEM_NAME=Linux " 150 151 if [ "$NATIVE_BUILD" -eq 0 ]; then 152 cmake_flags+="ARMCC_FLAGS='-funsafe-math-optimizations' " 153 fi 154 ;; 155 esac 156 157 echo -e "\n***** Building TF Lite for $TARGET_ARCH *****" 158 159 # Cleanup any previous cmake files, except actual builds which we keep 160 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} + 161 162 eval "$cmake_flags" \ 163 cmake -DTFLITE_ENABLE_XNNPACK=OFF \ 164 -DFLATBUFFERS_BUILD_FLATC=OFF \ 165 -DBUILD_SHARED_LIBS=OFF \ 166 -DBUILD_TESTING=OFF \ 167 "$target_arch_cmd" \ 168 "$TFLITE_SRC" 169 cmake --build . -j "$NUM_THREADS" 170 171 echo -e "\n***** Built TF Lite for $TARGET_ARCH *****" 172} 173 174generate_tflite_schema() 175{ 176 echo -e "\n***** Generating TF Lite Schema *****" 177 mkdir -p "$TFLITE_BUILD_ROOT" 178 cd "$TFLITE_BUILD_ROOT" 179 180 cp "$SCHEMA_SRC" . 181 182 $FLATC -c --gen-object-api --reflect-types --reflect-names schema.fbs 183 184 echo -e "\n***** Generated TF Lite Schema *****" 185} 186 187download_onnx() 188{ 189 download_and_extract \ 190 "ONNX" \ 191 "https://github.com/onnx/onnx/releases/download/v$ONNX_VERSION/onnx-$ONNX_VERSION.tar.gz" \ 192 "onnx-$ONNX_VERSION.tar.gz" 193} 194 195generate_onnx_sources() 196{ 197 mkdir -p "$ONNX_BUILD_TARGET" 198 cd "$ONNX_SRC" 199 200 echo -e "\n***** Generating ONNX sources for $TARGET_ARCH *****" 201 202 export LD_LIBRARY_PATH="$PROTOBUF_BUILD_HOST"/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} 203 204 eval "$PROTOCOL_COMPILER_HOST" onnx/onnx.proto \ 205 --proto_path=. \ 206 --proto_path="$ONNX_SRC" \ 207 --proto_path="$PROTOBUF_BUILD_HOST"/include \ 208 --cpp_out "$ONNX_BUILD_TARGET" 209 210 echo -e "\n***** Generated ONNX sources for $TARGET_ARCH *****" 211} 212 213usage() 214{ 215 cat <<EOF 216setup-armnn.sh - Download and build Arm NN dependencies in the current directory (ROOT_DIR) 217setup-armnn.sh [OPTION]... 218 --tflite-delegate 219 setup dependencies for the Arm NN TF Lite Delegate 220 --tflite-parser 221 setup dependencies for the Arm NN TF Lite Parser 222 --onnx-parser 223 setup dependencies for the Arm NN ONNX parser 224 --all 225 setup dependencies for all Arm NN components listed above 226 --target-arch=[aarch64|x86_64] 227 specify a target architecture (mandatory) 228 --num-threads=<INTEGER> 229 specify number of threads/cores to build dependencies with (optional: defaults to number of online CPU cores on host) 230 -h, --help 231 print brief usage information and exit 232 -x 233 enable shell tracing in this script 234 235At least one dependency flag (e.g. --tflite-delegate) must be provided or else provide --all to setup all dependencies. 236Directories called "source" and "build" will be generated in the current directory (ROOT_DIR) from which this script is called. 237It's recommended to call this script in a directory outside of this Arm NN source repo, to avoid nested repositories. 238 239Examples: 240Setup for aarch64 with all Arm NN dependencies: 241 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --all 242Setup for aarch64 with TF Lite Delegate and TF Lite Parser dependencies only: 243 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --tflite-delegate --tflite-parser 244EOF 245} 246 247# This will catch in validation.sh if not set 248target_arch="" 249 250# Default flag values 251flag_tflite_delegate=0 252flag_tflite_parser=0 253flag_onnx_parser=0 254 255# If --num-threads is not set, the default NUM_THREADS value in common.sh will be used 256num_threads=0 257 258name=$(basename "$0") 259 260# If no options provided, show help 261if [ $# -eq 0 ]; then 262 usage 263 exit 1 264fi 265 266args=$(getopt -ohx -l tflite-delegate,tflite-parser,onnx-parser,all,target-arch:,num-threads:,help -n "$name" -- "$@") 267eval set -- "$args" 268while [ $# -gt 0 ]; do 269 if [ -n "${opt_prev:-}" ]; then 270 eval "$opt_prev=\$1" 271 opt_prev= 272 shift 1 273 continue 274 elif [ -n "${opt_append:-}" ]; then 275 if [ -n "$1" ]; then 276 eval "$opt_append=\"\${$opt_append:-} \$1\"" 277 fi 278 opt_append= 279 shift 1 280 continue 281 fi 282 case $1 in 283 --tflite-parser) 284 flag_tflite_parser=1 285 ;; 286 287 --tflite-delegate) 288 flag_tflite_delegate=1 289 ;; 290 291 --onnx-parser) 292 flag_onnx_parser=1 293 ;; 294 295 --all) 296 flag_tflite_delegate=1 297 flag_tflite_parser=1 298 flag_onnx_parser=1 299 ;; 300 301 --target-arch) 302 opt_prev=target_arch 303 ;; 304 305 --num-threads) 306 opt_prev=num_threads 307 ;; 308 309 -h | --help) 310 usage 311 exit 0 312 ;; 313 314 -x) 315 set -x 316 ;; 317 318 --) 319 shift 320 break 2 321 ;; 322 323 esac 324 shift 1 325done 326 327# shellcheck source=common.sh 328source "$rel_path"/common.sh 329 330echo -e "\nINFO: Displaying configuration information before execution of $name" 331echo " target-arch: $TARGET_ARCH" 332echo " host-arch: $HOST_ARCH" 333echo " tflite-delegate: $flag_tflite_delegate" 334echo " tflite-parser: $flag_tflite_parser" 335echo " onnx-parser: $flag_onnx_parser" 336echo " num-threads: $NUM_THREADS" 337echo " root directory: $ROOT_DIR" 338echo "source directory: $SOURCE_DIR" 339echo " build directory: $BUILD_DIR" 340 341if check_if_repository .; then 342 echo -e "\n***** WARNING: Running script inside a git repository. To avoid nested repos, call this script from outside of this repo. *****" 343fi 344 345echo -e "\nScript execution will begin in 10 seconds..." 346 347sleep 10 348 349mkdir -p "$SOURCE_DIR" 350mkdir -p "$BUILD_DIR" 351 352if [ "$flag_tflite_delegate" -eq 1 ] || [ "$flag_tflite_parser" -eq 1 ]; then 353 download_flatbuffers 354 355 # Host build 356 build_flatbuffers 1 357 358 # Target build for cross compile 359 if [ "$NATIVE_BUILD" -eq 0 ]; then 360 build_flatbuffers 0 361 fi 362 363 download_tensorflow 364fi 365 366if [ "$flag_tflite_parser" -eq 1 ]; then 367 generate_tflite_schema 368fi 369 370if [ "$flag_tflite_delegate" -eq 1 ]; then 371 build_tflite 372fi 373 374if [ "$flag_onnx_parser" -eq 1 ]; then 375 download_protobuf 376 377 # Host build 378 build_protobuf 1 379 380 # Target build for cross compile 381 if [ "$NATIVE_BUILD" -eq 0 ]; then 382 build_protobuf 0 383 fi 384 385 download_onnx 386 generate_onnx_sources 387fi 388 389echo -e "\n***** Arm NN setup complete. Now build with build-armnn.sh. *****\n" 390 391exit 0