xref: /aosp_15_r20/external/armnn/build-tool/scripts/setup-armnn.sh (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
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