blob: db2ef2a4ee6560ba15a2f1ab1fa6342077a9723c [file] [log] [blame]
James Conroy919ec712022-07-13 12:57:53 +01001#!/bin/bash
2#
John Mcloughlin35bae832023-07-24 11:55:13 +01003# Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
James Conroy919ec712022-07-13 12:57:53 +01004# 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
James Conroy210897d2022-08-04 16:55:05 +010025 echo -e "\n***** Downloading $1 *****\n"
James Conroy919ec712022-07-13 12:57:53 +010026 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
John Mcloughlin35bae832023-07-24 11:55:13 +010037download_androidndk()
38{
39 cd "$SOURCE_DIR"
40 echo -e "\n***** Downloading Android NDK *****\n"
41 wget https://dl.google.com/android/repository/android-ndk-r25-linux.zip
42 echo -e "\n***** Extracting archive *****"
43 unzip android-ndk-r25-linux.zip
44 echo -e "\n***** Removing archive *****"
45 rm android-ndk-r25-linux.zip
46 echo -e "\n***** Android NDK downloaded *****"
47}
48
James Conroy919ec712022-07-13 12:57:53 +010049download_protobuf()
50{
51 download_and_extract \
52 "Protobuf" \
53 "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz" \
54 "protobuf-all-$PROTOBUF_VERSION.tar.gz"
55}
56
57build_protobuf()
58{
59 local native_build=$1
60 local build_dir="$PROTOBUF_BUILD_TARGET"
61 local cmake_flags=""
62 local target_arch="$TARGET_ARCH"
63 local additional_cmds=""
64
65 if [ "$native_build" -eq 0 ]; then
66 mkdir -p "$PROTOBUF_BUILD_TARGET"
67 additional_cmds+="--with-protoc=$PROTOCOL_COMPILER_HOST "
68 if [ "$TARGET_ARCH" == "aarch64" ]; then
69 cmake_flags+="$AARCH64_COMPILER_FLAGS"
70 additional_cmds+="--host=aarch64-linux "
James Conroy919ec712022-07-13 12:57:53 +010071 fi
John Mcloughlin35bae832023-07-24 11:55:13 +010072 if [ "$TARGET_ARCH" == "android64" ]; then
73 additional_cmds+="--host=aarch64-linux-android "
74 cmake_flags+="$ANDROID64_COMPILER_FLAGS"
75 fi
James Conroy919ec712022-07-13 12:57:53 +010076 else
77 target_arch="$HOST_ARCH"
78 mkdir -p "$PROTOBUF_BUILD_HOST"
79 build_dir="$PROTOBUF_BUILD_HOST"
80 fi
81
82 echo -e "\n***** Building Protobuf for $target_arch ***** "
83
84 cd "$PROTOBUF_BUILD_ROOT"
85
86 # Cleanup any previous cmake files, except actual builds which we keep
87 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
88
John Mcloughlin35bae832023-07-24 11:55:13 +010089 if [ "$native_build" -eq 0 ] && [ "$TARGET_ARCH" == "android64" ]; then
90 eval "$cmake_flags"
91 cmake -DCMAKE_ANDROID_NDK="$NDK_SRC" \
92 -DCMAKE_SYSTEM_NAME=Android \
93 -DCMAKE_SYSTEM_VERSION="$ANDROID_API_VERSION" \
94 -DCMAKE_ANDROID_ARCH_ABI="$ANDROID_ARM_ARCH" \
95 -DCMAKE_CXX_FLAGS=--std=c++14 \
96 -Dprotobuf_BUILD_TESTS=OFF \
97 -Dprotobuf_BUILD_SHARED_LIBS=ON \
98 -Dprotobuf_WITH_ZLIB=OFF \
99 -DCMAKE_BUILD_TYPE=Release \
100 $PROTOBUF_SRC/cmake/
101 make libprotobuf -j "$NUM_THREADS"
102 cmake -DCMAKE_INSTALL_PREFIX=$PROTOBUF_BUILD_TARGET -DCOMPONENT=libprotobuf -P cmake_install.cmake
103 cmake -DCMAKE_INSTALL_PREFIX=$PROTOBUF_BUILD_TARGET -DCOMPONENT=protobuf-headers -P cmake_install.cmake
104 else
105 eval "$cmake_flags" \
106 "$PROTOBUF_SRC"/configure --prefix="$build_dir" "$additional_cmds"
107 make install -j "$NUM_THREADS"
108 fi
James Conroy919ec712022-07-13 12:57:53 +0100109
110 echo -e "\n***** Protobuf built for $target_arch ***** "
111}
112
113download_flatbuffers()
114{
115 download_and_extract \
116 "Flatbuffers" \
117 "https://github.com/google/flatbuffers/archive/v$FLATBUFFERS_VERSION.tar.gz" \
118 "flatbuffers-$FLATBUFFERS_VERSION.tar.gz"
119}
120
121build_flatbuffers()
122{
123 local native_build=$1
124 local build_dir="$FLATBUFFERS_BUILD_TARGET"
125 local target_arch="$TARGET_ARCH"
126
127 local cmake_flags="CXXFLAGS=-fPIC "
128
129 if [ "$native_build" -eq 0 ]; then
130 mkdir -p "$FLATBUFFERS_BUILD_TARGET"
John Mcloughlin35bae832023-07-24 11:55:13 +0100131 if [ "$TARGET_ARCH" == "aarch64" ] || [ "$TARGET_ARCH" == "android64" ]; then
James Conroy919ec712022-07-13 12:57:53 +0100132 cmake_flags+="$AARCH64_COMPILER_FLAGS"
James Conroy919ec712022-07-13 12:57:53 +0100133 fi
134 else
135 target_arch="$HOST_ARCH"
136 mkdir -p "$FLATBUFFERS_BUILD_HOST"
137 build_dir="$FLATBUFFERS_BUILD_HOST"
138 fi
139
140 echo -e "\n***** Building flatbuffers for $target_arch *****"
141
142 mkdir -p "$FLATBUFFERS_BUILD_ROOT"
143 cd "$FLATBUFFERS_BUILD_ROOT"
144
145 # Cleanup any previous cmake files, except actual builds which we keep
146 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
147
John Mcloughlin35bae832023-07-24 11:55:13 +0100148 if [ "$native_build" -eq 0 ] && [ "$TARGET_ARCH" == "android64" ]; then
149 eval "$cmake_flags" \
150 cmake -DCMAKE_ANDROID_NDK="$NDK_SRC" \
151 -DCMAKE_SYSTEM_NAME=Android \
152 -DCMAKE_SYSTEM_VERSION="$ANDROID_API_VERSION" \
153 -DCMAKE_ANDROID_ARCH_ABI="$ANDROID_ARM_ARCH" \
154 -DCMAKE_CXX_FLAGS=--std=c++14 \
155 -DFLATBUFFERS_BUILD_FLATC=0 \
156 -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \
157 -DCMAKE_BUILD_TYPE=Release \
158 -DFLATBUFFERS_BUILD_TESTS=0 \
159 "$FLATBUFFERS_SRC"
160 else
161 eval "$cmake_flags" \
162 cmake -DFLATBUFFERS_BUILD_FLATC="$native_build" \
163 -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \
164 -DFLATBUFFERS_BUILD_TESTS=0 \
165 "$FLATBUFFERS_SRC"
166 fi
James Conroy919ec712022-07-13 12:57:53 +0100167 make all install -j "$NUM_THREADS"
168
169 echo -e "\n***** Built flatbuffers for $target_arch *****"
170}
171
172download_tensorflow()
173{
174 cd "$SOURCE_DIR"
175
176 echo -e "\n***** Downloading TensorFlow *****"
177 git clone https://github.com/tensorflow/tensorflow.git
178 cd "$TENSORFLOW_SRC"
179
James Conroy210897d2022-08-04 16:55:05 +0100180 git checkout "$TENSORFLOW_VERSION"
James Conroy919ec712022-07-13 12:57:53 +0100181 echo -e "\n***** TensorFlow downloaded *****"
182}
183
184build_tflite()
185{
186 mkdir -p "$TFLITE_BUILD_TARGET"
187 cd "$TFLITE_BUILD_TARGET"
188
189 local target_arch_cmd="" # default is native, no command needed
190 local cmake_flags=""
191
192 case "$TARGET_ARCH" in
193 "aarch64")
194 cmake_flags+="$AARCH64_COMPILER_FLAGS"
James Conroy2e950f42022-11-01 15:01:06 +0000195 target_arch_cmd="-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
196 -DCMAKE_SYSTEM_NAME=Linux "
James Conroy919ec712022-07-13 12:57:53 +0100197
198 if [ "$NATIVE_BUILD" -eq 0 ]; then
199 cmake_flags+="ARMCC_FLAGS='-funsafe-math-optimizations' "
200 fi
201 ;;
John Mcloughlin35bae832023-07-24 11:55:13 +0100202 "android64")
203 cmake_flags+="$AARCH64_COMPILER_FLAGS"
204 if [ "$NATIVE_BUILD" -eq 0 ]; then
205 target_arch_cmd="-DCMAKE_TOOLCHAIN_FILE=$NDK_SRC/build/cmake/android.toolchain.cmake \
206 -DANDROID_ABI=$ANDROID_ARM_ARCH \
207 -DANDROID_PLATFORM=$ANDROID_API_VERSION"
208 fi
209 ;;
James Conroy919ec712022-07-13 12:57:53 +0100210 esac
211
212 echo -e "\n***** Building TF Lite for $TARGET_ARCH *****"
213
214 # Cleanup any previous cmake files, except actual builds which we keep
215 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
216
217 eval "$cmake_flags" \
218 cmake -DTFLITE_ENABLE_XNNPACK=OFF \
Colm Donelan3aad6f62023-04-20 21:56:11 +0100219 -DFLATBUFFERS_BUILD_FLATC=OFF \
220 -DBUILD_SHARED_LIBS=OFF \
221 -DBUILD_TESTING=OFF \
James Conroy919ec712022-07-13 12:57:53 +0100222 "$target_arch_cmd" \
223 "$TFLITE_SRC"
224 cmake --build . -j "$NUM_THREADS"
225
226 echo -e "\n***** Built TF Lite for $TARGET_ARCH *****"
227}
228
229generate_tflite_schema()
230{
231 echo -e "\n***** Generating TF Lite Schema *****"
232 mkdir -p "$TFLITE_BUILD_ROOT"
233 cd "$TFLITE_BUILD_ROOT"
234
235 cp "$SCHEMA_SRC" .
236
237 $FLATC -c --gen-object-api --reflect-types --reflect-names schema.fbs
238
239 echo -e "\n***** Generated TF Lite Schema *****"
240}
241
242download_onnx()
243{
244 download_and_extract \
245 "ONNX" \
246 "https://github.com/onnx/onnx/releases/download/v$ONNX_VERSION/onnx-$ONNX_VERSION.tar.gz" \
247 "onnx-$ONNX_VERSION.tar.gz"
248}
249
250generate_onnx_sources()
251{
252 mkdir -p "$ONNX_BUILD_TARGET"
253 cd "$ONNX_SRC"
254
255 echo -e "\n***** Generating ONNX sources for $TARGET_ARCH *****"
256
257 export LD_LIBRARY_PATH="$PROTOBUF_BUILD_HOST"/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
258
259 eval "$PROTOCOL_COMPILER_HOST" onnx/onnx.proto \
260 --proto_path=. \
261 --proto_path="$ONNX_SRC" \
262 --proto_path="$PROTOBUF_BUILD_HOST"/include \
263 --cpp_out "$ONNX_BUILD_TARGET"
264
265 echo -e "\n***** Generated ONNX sources for $TARGET_ARCH *****"
266}
267
James Conroy919ec712022-07-13 12:57:53 +0100268usage()
269{
270 cat <<EOF
271setup-armnn.sh - Download and build Arm NN dependencies in the current directory (ROOT_DIR)
272setup-armnn.sh [OPTION]...
Nikhil Raj542c8482023-04-26 16:22:10 +0100273 --tflite-classic-delegate
274 setup dependencies for the existing Arm NN TF Lite Delegate
275 --tflite-opaque-delegate
276 setup dependencies for the new Opaque Delegate
James Conroy919ec712022-07-13 12:57:53 +0100277 --tflite-parser
278 setup dependencies for the Arm NN TF Lite Parser
279 --onnx-parser
280 setup dependencies for the Arm NN ONNX parser
281 --all
282 setup dependencies for all Arm NN components listed above
John Mcloughlin35bae832023-07-24 11:55:13 +0100283 --target-arch=[aarch64|android64|x86_64]
James Conroy919ec712022-07-13 12:57:53 +0100284 specify a target architecture (mandatory)
285 --num-threads=<INTEGER>
286 specify number of threads/cores to build dependencies with (optional: defaults to number of online CPU cores on host)
287 -h, --help
288 print brief usage information and exit
289 -x
290 enable shell tracing in this script
291
Nikhil Raj542c8482023-04-26 16:22:10 +0100292At least one dependency flag (e.g. --tflite-classic-delegate) must be provided or else provide --all to setup all dependencies.
James Conroy919ec712022-07-13 12:57:53 +0100293Directories called "source" and "build" will be generated in the current directory (ROOT_DIR) from which this script is called.
294It's recommended to call this script in a directory outside of this Arm NN source repo, to avoid nested repositories.
295
James Conroy919ec712022-07-13 12:57:53 +0100296Examples:
297Setup for aarch64 with all Arm NN dependencies:
298 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --all
Nikhil Raj542c8482023-04-26 16:22:10 +0100299Setup for aarch64 with the existing TF Lite Delegate and TF Lite Parser dependencies only:
300 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --tflite-classic-delegate --tflite-parser
James Conroy919ec712022-07-13 12:57:53 +0100301EOF
302}
303
304# This will catch in validation.sh if not set
305target_arch=""
306
307# Default flag values
Nikhil Raj542c8482023-04-26 16:22:10 +0100308flag_tflite_classic_delegate=0
309flag_tflite_opaque_delegate=0
James Conroy919ec712022-07-13 12:57:53 +0100310flag_tflite_parser=0
311flag_onnx_parser=0
312
313# If --num-threads is not set, the default NUM_THREADS value in common.sh will be used
314num_threads=0
315
316name=$(basename "$0")
317
318# If no options provided, show help
319if [ $# -eq 0 ]; then
320 usage
321 exit 1
322fi
323
Nikhil Raj542c8482023-04-26 16:22:10 +0100324args=$(getopt -ohx -l tflite-classic-delegate,tflite-opaque-delegate,tflite-parser,onnx-parser,all,target-arch:,num-threads:,help -n "$name" -- "$@")
James Conroy919ec712022-07-13 12:57:53 +0100325eval set -- "$args"
326while [ $# -gt 0 ]; do
327 if [ -n "${opt_prev:-}" ]; then
328 eval "$opt_prev=\$1"
329 opt_prev=
330 shift 1
331 continue
332 elif [ -n "${opt_append:-}" ]; then
333 if [ -n "$1" ]; then
334 eval "$opt_append=\"\${$opt_append:-} \$1\""
335 fi
336 opt_append=
337 shift 1
338 continue
339 fi
340 case $1 in
341 --tflite-parser)
342 flag_tflite_parser=1
343 ;;
344
Nikhil Raj542c8482023-04-26 16:22:10 +0100345 --tflite-classic-delegate)
346 flag_tflite_classic_delegate=1
347 ;;
348
349 --tflite-opaque-delegate)
350 flag_tflite_opaque_delegate=1
James Conroy919ec712022-07-13 12:57:53 +0100351 ;;
352
353 --onnx-parser)
354 flag_onnx_parser=1
355 ;;
356
357 --all)
Nikhil Raj542c8482023-04-26 16:22:10 +0100358 flag_tflite_classic_delegate=1
359 flag_tflite_opaque_delegate=1
James Conroy919ec712022-07-13 12:57:53 +0100360 flag_tflite_parser=1
361 flag_onnx_parser=1
362 ;;
363
364 --target-arch)
365 opt_prev=target_arch
366 ;;
367
368 --num-threads)
369 opt_prev=num_threads
370 ;;
371
372 -h | --help)
373 usage
374 exit 0
375 ;;
376
377 -x)
378 set -x
379 ;;
380
381 --)
382 shift
383 break 2
384 ;;
385
386 esac
387 shift 1
388done
389
390# shellcheck source=common.sh
391source "$rel_path"/common.sh
392
393echo -e "\nINFO: Displaying configuration information before execution of $name"
Nikhil Raj542c8482023-04-26 16:22:10 +0100394echo " target-arch: $TARGET_ARCH"
395echo " host-arch: $HOST_ARCH"
396echo "tflite-classic-delegate: $flag_tflite_classic_delegate"
397echo "tflite-opaque-delegate : $flag_tflite_opaque_delegate"
398echo " tflite-parser: $flag_tflite_parser"
399echo " onnx-parser: $flag_onnx_parser"
400echo " num-threads: $NUM_THREADS"
401echo " root directory: $ROOT_DIR"
402echo " source directory: $SOURCE_DIR"
403echo " build directory: $BUILD_DIR"
James Conroy919ec712022-07-13 12:57:53 +0100404
James Conroy210897d2022-08-04 16:55:05 +0100405if check_if_repository .; then
James Conroy919ec712022-07-13 12:57:53 +0100406 echo -e "\n***** WARNING: Running script inside a git repository. To avoid nested repos, call this script from outside of this repo. *****"
407fi
408
409echo -e "\nScript execution will begin in 10 seconds..."
410
411sleep 10
412
413mkdir -p "$SOURCE_DIR"
414mkdir -p "$BUILD_DIR"
415
John Mcloughlin35bae832023-07-24 11:55:13 +0100416if [ "$TARGET_ARCH" == "android64" ]; then
417 download_androidndk
418fi
419
Nikhil Raj542c8482023-04-26 16:22:10 +0100420if [ "$flag_tflite_classic_delegate" -eq 1 ] || [ "$flag_tflite_opaque_delegate" -eq 1 ] || [ "$flag_tflite_parser" -eq 1 ]; then
James Conroy919ec712022-07-13 12:57:53 +0100421 download_flatbuffers
422
423 # Host build
424 build_flatbuffers 1
425
426 # Target build for cross compile
427 if [ "$NATIVE_BUILD" -eq 0 ]; then
428 build_flatbuffers 0
429 fi
430
431 download_tensorflow
432fi
433
434if [ "$flag_tflite_parser" -eq 1 ]; then
435 generate_tflite_schema
436fi
437
Nikhil Raj542c8482023-04-26 16:22:10 +0100438if [ "$flag_tflite_classic_delegate" -eq 1 ] || [ "$flag_tflite_opaque_delegate" -eq 1 ]; then
James Conroy919ec712022-07-13 12:57:53 +0100439 build_tflite
440fi
441
442if [ "$flag_onnx_parser" -eq 1 ]; then
443 download_protobuf
444
445 # Host build
446 build_protobuf 1
447
448 # Target build for cross compile
449 if [ "$NATIVE_BUILD" -eq 0 ]; then
450 build_protobuf 0
451 fi
452
453 download_onnx
454 generate_onnx_sources
455fi
456
457echo -e "\n***** Arm NN setup complete. Now build with build-armnn.sh. *****\n"
458
459exit 0