blob: 05d1280eed04b6a5fb65a5778e005287484ea2c0 [file] [log] [blame]
James Conroy919ec712022-07-13 12:57:53 +01001#!/bin/bash
2#
Tracy Narine5652e0e2024-02-22 15:54:14 +00003# Copyright © 2022-2024 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
Tracy Narine2883a862024-02-26 15:05:11 +000016# Figure out platform specific settings
17osname=$(uname)
18osgetopt=getopt
19os_darwin=0
20if [ "$osname" == "Darwin" ]; then
21 os_darwin=1
22 osgetoptsys="/opt/homebrew/opt/gnu-getopt/bin/getopt"
23 osgetopthome="$HOME/homebrew/opt/gnu-getopt/bin/getopt"
24 if [ -f "$osgetoptsys" ]; then
25 echo "gnu-getopt found at: $osgetoptsys"
26 osgetopt=$osgetoptsys
27 elif [ -f "$osgetopthome" ]; then
28 echo "gnu-getopt found at: $osgetopthome"
29 osgetopt=$osgetopthome
30 else
31 echo "Run $rel_path/install-packages.sh and follow the instructions to configure the environment for $osname"
32 exit 1
33 fi
34fi
35
James Conroy919ec712022-07-13 12:57:53 +010036# Download an archive using wget and extract using tar
37# Takes three arguments:
38# 1. Name of dependency being downloaded e.g. Flatbuffers
39# 2. Link to archive
40# 3. Filename given to archive upon downloading
41download_and_extract()
42{
43 cd "$SOURCE_DIR"
44
James Conroy210897d2022-08-04 16:55:05 +010045 echo -e "\n***** Downloading $1 *****\n"
James Conroy919ec712022-07-13 12:57:53 +010046 wget -O "$3" "$2"
47
48 echo -e "\n***** Extracting archive *****"
49 tar -xzf "$3"
50
51 echo -e "\n***** Removing archive *****"
52 rm "$3"
53
54 echo -e "\n***** $1 downloaded *****"
55}
56
John Mcloughlin35bae832023-07-24 11:55:13 +010057download_androidndk()
58{
59 cd "$SOURCE_DIR"
60 echo -e "\n***** Downloading Android NDK *****\n"
Nikhil Raj58a49232023-12-21 12:08:42 +000061 wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
John Mcloughlin35bae832023-07-24 11:55:13 +010062 echo -e "\n***** Extracting archive *****"
Nikhil Raj58a49232023-12-21 12:08:42 +000063 unzip android-ndk-r26b-linux.zip
John Mcloughlin35bae832023-07-24 11:55:13 +010064 echo -e "\n***** Removing archive *****"
Nikhil Raj58a49232023-12-21 12:08:42 +000065 rm android-ndk-r26b-linux.zip
John Mcloughlin35bae832023-07-24 11:55:13 +010066 echo -e "\n***** Android NDK downloaded *****"
67}
68
James Conroy919ec712022-07-13 12:57:53 +010069download_protobuf()
70{
71 download_and_extract \
72 "Protobuf" \
73 "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz" \
74 "protobuf-all-$PROTOBUF_VERSION.tar.gz"
75}
76
77build_protobuf()
78{
79 local native_build=$1
80 local build_dir="$PROTOBUF_BUILD_TARGET"
81 local cmake_flags=""
82 local target_arch="$TARGET_ARCH"
83 local additional_cmds=""
84
85 if [ "$native_build" -eq 0 ]; then
86 mkdir -p "$PROTOBUF_BUILD_TARGET"
87 additional_cmds+="--with-protoc=$PROTOCOL_COMPILER_HOST "
88 if [ "$TARGET_ARCH" == "aarch64" ]; then
89 cmake_flags+="$AARCH64_COMPILER_FLAGS"
90 additional_cmds+="--host=aarch64-linux "
James Conroy919ec712022-07-13 12:57:53 +010091 fi
John Mcloughlin35bae832023-07-24 11:55:13 +010092 if [ "$TARGET_ARCH" == "android64" ]; then
93 additional_cmds+="--host=aarch64-linux-android "
94 cmake_flags+="$ANDROID64_COMPILER_FLAGS"
95 fi
James Conroy919ec712022-07-13 12:57:53 +010096 else
97 target_arch="$HOST_ARCH"
98 mkdir -p "$PROTOBUF_BUILD_HOST"
99 build_dir="$PROTOBUF_BUILD_HOST"
100 fi
101
102 echo -e "\n***** Building Protobuf for $target_arch ***** "
103
104 cd "$PROTOBUF_BUILD_ROOT"
105
106 # Cleanup any previous cmake files, except actual builds which we keep
107 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
108
John Mcloughlin35bae832023-07-24 11:55:13 +0100109 if [ "$native_build" -eq 0 ] && [ "$TARGET_ARCH" == "android64" ]; then
110 eval "$cmake_flags"
111 cmake -DCMAKE_ANDROID_NDK="$NDK_SRC" \
112 -DCMAKE_SYSTEM_NAME=Android \
113 -DCMAKE_SYSTEM_VERSION="$ANDROID_API_VERSION" \
114 -DCMAKE_ANDROID_ARCH_ABI="$ANDROID_ARM_ARCH" \
115 -DCMAKE_CXX_FLAGS=--std=c++14 \
116 -Dprotobuf_BUILD_TESTS=OFF \
117 -Dprotobuf_BUILD_SHARED_LIBS=ON \
118 -Dprotobuf_WITH_ZLIB=OFF \
119 -DCMAKE_BUILD_TYPE=Release \
120 $PROTOBUF_SRC/cmake/
121 make libprotobuf -j "$NUM_THREADS"
122 cmake -DCMAKE_INSTALL_PREFIX=$PROTOBUF_BUILD_TARGET -DCOMPONENT=libprotobuf -P cmake_install.cmake
123 cmake -DCMAKE_INSTALL_PREFIX=$PROTOBUF_BUILD_TARGET -DCOMPONENT=protobuf-headers -P cmake_install.cmake
124 else
125 eval "$cmake_flags" \
126 "$PROTOBUF_SRC"/configure --prefix="$build_dir" "$additional_cmds"
127 make install -j "$NUM_THREADS"
128 fi
James Conroy919ec712022-07-13 12:57:53 +0100129
130 echo -e "\n***** Protobuf built for $target_arch ***** "
131}
132
133download_flatbuffers()
134{
135 download_and_extract \
136 "Flatbuffers" \
137 "https://github.com/google/flatbuffers/archive/v$FLATBUFFERS_VERSION.tar.gz" \
138 "flatbuffers-$FLATBUFFERS_VERSION.tar.gz"
139}
140
141build_flatbuffers()
142{
143 local native_build=$1
144 local build_dir="$FLATBUFFERS_BUILD_TARGET"
145 local target_arch="$TARGET_ARCH"
146
147 local cmake_flags="CXXFLAGS=-fPIC "
148
149 if [ "$native_build" -eq 0 ]; then
150 mkdir -p "$FLATBUFFERS_BUILD_TARGET"
Nikhil Rajba6dcb22023-11-24 16:25:10 +0000151 if [ "$TARGET_ARCH" == "aarch64" ]; then
James Conroy919ec712022-07-13 12:57:53 +0100152 cmake_flags+="$AARCH64_COMPILER_FLAGS"
James Conroy919ec712022-07-13 12:57:53 +0100153 fi
Nikhil Rajba6dcb22023-11-24 16:25:10 +0000154 if [ "$TARGET_ARCH" == "android64" ]; then
155 cmake_flags+="$ANDROID64_COMPILER_FLAGS"
156 fi
James Conroy919ec712022-07-13 12:57:53 +0100157 else
158 target_arch="$HOST_ARCH"
159 mkdir -p "$FLATBUFFERS_BUILD_HOST"
160 build_dir="$FLATBUFFERS_BUILD_HOST"
Tracy Narine2883a862024-02-26 15:05:11 +0000161 if [ "$os_darwin" -eq 1 ]; then
162 cmake_flags+="$AARCH64_COMPILER_FLAGS"
163 fi
James Conroy919ec712022-07-13 12:57:53 +0100164 fi
165
166 echo -e "\n***** Building flatbuffers for $target_arch *****"
167
168 mkdir -p "$FLATBUFFERS_BUILD_ROOT"
169 cd "$FLATBUFFERS_BUILD_ROOT"
170
171 # Cleanup any previous cmake files, except actual builds which we keep
172 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
173
John Mcloughlin35bae832023-07-24 11:55:13 +0100174 if [ "$native_build" -eq 0 ] && [ "$TARGET_ARCH" == "android64" ]; then
175 eval "$cmake_flags" \
176 cmake -DCMAKE_ANDROID_NDK="$NDK_SRC" \
177 -DCMAKE_SYSTEM_NAME=Android \
178 -DCMAKE_SYSTEM_VERSION="$ANDROID_API_VERSION" \
179 -DCMAKE_ANDROID_ARCH_ABI="$ANDROID_ARM_ARCH" \
180 -DCMAKE_CXX_FLAGS=--std=c++14 \
181 -DFLATBUFFERS_BUILD_FLATC=0 \
182 -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \
183 -DCMAKE_BUILD_TYPE=Release \
184 -DFLATBUFFERS_BUILD_TESTS=0 \
185 "$FLATBUFFERS_SRC"
186 else
187 eval "$cmake_flags" \
188 cmake -DFLATBUFFERS_BUILD_FLATC="$native_build" \
189 -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \
190 -DFLATBUFFERS_BUILD_TESTS=0 \
191 "$FLATBUFFERS_SRC"
192 fi
James Conroy919ec712022-07-13 12:57:53 +0100193 make all install -j "$NUM_THREADS"
194
195 echo -e "\n***** Built flatbuffers for $target_arch *****"
196}
197
198download_tensorflow()
199{
200 cd "$SOURCE_DIR"
201
202 echo -e "\n***** Downloading TensorFlow *****"
203 git clone https://github.com/tensorflow/tensorflow.git
204 cd "$TENSORFLOW_SRC"
205
James Conroy210897d2022-08-04 16:55:05 +0100206 git checkout "$TENSORFLOW_VERSION"
James Conroy919ec712022-07-13 12:57:53 +0100207 echo -e "\n***** TensorFlow downloaded *****"
208}
209
Tracy Narine2883a862024-02-26 15:05:11 +0000210build_tflite_cpuinfo()
211{
212 cd "$TFLITE_BUILD_TARGET"/cpuinfo
213 cmake .
214 make
215 cp *.a ../_deps/cpuinfo-build
216}
217
James Conroy919ec712022-07-13 12:57:53 +0100218build_tflite()
219{
220 mkdir -p "$TFLITE_BUILD_TARGET"
221 cd "$TFLITE_BUILD_TARGET"
222
223 local target_arch_cmd="" # default is native, no command needed
224 local cmake_flags=""
225
226 case "$TARGET_ARCH" in
227 "aarch64")
Tracy Narine2883a862024-02-26 15:05:11 +0000228 cmake_system="Linux"
229 if [ "$os_darwin" -eq 1 ]; then
230 cmake_system="Darwin"
231 fi
James Conroy919ec712022-07-13 12:57:53 +0100232 cmake_flags+="$AARCH64_COMPILER_FLAGS"
James Conroy2e950f42022-11-01 15:01:06 +0000233 target_arch_cmd="-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
Tracy Narine2883a862024-02-26 15:05:11 +0000234 -DCMAKE_SYSTEM_NAME=$cmake_system "
James Conroy919ec712022-07-13 12:57:53 +0100235
236 if [ "$NATIVE_BUILD" -eq 0 ]; then
237 cmake_flags+="ARMCC_FLAGS='-funsafe-math-optimizations' "
238 fi
239 ;;
John Mcloughlin35bae832023-07-24 11:55:13 +0100240 "android64")
Nikhil Rajba6dcb22023-11-24 16:25:10 +0000241 cmake_flags+="$ANDROID64_COMPILER_FLAGS"
John Mcloughlin35bae832023-07-24 11:55:13 +0100242 if [ "$NATIVE_BUILD" -eq 0 ]; then
243 target_arch_cmd="-DCMAKE_TOOLCHAIN_FILE=$NDK_SRC/build/cmake/android.toolchain.cmake \
244 -DANDROID_ABI=$ANDROID_ARM_ARCH \
245 -DANDROID_PLATFORM=$ANDROID_API_VERSION"
246 fi
247 ;;
James Conroy919ec712022-07-13 12:57:53 +0100248 esac
249
250 echo -e "\n***** Building TF Lite for $TARGET_ARCH *****"
251
252 # Cleanup any previous cmake files, except actual builds which we keep
253 find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} +
254
255 eval "$cmake_flags" \
256 cmake -DTFLITE_ENABLE_XNNPACK=OFF \
Colm Donelan3aad6f62023-04-20 21:56:11 +0100257 -DFLATBUFFERS_BUILD_FLATC=OFF \
258 -DBUILD_SHARED_LIBS=OFF \
259 -DBUILD_TESTING=OFF \
James Conroy919ec712022-07-13 12:57:53 +0100260 "$target_arch_cmd" \
261 "$TFLITE_SRC"
262 cmake --build . -j "$NUM_THREADS"
263
Tracy Narine2883a862024-02-26 15:05:11 +0000264 if [ "$os_darwin" -eq 1 ]; then
265 # Workaround undefined link error for this platform
266 build_tflite_cpuinfo
267 fi
268
James Conroy919ec712022-07-13 12:57:53 +0100269 echo -e "\n***** Built TF Lite for $TARGET_ARCH *****"
270}
271
272generate_tflite_schema()
273{
274 echo -e "\n***** Generating TF Lite Schema *****"
275 mkdir -p "$TFLITE_BUILD_ROOT"
276 cd "$TFLITE_BUILD_ROOT"
277
278 cp "$SCHEMA_SRC" .
279
280 $FLATC -c --gen-object-api --reflect-types --reflect-names schema.fbs
281
282 echo -e "\n***** Generated TF Lite Schema *****"
283}
284
285download_onnx()
286{
287 download_and_extract \
288 "ONNX" \
289 "https://github.com/onnx/onnx/releases/download/v$ONNX_VERSION/onnx-$ONNX_VERSION.tar.gz" \
290 "onnx-$ONNX_VERSION.tar.gz"
291}
292
293generate_onnx_sources()
294{
295 mkdir -p "$ONNX_BUILD_TARGET"
296 cd "$ONNX_SRC"
297
298 echo -e "\n***** Generating ONNX sources for $TARGET_ARCH *****"
299
300 export LD_LIBRARY_PATH="$PROTOBUF_BUILD_HOST"/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
301
302 eval "$PROTOCOL_COMPILER_HOST" onnx/onnx.proto \
303 --proto_path=. \
304 --proto_path="$ONNX_SRC" \
305 --proto_path="$PROTOBUF_BUILD_HOST"/include \
306 --cpp_out "$ONNX_BUILD_TARGET"
307
308 echo -e "\n***** Generated ONNX sources for $TARGET_ARCH *****"
309}
310
James Conroy919ec712022-07-13 12:57:53 +0100311usage()
312{
313 cat <<EOF
314setup-armnn.sh - Download and build Arm NN dependencies in the current directory (ROOT_DIR)
315setup-armnn.sh [OPTION]...
Nikhil Raj542c8482023-04-26 16:22:10 +0100316 --tflite-classic-delegate
317 setup dependencies for the existing Arm NN TF Lite Delegate
318 --tflite-opaque-delegate
319 setup dependencies for the new Opaque Delegate
James Conroy919ec712022-07-13 12:57:53 +0100320 --tflite-parser
321 setup dependencies for the Arm NN TF Lite Parser
322 --onnx-parser
323 setup dependencies for the Arm NN ONNX parser
324 --all
325 setup dependencies for all Arm NN components listed above
John Mcloughlin35bae832023-07-24 11:55:13 +0100326 --target-arch=[aarch64|android64|x86_64]
James Conroy919ec712022-07-13 12:57:53 +0100327 specify a target architecture (mandatory)
328 --num-threads=<INTEGER>
329 specify number of threads/cores to build dependencies with (optional: defaults to number of online CPU cores on host)
330 -h, --help
331 print brief usage information and exit
332 -x
333 enable shell tracing in this script
334
Nikhil Raj542c8482023-04-26 16:22:10 +0100335At 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 +0100336Directories called "source" and "build" will be generated in the current directory (ROOT_DIR) from which this script is called.
337It's recommended to call this script in a directory outside of this Arm NN source repo, to avoid nested repositories.
338
James Conroy919ec712022-07-13 12:57:53 +0100339Examples:
340Setup for aarch64 with all Arm NN dependencies:
341 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --all
Nikhil Raj542c8482023-04-26 16:22:10 +0100342Setup for aarch64 with the existing TF Lite Delegate and TF Lite Parser dependencies only:
343 <PATH_TO>/setup-armnn.sh --target-arch=aarch64 --tflite-classic-delegate --tflite-parser
James Conroy919ec712022-07-13 12:57:53 +0100344EOF
345}
346
347# This will catch in validation.sh if not set
348target_arch=""
349
350# Default flag values
Nikhil Raj542c8482023-04-26 16:22:10 +0100351flag_tflite_classic_delegate=0
352flag_tflite_opaque_delegate=0
James Conroy919ec712022-07-13 12:57:53 +0100353flag_tflite_parser=0
354flag_onnx_parser=0
355
356# If --num-threads is not set, the default NUM_THREADS value in common.sh will be used
357num_threads=0
358
359name=$(basename "$0")
360
361# If no options provided, show help
362if [ $# -eq 0 ]; then
363 usage
364 exit 1
365fi
366
Tracy Narine2883a862024-02-26 15:05:11 +0000367args=$($osgetopt -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 +0100368eval set -- "$args"
369while [ $# -gt 0 ]; do
370 if [ -n "${opt_prev:-}" ]; then
371 eval "$opt_prev=\$1"
372 opt_prev=
373 shift 1
374 continue
375 elif [ -n "${opt_append:-}" ]; then
376 if [ -n "$1" ]; then
377 eval "$opt_append=\"\${$opt_append:-} \$1\""
378 fi
379 opt_append=
380 shift 1
381 continue
382 fi
383 case $1 in
384 --tflite-parser)
385 flag_tflite_parser=1
386 ;;
387
Nikhil Raj542c8482023-04-26 16:22:10 +0100388 --tflite-classic-delegate)
389 flag_tflite_classic_delegate=1
390 ;;
391
392 --tflite-opaque-delegate)
393 flag_tflite_opaque_delegate=1
James Conroy919ec712022-07-13 12:57:53 +0100394 ;;
395
396 --onnx-parser)
397 flag_onnx_parser=1
398 ;;
399
400 --all)
Nikhil Raj542c8482023-04-26 16:22:10 +0100401 flag_tflite_classic_delegate=1
402 flag_tflite_opaque_delegate=1
James Conroy919ec712022-07-13 12:57:53 +0100403 flag_tflite_parser=1
404 flag_onnx_parser=1
405 ;;
406
407 --target-arch)
408 opt_prev=target_arch
409 ;;
410
411 --num-threads)
412 opt_prev=num_threads
413 ;;
414
415 -h | --help)
416 usage
417 exit 0
418 ;;
419
420 -x)
421 set -x
422 ;;
423
424 --)
425 shift
426 break 2
427 ;;
428
429 esac
430 shift 1
431done
432
433# shellcheck source=common.sh
434source "$rel_path"/common.sh
435
436echo -e "\nINFO: Displaying configuration information before execution of $name"
Nikhil Raj542c8482023-04-26 16:22:10 +0100437echo " target-arch: $TARGET_ARCH"
438echo " host-arch: $HOST_ARCH"
439echo "tflite-classic-delegate: $flag_tflite_classic_delegate"
Cathal Corbett80ef5112024-03-13 10:41:02 +0000440echo " tflite-opaque-delegate: $flag_tflite_opaque_delegate"
Nikhil Raj542c8482023-04-26 16:22:10 +0100441echo " tflite-parser: $flag_tflite_parser"
442echo " onnx-parser: $flag_onnx_parser"
443echo " num-threads: $NUM_THREADS"
444echo " root directory: $ROOT_DIR"
445echo " source directory: $SOURCE_DIR"
446echo " build directory: $BUILD_DIR"
James Conroy919ec712022-07-13 12:57:53 +0100447
James Conroy210897d2022-08-04 16:55:05 +0100448if check_if_repository .; then
James Conroy919ec712022-07-13 12:57:53 +0100449 echo -e "\n***** WARNING: Running script inside a git repository. To avoid nested repos, call this script from outside of this repo. *****"
450fi
451
James Conroy919ec712022-07-13 12:57:53 +0100452mkdir -p "$SOURCE_DIR"
453mkdir -p "$BUILD_DIR"
454
John Mcloughlin35bae832023-07-24 11:55:13 +0100455if [ "$TARGET_ARCH" == "android64" ]; then
456 download_androidndk
457fi
458
Tracy Narine5652e0e2024-02-22 15:54:14 +0000459if [ "$flag_onnx_parser" -eq 1 ] || [ "$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 +0100460 download_flatbuffers
461
462 # Host build
463 build_flatbuffers 1
464
465 # Target build for cross compile
466 if [ "$NATIVE_BUILD" -eq 0 ]; then
467 build_flatbuffers 0
468 fi
469
Tracy Narine5652e0e2024-02-22 15:54:14 +0000470 if [ "$flag_tflite_classic_delegate" -eq 1 ] || [ "$flag_tflite_opaque_delegate" -eq 1 ] || [ "$flag_tflite_parser" -eq 1 ]; then
471 download_tensorflow
472 fi
James Conroy919ec712022-07-13 12:57:53 +0100473fi
474
475if [ "$flag_tflite_parser" -eq 1 ]; then
476 generate_tflite_schema
477fi
478
Nikhil Raj542c8482023-04-26 16:22:10 +0100479if [ "$flag_tflite_classic_delegate" -eq 1 ] || [ "$flag_tflite_opaque_delegate" -eq 1 ]; then
James Conroy919ec712022-07-13 12:57:53 +0100480 build_tflite
481fi
482
483if [ "$flag_onnx_parser" -eq 1 ]; then
484 download_protobuf
485
486 # Host build
487 build_protobuf 1
488
489 # Target build for cross compile
490 if [ "$NATIVE_BUILD" -eq 0 ]; then
491 build_protobuf 0
492 fi
493
494 download_onnx
495 generate_onnx_sources
496fi
497
498echo -e "\n***** Arm NN setup complete. Now build with build-armnn.sh. *****\n"
499
Nikhil Rajba6dcb22023-11-24 16:25:10 +0000500exit 0