44#
55# SPDX-License-Identifier: MIT
66#
7-
87function Usage() {
98 echo "This script builds Arm NN for Android using the Android NDK. The script builds"
109 echo "the Arm NN core library and its dependencies."
@@ -90,20 +89,21 @@ function GetAndroidNDK {
9089 cd $WORKING_DIR
9190 if [[ ! -d android-ndk-r26b ]]; then
9291 echo "+++ Getting Android NDK"
93- wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
94- unzip android-ndk-r26b-linux.zip
92+ wget -O android-ndk-r26b-linux.zip https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
93+ unzip -o android-ndk-r26b-linux.zip
94+ rm -f android-ndk-r26b-linux.zip
9595 fi
9696}
9797
9898function GetAndBuildCmake {
9999 echo "+++ Building Cmake 3.22.1"
100100 cd $WORKING_DIR
101- sudo apt-get install libssl-dev
101+ sudo apt-get update -y && sudo apt-get install -y libssl-dev build-essential ca-certificates
102102 wget https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1.tar.gz
103103 tar -zxf cmake-3.22.1.tar.gz
104104 pushd cmake-3.22.1
105105 ./bootstrap --prefix=$WORKING_DIR/cmake/install
106- make all install
106+ make all install -j16
107107 popd
108108}
109109
@@ -130,6 +130,7 @@ function GetAndBuildFlatbuffers {
130130
131131 CXXFLAGS="-fPIC" $CMAKE .. \
132132 -DFLATBUFFERS_BUILD_FLATC=1 \
133+ -DTFLITE_HOST_TOOLS_DIR=$WORKING_DIR/flatbuffers-x86/bin \
133134 -DCMAKE_INSTALL_PREFIX:PATH=$WORKING_DIR/flatbuffers-x86
134135
135136 make all install -j16
@@ -140,11 +141,11 @@ function GetAndBuildFlatbuffers {
140141 rm -f CMakeCache.txt
141142
142143 rm -rf build-android
143- mkdir build-android
144+ mkdir -p build-android
144145 cd build-android
145146
146147 rm -rf $WORKING_DIR/flatbuffers-android
147- mkdir $WORKING_DIR/flatbuffers-android
148+ mkdir -p $WORKING_DIR/flatbuffers-android
148149
149150 CC=/usr/bin/aarch64-linux-gnu-gcc CXX=/usr/bin/aarch64-linux-gnu-g++ \
150151 CXXFLAGS="-fPIC" $CMAKE .. \
@@ -216,7 +217,7 @@ function GetAndBuildComputeLibrary {
216217}
217218
218219function GetAndBuildTFLite {
219- TENSORFLOW_REVISION="tags/v2.14 .0" # TF 2.14 .0
220+ TENSORFLOW_REVISION="tags/v2.19 .0" # TF 2.19 .0
220221 TFLITE_ROOT_DIR=${WORKING_DIR}/tensorflow/tensorflow/lite
221222
222223 cd $WORKING_DIR
@@ -237,14 +238,29 @@ function GetAndBuildTFLite {
237238 cd $WORKING_DIR
238239 fi
239240
241+ # Ensure we use a known host protoc and headers to generate any protos
242+ HOST_PROTOC="$WORKING_DIR/protobuf-host/bin/protoc"
243+ PROTOBUF_HOST_INCLUDE="$WORKING_DIR/protobuf-host/include"
244+ if [[ ! -x "$HOST_PROTOC" ]]; then
245+ echo "Error: Host protoc not found at $HOST_PROTOC. Build Protobuf first." >&2
246+ exit 1
247+ fi
248+
240249 CMARGS="-DTFLITE_ENABLE_XNNPACK=OFF \
241250 -DFLATBUFFERS_BUILD_FLATC=OFF \
242251 -DBUILD_SHARED_LIBS=OFF \
243- -DBUILD_TESTING=OFF"
252+ -DBUILD_TESTING=OFF \
253+ -DTFLITE_BUILD_EXAMPLES=OFF \
254+ -DTFLITE_ENABLE_PROFILING=OFF \
255+ -DProtobuf_PROTOC_EXECUTABLE=$HOST_PROTOC \
256+ -DProtobuf_INCLUDE_DIRS=$PROTOBUF_HOST_INCLUDE \
257+ -DTFLITE_HOST_TOOLS_DIR=$WORKING_DIR/flatbuffers-x86/bin "
244258
245259 # Two different naming conventions; one for build and the other for CC_OPT_FLAGS
246260 ANDROID_ARM_ARCH="arm64-v8a"
247261
262+ # Clean previous build to avoid stale generated sources from older protoc
263+ rm -rf tflite-out/android
248264 mkdir -p tflite-out/android
249265 cd tflite-out/android
250266
@@ -265,21 +281,48 @@ function GetAndBuildTFLite {
265281
266282 mkdir -p $WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema
267283
268- SCHEMA_LOCATION=$WORKING_DIR/tensorflow/tensorflow/lite/schema/schema.fbs
284+ # TensorFlow >= 2.14 moved schema to compiler/mlir/lite/schema
285+ SCHEMA_LOCATION_NEW=$WORKING_DIR/tensorflow/tensorflow/compiler/mlir/lite/schema/schema.fbs
286+ SCHEMA_LOCATION_OLD=$WORKING_DIR/tensorflow/tensorflow/lite/schema/schema.fbs
287+ if [[ -f "$SCHEMA_LOCATION_NEW" ]]; then
288+ SCHEMA_LOCATION="$SCHEMA_LOCATION_NEW"
289+ elif [[ -f "$SCHEMA_LOCATION_OLD" ]]; then
290+ SCHEMA_LOCATION="$SCHEMA_LOCATION_OLD"
291+ else
292+ echo "TensorFlow schema.fbs not found in expected locations." >&2
293+ echo "Tried: $SCHEMA_LOCATION_NEW and $SCHEMA_LOCATION_OLD" >&2
294+ exit 1
295+ fi
269296
270- cp $SCHEMA_LOCATION $WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema
297+ cp " $SCHEMA_LOCATION" $WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema
271298
272299 cd $WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema
273300 $WORKING_DIR/flatbuffers-x86/bin/flatc -c --gen-object-api --reflect-types --reflect-names schema.fbs
274301 AssertZeroExitCode "Failed to generate C++ schema from $SCHEMA_LOCATION"
275302}
276303
304+ function GetPrebuiltProtoc {
305+ # Download a prebuilt protoc binary + headers to speed up iteration
306+ # Set PROTOC_VERSION to override; defaults to 21.9 to align with build-tool flow
307+ local ver=${PROTOC_VERSION:-21.9}
308+ local url="https://github.com/protocolbuffers/protobuf/releases/download/v${ver}/protoc-${ver}-linux-x86_64.zip"
309+ local outzip="$WORKING_DIR/protoc-${ver}-linux-x86_64.zip"
310+ local dest="$WORKING_DIR/protobuf-host"
311+
312+ echo "+++ Downloading prebuilt protoc ${ver}"
313+ mkdir -p "$dest"
314+ wget -O "$outzip" "$url"
315+ unzip -o "$outzip" -d "$dest"
316+ rm -f "$outzip"
317+ "$dest/bin/protoc" --version || true
318+ }
319+
277320function BuildArmNN {
278321 echo "+++ Building Arm NN"
279322
280323 rm -rf $WORKING_DIR/armnn/build
281324
282- mkdir $WORKING_DIR/armnn/build
325+ mkdir -p $WORKING_DIR/armnn/build
283326 cd $WORKING_DIR/armnn/build
284327
285328 CMARGS="-DCMAKE_BUILD_TYPE=Release \
@@ -424,7 +467,9 @@ if [[ $? != 0 ]] ; then
424467 echo "Downloading Android NDK failed"
425468 exit 1
426469fi
470+
427471GetAndBuildCmake
472+
428473CMAKE=$WORKING_DIR/cmake/install/bin/cmake
429474GetAndBuildFlatbuffers
430475if [[ $? != 0 ]] ; then
@@ -436,10 +481,14 @@ if [[ $? != 0 ]] ; then
436481 echo "Cloning Arm NN failed"
437482 exit 1
438483fi
484+
439485# Build TFLite if the Delegate or Parser is required
440- if [[ $DELEGATE == 1 || $TFLITE_PARSER ]]; then
486+ if [[ "$DELEGATE" -eq 1 || "$TFLITE_PARSER" -eq 1 ]]; then
487+ # Faster path: use prebuilt protoc instead of rebuilding
488+ GetPrebuiltProtoc
441489 GetAndBuildTFLite
442490fi
491+
443492if [[ $? != 0 ]] ; then
444493 echo "Building tflite failed"
445494 exit 1
0 commit comments