tflite-rs
tflite-rs copied to clipboard
Unable to cross-compile to Android
I'm trying to use the tflite
crate on Android and iOS, but have been having issues getting it to compile. For some reason it doesn't look like bindgen
can find the C++ STL when it tries to generate bindings.
$ RUST_BACKTRACE=1 cargo build --target aarch64-linux-android
Compiling tflite v0.9.5 (/tmp/tflite-rs)
error: failed to run custom build command for `tflite v0.9.5 (/tmp/tflite-rs)`
Caused by:
process didn't exit successfully: `/tmp/tflite-rs/target/debug/build/tflite-764e91f18045bab8/build-script-build` (exit status: 101)
--- stderr
csrc/stl_wrapper.hpp:1:10: fatal error: 'memory' file not found
csrc/stl_wrapper.hpp:1:10: fatal error: 'memory' file not found, err: true
thread 'main' panicked at 'Unable to generate STL bindings: ()', build.rs:299:10
stack backtrace:
0: rust_begin_unwind
at /rustc/1c6868aa21981b37cbd3fc95828ee3b0ac22d494/library/std/src/panicking.rs:515:5
1: core::panicking::panic_fmt
at /rustc/1c6868aa21981b37cbd3fc95828ee3b0ac22d494/library/core/src/panicking.rs:92:14
2: core::result::unwrap_failed
at /rustc/1c6868aa21981b37cbd3fc95828ee3b0ac22d494/library/core/src/result.rs:1355:5
3: core::result::Result<T,E>::expect
at /rustc/1c6868aa21981b37cbd3fc95828ee3b0ac22d494/library/core/src/result.rs:997:23
4: build_script_build::import_stl_types
at ./build.rs:282:20
5: build_script_build::main
at ./build.rs:530:5
6: core::ops::function::FnOnce::call_once
at /rustc/1c6868aa21981b37cbd3fc95828ee3b0ac22d494/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Do you have any suggestions for resolving this?
Full Steps to Reproduce
First, clone the tflite
crate:
$ cd /tmp
$ git clone https://github.com/boncheolgu/tflite-rs
$ cd tflite-rs
$ git log -1
commit b206241826e92005ad2155b20f04b6c293892372 (HEAD -> master, origin/master, origin/HEAD)
Author: Boncheol Gu <[email protected]>
Date: Sat Mar 20 17:19:51 2021 +0900
Bump version to v0.9.5
Next we need to add set up our environment for cross-compiling. This involves adding the aarch64-linux-android
target and telling cargo
where our C compiler and archiver is.
$ rustup target add aarch64-linux-android
$ rustc --version --verbose
rustc 1.54.0-nightly (1c6868aa2 2021-05-27)
binary: rustc
commit-hash: 1c6868aa21981b37cbd3fc95828ee3b0ac22d494
commit-date: 2021-05-27
host: x86_64-unknown-linux-gnu
release: 1.54.0-nightly
LLVM version: 12.0.1
$ echo $ANDROID_HOME
/home/michael/Android/Sdk
$ echo $NDK_HOME
/home/michael/Android/Sdk/ndk/22.1.7171670
$ cat ~/.cargo/config
[target.aarch64-linux-android]
ar = "/home/michael/Android/Sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar"
linker = "/home/michael/Android/Sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang"
I had the same issue using the tf_v2.4.1
branch, although I needed to tell cc
where the C compiler and archiver is.
$ git checkout tf_v2.4.1
$ git log -1
commit 59894c2ad99bbccc1944d935b97e2863f61f71a4 (HEAD -> tf_v2.4.1, origin/tf_v2.4.1)
Author: Tyler Hawkes <[email protected]>
Date: Mon May 24 23:44:05 2021 +0000
Adding send/sync implementations
$ export CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++
$ export CC_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang
$ export AR_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar
$ cargo build --target aarch64-linux-android
Compiling tflite v0.10.1 (/tmp/tflite-rs)
error: failed to run custom build command for `tflite v0.10.1 (/tmp/tflite-rs)`
Caused by:
process didn't exit successfully: `/tmp/tflite-rs/target/debug/build/tflite-e5d8c2c5e7f7c2ae/build-script-build` (exit status: 101)
--- stderr
csrc/stl_wrapper.hpp:1:10: fatal error: 'memory' file not found
csrc/stl_wrapper.hpp:1:10: fatal error: 'memory' file not found, err: true
thread 'main' panicked at 'Unable to generate STL bindings: ()', build.rs:328:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
On Discord, @bkirwi pointed out you can use the BINDGEN_EXTRA_CLANG_ARGS
environment variable to point bindgen
at the STL for your Android NDK so I've now moved on to a different compilation error.
$ export AR_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar
$ export CC_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang
$ export CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++
$ export BINDGEN_EXTRA_CLANG_ARGS=-I$NDK_HOME/sources/cxx-stl/llvm-libc++/include/
$ cargo build --target aarch64-linux-android
...
Compiling tflite v0.9.6
error: failed to run custom build command for `tflite v0.9.6`
Caused by:
process didn't exit successfully: `/home/michael/Documents/hotg-ai/rune/target/debug/build/tflite-e86bb924f15fa979/build-script-build` (exit status: 101)
--- stderr
/home/michael/Android/Sdk/ndk/22.1.7171670/sources/cxx-stl/llvm-libc++/include/typeinfo:222:16: error: reinterpret_cast from 'std::__type_info_implementations::__non_unique_arm_rtti_bit_impl::__type_name_t' (aka 'unsigned int') to 'size_t' (aka 'unsigned long') is not allowed
/home/michael/Android/Sdk/ndk/22.1.7171670/sources/cxx-stl/llvm-libc++/include/typeinfo:222:16: error: reinterpret_cast from 'std::__type_info_implementations::__non_unique_arm_rtti_bit_impl::__type_name_t' (aka 'unsigned int') to 'size_t' (aka 'unsigned long') is not allowed, err: true
thread 'main' panicked at 'Unable to generate STL bindings: ()', /home/michael/.cargo/registry/src/github.com-1ecc6299db9ec823/tflite-0.9.6/build.rs:280:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: build failed
It seems like tflite
's build script isn't telling bindgen
that it is targeting a 64-bit platform because it thinks __type_name_t
is an unsigned int
instead of a unsigned long
.
Did you solved it?
Our solution was to create our own library which builds TensorFlow Lite and exposes just enough functionality to suit our needs while also (cross-)compiling to our target devices (Android, iOS, x86/ARM linux, x86 MacOS, Windows, etc.).
On Discord, @bkirwi pointed out you can use the
BINDGEN_EXTRA_CLANG_ARGS
environment variable to pointbindgen
at the STL for your Android NDK so I've now moved on to a different compilation error.$ export AR_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar $ export CC_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang $ export CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ $ export BINDGEN_EXTRA_CLANG_ARGS=-I$NDK_HOME/sources/cxx-stl/llvm-libc++/include/ $ cargo build --target aarch64-linux-android ... Compiling tflite v0.9.6 error: failed to run custom build command for `tflite v0.9.6` Caused by: process didn't exit successfully: `/home/michael/Documents/hotg-ai/rune/target/debug/build/tflite-e86bb924f15fa979/build-script-build` (exit status: 101) --- stderr /home/michael/Android/Sdk/ndk/22.1.7171670/sources/cxx-stl/llvm-libc++/include/typeinfo:222:16: error: reinterpret_cast from 'std::__type_info_implementations::__non_unique_arm_rtti_bit_impl::__type_name_t' (aka 'unsigned int') to 'size_t' (aka 'unsigned long') is not allowed /home/michael/Android/Sdk/ndk/22.1.7171670/sources/cxx-stl/llvm-libc++/include/typeinfo:222:16: error: reinterpret_cast from 'std::__type_info_implementations::__non_unique_arm_rtti_bit_impl::__type_name_t' (aka 'unsigned int') to 'size_t' (aka 'unsigned long') is not allowed, err: true thread 'main' panicked at 'Unable to generate STL bindings: ()', /home/michael/.cargo/registry/src/github.com-1ecc6299db9ec823/tflite-0.9.6/build.rs:280:10 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace warning: build failed, waiting for other jobs to finish... error: build failed
It seems like
tflite
's build script isn't tellingbindgen
that it is targeting a 64-bit platform because it thinks__type_name_t
is anunsigned int
instead of aunsigned long
.
I hope I'm not wrong to ask this here on such an old thread. But I have exactly the same blocker. I'm wondering if you happen to know what I would have to do to correct bindgen such that it targets a 64 bit platform?
Sorry, I can't really help you there. We ended up moving away from the tflite-rs
crate.
I don't want to be that guy who found a solution but left no update, so here goes:
Take a look at my solution
I would suggest to build tflitec-rs with a empty (except for the tflitec dependency) cargo project with all the settings configured for Android NDK 21. you'll need bazelisk
, android studio
and cargo-ndk
installed. Take a look at the this folder in this commit in my solution and you'll find the necessary environment variables. There's even a script. I hope it helps. Once you've succeeded in building your project for all platforms, you'll find the built artifact under the /target/
If you're really suffering, you can just grab the 64-bit libs here
And very importantly, make sure you use rust 1.67.1
or BELLOW! since version 1.6.8 rust does not compile with NDK lower than 25
Compatibility Notes # Only support Android NDK 25 or newer