【问题标题】:Tensorflow: How to compile libtensorflow_cc.so for AndroidTensorflow:如何为 Android 编译 libtensorflow_cc.so
【发布时间】:2017-02-12 19:38:55
【问题描述】:

我目前正在尝试使用 Android 的 bazel 编译 TensorFlow 的目标 //tensorflow:libtensorflow_cc.so。我需要这个库才能让 TensorFlow 与 Android 一起使用的 javacpp-presets。

我尝试了以下语句:

bazel build -c opt //tensorflow:libtensorflow_cc.so --crosstool_top=//external:android/crosstool --cpu=armeabi-v7a --host_crosstool_top=@bazel_tools//tools/cpp:toolchain --verbose_failures

但是导致找不到 S_IREAD, S_IWRITE 的错误:

external/gif_archive/giflib-5.1.4/lib/egif_lib.c:62:6: error: 'S_IREAD' undeclared (first use in this function)
  S_IREAD | S_IWRITE);
  ^
external/gif_archive/giflib-5.1.4/lib/egif_lib.c:62:6: note: each undeclared identifier is reported only once for each function it appears in
external/gif_archive/giflib-5.1.4/lib/egif_lib.c:62:16: error: 'S_IWRITE' undeclared (first use in this function)
      S_IREAD | S_IWRITE);
                ^
Target //tensorflow:libtensorflow_cc.so failed to build

Android Demo build中的Android build启发,我也尝试将cc_binary定义更改为以下代码,但仍然出现相同的错误。

cc_binary(
    name = "libtensorflow_cc.so",
    copts = tf_copts(),
    linkopts = [
        "-landroid",
        "-ljnigraphics",
        "-llog",
        "-lm",
        "-z defs",
        "-s",
        "-Wl,--icf=all",  # Identical Code Folding
    ],
    linkshared = 1,
    linkstatic = 1,
    deps = [
        "//tensorflow/c:c_api",
        "//tensorflow/cc:cc_ops",
        "//tensorflow/core:tensorflow",
    ],
)

通过谷歌搜索,我发现 S_IWRITE 标志已被弃用,因此从未在 Android 中实现。但是,我不知道如何解决这个问题。

总结一下:您知道如何为 Android 构建 libtensorflow_cc.so 目标吗? Android 示例中的库构建对我来说是不够的,因为我还需要包含 cc_ops。

【问题讨论】:

  • 这个版本的 giflib 似乎已经解决了这个问题:android.googlesource.com/platform/external/giflib/+/… 注意他们已经做出改变的评论:/* android-changed: changed "S_IREAD | S_IWRITE" to "S_IRUSR | S_IWUSR" */
  • 我更新了这个问题,因为 Dan Albert 的回答解决了原来的问题,但是这导致了下一个问题。
  • 应该可能会问一个新问题,因为这个问题是不相关的,并且会有一个完全不同的答案。第二部分看起来只是与 TF 相关,而不是与 NDK 相关。
  • 谢谢提示。

标签: android android-ndk tensorflow javacpp


【解决方案1】:

通过谷歌搜索,我发现 S_IWRITE 标志已被弃用,因此从未在 Android 中实现。

为了兼容性,我们似乎改变了主意:https://android.googlesource.com/platform/bionic/+/1f1a51aecd7c825418bfedcb66772e92de790149%5E%21/#F2

#if defined(__USE_BSD) || defined(__USE_GNU)
#define S_IREAD S_IRUSR
#define S_IWRITE S_IWUSR
#define S_IEXEC S_IXUSR
#endif

这是系统的sys/stat.h;它尚未在 NDK 中发货。不幸的是,大多数 NDK 标头都非常过时。这是https://github.com/android-ndk/ndk/issues/120

我们将在 NDK r14 中对此进行修复(我刚刚提交了 https://github.com/android-ndk/ndk/issues/211 以修复旧标头,以防到那时 #120 还没有修复)。

在此之前,您可以将这些定义添加到您的 cflags 中。看起来在 bazel 中执行此操作的方法是:

cc_binary(
    name = "libtensorflow_cc.so",
    defines = [
        "S_IREAD=S_IRUSR",
        "S_IWRITE=S_IWUSR",
        "S_IEXEC=S_IXUSR",
    ],
    ...
)

https://www.bazel.io/versions/master/docs/be/c-cpp.html#cc_binary.defines

【讨论】:

  • 谢谢!这解决了这个问题。但是,现在我遇到了下一个问题。你也知道如何解决这个问题吗?
猜你喜欢
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
  • 2020-01-19
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多