2

I'm currently trying to compile the target //tensorflow:libtensorflow_cc.so of TensorFlow with bazel for Android. I need this library in order to get the javacpp-presets for TensorFlow working with Android.

I tried the following statement:

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

Which however results in the error that S_IREAD, S_IWRITE cannot be found:

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

Inspired by the Android build in the Android Demo build, I also tried to change the cc_binary definition to the following code, but still got the same error.

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",
    ],
)

From googling, I found out that the S_IWRITE flags are deprecated and therefore have never been implemented in Android. However, I have no idea how to get around this problem.

To sum it up: Do you know how I can build the libtensorflow_cc.so target for Android? The library build in the Android example is not enough for me because I also need the cc_ops included.

andy
  • 1,852
  • 2
  • 20
  • 31
  • This version of giflib seems to have fixed the issue: https://android.googlesource.com/platform/external/giflib/+/814d1938f091d311c709bc714c2d31032d43d7bc/egif_lib.c#61 Note the comment that they have made the change: /* android-changed: changed "S_IREAD | S_IWRITE" to "S_IRUSR | S_IWUSR" */ – Yao Zhang Oct 04 '16 at 18:11
  • I updated the question, as Dan Albert's answer fixed the original problem, which however led to the next problem. – andy Oct 05 '16 at 08:06
  • Should probably ask a new question since that problem is unrelated and will have a completely different answer. Part two looks to be just TF related rather than NDK related. – Dan Albert Oct 05 '16 at 18:29
  • Thx for the hint. – andy Oct 06 '16 at 08:08

1 Answers1

3

From googling, I found out that the S_IWRITE flags are deprecated and therefore have never been implemented in Android.

It looks like we've changed our minds on that for the sake of compatibility: 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

That's the system's sys/stat.h; it hasn't been shipped in the NDK yet. Unfortunately most of the NDK headers are very out of date. This is https://github.com/android-ndk/ndk/issues/120.

We'll get a fix for this into NDK r14 (I just filed https://github.com/android-ndk/ndk/issues/211 to fix up the old headers in case #120 doesn't get fixed by then).

Until then, you could add those defines to your cflags. Looks like the way to do this in bazel would be:

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

Dan Albert
  • 10,079
  • 2
  • 36
  • 79
  • Thanks! This solved that problem. However, now I have the next problem. Do you know how to fix this, too? – andy Oct 05 '16 at 08:05