主要流程参考TensorFlow Android Demo 项目地址
一,下载 TensorFlow Android Demo项目源码
git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git
二,编译安装,主要有以下两种方法:
1,利用Bazel直接在源码中进行编译
(1) 参考官网步骤安装Bazel,Android SDK和NDK,注意NDK版本为14b。
(2) 在项目TensorFlow 根目录下执行./configure,注意填入本机python,Android SDK和NDK正确的安装路径,其中python的安装教程可以参考我另一篇博客TensorFlow在Windows7和Mac中的安装步骤。并且针对Would you like to interactively configure ./WORKSPACE for Android builds?选择yes,其他的都选择no和默认即可。
以下路径为我本机的安装路径,仅供参考:
python:/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
Android SDK:/Users/用户名/library/Android/Sdk
Android NDK:/Users/用户名/library/Android/Sdk/android-ndk-r14b
(3) 在项目TensorFlow 根目录下执行以下命令进行编译:
bazel build --cxxopt='--std=c++11' -c opt //tensorflow/examples/android:tensorflow_demo
在编译的过程中遇到以下错误:
ERROR: /private/var/tmp/_bazel_cixueting/58f9ed3d91201fabd195ccb0da38a86b/external/com_google_absl/absl/base/BUILD.bazel:29:1: C++ compilation of rule '@com_google_absl//absl/base:spinlock_wait' failed (Exit 1)
In file included from external/com_google_absl/absl/base/internal/spinlock_wait.cc:27:
In file included from external/com_google_absl/absl/base/internal/spinlock_linux.inc:17:
external/androidndk/ndk/platforms/android-14/arch-arm/usr/include/linux/futex.h:28:21: error: field has incomplete type 'struct robust_list'
struct robust_list __user *next;
^
external/androidndk/ndk/platforms/android-14/arch-arm/usr/include/linux/futex.h:27:8: note: definition of 'robust_list' is not complete until the closing '}'
struct robust_list {
^
external/androidndk/ndk/platforms/android-14/arch-arm/usr/include/linux/futex.h:28:27: error: expected ';' at end of declaration list
struct robust_list __user *next;
^
external/androidndk/ndk/platforms/android-14/arch-arm/usr/include/linux/futex.h:37:27: error: expected ';' at end of declaration list
struct robust_list __user *list_op_pending;
^
3 errors generated.
根据报错信息的路径,找到“futex.h”文件后,其出错的代码如下
struct robust_list {
struct robust_list __user *next;
};
struct robust_list_head {
struct robust_list list;
long futex_offset;
struct robust_list __user *list_op_pending;
};
其中两行中的“__user”编译器不认识,这个符号是个宏,用途大概是linux编译器用来分配变量空间的标志。不知道由于什么原因,这个宏没有定义,所以报错了。根据文件开始处的注释,我们可以知道,这个.h是调用linux相关库函数时用到的声明文件,从语法上来说,直接删除这两个“__user”编译器就不会报错了。也可以谨慎一点,在这里增加下列宏,使得当没有外部定义时,这个符号定义为空。
#ifndef __user
#define __user
#endif
修改完成后重新编译,编译通过:
Target //tensorflow/examples/android:tensorflow_demo up-to-date:
bazel-bin/tensorflow/examples/android/tensorflow_demo_deploy.jar
bazel-bin/tensorflow/examples/android/tensorflow_demo_unsigned.apk
bazel-bin/tensorflow/examples/android/tensorflow_demo.apk
INFO: Elapsed time: 830.093s, Critical Path: 71.80s
INFO: 879 processes: 867 local, 12 worker.
INFO: Build completed successfully, 906 total actions
(4) 安装:
adb install -r bazel-bin/tensorflow/examples/android/tensorflow_demo.apk
安装完成后的界面如下图所示,运行效果类似官网。
2,在AndroidStudio中编译运行:
将tensorflow/tensorflow/examples/android文件夹的内容导入Android Studio,并在build.gradle中将defnativeBuildSystem='bazel’改为defnativeBuildSystem='none’编译完成后在手机端不能正常运行,如果不做更改则编译都通不过,在官网上看到这么一句:
Pick your preferred approach below. At the moment, we have full support for Bazel, and partial support for gradle, cmake, make, and Android Studio.
不明白是不是还没有完全支持在Android Studio上进行编译的原因,所以暂时先放弃,如果有编译成功的麻烦回帖交流,不胜感激!