I am trying to run a neural network on Android in C++. The examples (https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/android) show how to use tensorflow using JAVA apis which call C++ using JNI functions. Has anyone tried to use tensorflow directly in C++ on Android? How can the tensorflow library be built and linked for using C++ apis on Android. Can you please guide me on that? I want to use C++ apis on Android in the similar way as done in iOS examples.
Here is how I solved this problem. Although there is not much documentation of using c++ apis on android and compiling and linking tensorflow to NDK, the makefile have important comments as well as there are associated scripts. Compilation steps are very similar to that of ios.
Install following dependencies a)autoconf b) automake c)automake. Then run tensorflow/contrib/makefile/download_dependencies.sh; I ran on May 10, 2017 repository for the first time, when it worked perfectly. In the later version around June 1, due to some changes in tensorflow/workspace.bzl, that I do not understand in download_dependencies.sh fails to recognise the tar files download_dependencies is trying to download. I just replaced workspace.bzl from May 10 repo commit.
Step 2 is to run tensorflow/contrib/makefile/compile_android_protobuf.sh like this
NDK_ROOT=absolute/path/to/ndk/folder ./tensorflow/contrib/makefile/compile_android_protobuf.sh
Run make. But first you may need to make some changes in Makefile. Replace -fPIE flags with -fPIC flags. Also add -fPIC flag to HOST_CXXFLAGS. Then run make like this:
make -f tensorflow/contrib/makefile/Makefile TARGET=ANDROID NDK_ROOT=absolute/path/to/ndk/folder
Alternatively one can also run build_all_android.sh which runs all 3 steps in one go, but you may need to do Makefile changes for flags.
This generated tensorflow/contrib/makefile/gen/protobuf/lib/libprotobuf.a and tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a; This can be linked to Android NDK project in Android.mk file under LOCAL_LDLIBS. One should use these Linked flags -Wl,--build-id -Wl,--allow-multiple-definition -Wl,--whole-archive Also -std=c++11 in LOCAL_CFLAGS in Android.mk file and APP_STL := gnustl_shared in Application.mk file.
This should be sufficient to build a shared library of your NDK project.
100% possible, with a small caveat...
Most of Android's UI is done in Java. You can create a native activity, but to get any output to the screen, you need to either use OpenGL (which doesn't have all the nice Android UI Views) or you will need to transition the JNI barrier to get your data output to and from the native code to display to the user.
Depending on your familiarity with OpenGLES, EGL, etc.. You might opt to transition the JNI barrier instead of creating a native_activity, but at a much smaller cross section.
You could create a Runnable and signal it when there's work to be performed. Use a concurrent queue (in Java) to submit work and another (concurrent) queue to receive results from. The Runnable pops the work queue, calls a single JNI/C function to submit the work and return a JSON string. Then it submits the work to the finished queue.
Related
I'm building a shared library with C++ to be used on Android, i.e. the result of my work is a standard linux .so file. The library is compiled using clang and originally I planned to create a release build without any debugging information, include it in my Android app and off we go. Technically that all works.
However, there is one downside to this: Without debugging information a call stack created due to a crash of my shared library is pretty useless because it contains no reference to the source code anymore.
Now, Google Play offers a way to submit shared libraries without debugging information and a second copy of the same library with debugging information. The library without debugging information gets packaged into the Android app and is installed on end user devices. The second copy with the debugging information resided within Google Play, i.e. is not installed on end user devices. Google Play uses that copy to turn call stacks it receives from crashes to call stacks containing references to the source code.
BUT, for the life of me I cannot figure out how to strip out the debugging information of a shared library. The debugging information is in the DWARF format version 2.
I compile my library as follows:
clang ... -g2 -gdwarf-2 -O3 ...
So, the code is optimized but contains debugging information. Inspecting the resulting .so file using objdump -g libwhatever.so reveals a lot of DWARF information.
Compiling the same library with
clang ... -g0 -O3
and inspecting it using objdump -g libwhatever.so confirms that a lot less DWARF information is contained. This is the end goal.
So, the question is how can I strip out the DWARF debugging information compiled with the first clang call shown above so that I end up with the same result that is achieved by the second clang call?
What I have tried:
strip --strip-all libwhatever.so
This had no effect at all, i.e. the output is identical to the input.
objcopy --strip-debug libwhatever.so
Same as with strip, the output is identical to the input. That is what is recommended in the link above but I just cannot make it work.
I know that it might not be a real problem to ship a library containing debugging information. However, I'm attempting to obtain more insight here to understand better how the workflows are.
I am trying to use FFMPEG library for Video compression on Android.
I've compiled the library using : http://bambuser.com/opensource and https://www.quora.com/What-are-the-steps-for-integrating-FFMPEG-on-Android
Now next step is NDK build of this. But I am not sure what all will go as LOCAL_SRC_FILES, LOCAL_LDLIBS and LOCAL_C_INCLUDES.
Apart from that what function should be called for compression in this library.
Please suggest.
For ffmpeg use on Android (or other platforms) there are a number of common approachs you can take:
invoke the command line from your program via EXEC command (has some limitations and drawbacks)
use a wrapper around the ffmpeg command line C program
Directly use the ffmpeg libraries, or more accurately the libraries that ffmpeg uses
The wrapper approach may be the easiest is you simply want to get the functionality working quickly.
There are several fairly well used wrappers available on GitHub - the ones below are particularly well featured and documented (note, I have not used these as they were not so mature when I was looking at this previously, but if I was doing something like this again now I would definitely build on one of these):
http://writingminds.github.io/ffmpeg-android-java/
https://github.com/guardianproject/android-ffmpeg
Using one of the well supported and used libraries will take care of some common issues that you might otherwise encounter - having to load different binaries for different processor types, and some tricky issues with native library reloading to avoid crashes on subsequent invocations of the wrapper.
Because this approach uses the standard ffmpeg cmd line syntax for commands it also means you should be able to search and find help easily on multiple different operations (as anyone using ffmpeg in 'normal' model will use the same syntax for the ffmpeg command itself).
I want to use some function calls(commands) designed for linux. I can use them by enter the key words in adb(Android CML).
Here I found some works some people did.
wget (because it isn't included in most Android device )
Iperf
But after reading their methods or suggestions, I can only understand that I need to use Android NDK and write the correct makefile. I have no idea about building others source code (most of them are C/C++) for linux(only need to use 'make' command mentioned in their README file). The official NDK document is for Java environment to call C lib mainly.
Are there some HOWTO, courses or suggestions for this. Thanks!
I have compiled single cpp file program. I try to compile a alternative version iperf
https://github.com/tierney/iperf
It seems to be relative to lib ,some header files, and multiple c files. I failed to compile by enter all c files normally. Is there anything I missed?
yeah you need the NDK, it offers an C/C++ compiler for Android.
In general the steps are all the same:
Setting up the NDK (I wrote a small how-to, but it's for Arch-Linux and the fish-shell, Windows how-to)
Adjusting your make file (instead of gcc compiler use Android NDK compiler, and so on)
Remember that Android uses Bionic C library, so only use functions supported by it
Run make, push the program to your device and make it executable
Of course, this is just an overview how it is done. You should try it and then ask specific questions if you run into troubles.
NDK is mostly intended to extend the Java apps, but you can download NDK and create a standalone toolchain from it (see http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html). Now you have a cross-compilation environment which is very similar to standard Linux dev environment.
In addition, for small executables and for testing only, you can also cross-compile and link statically to the libc. This way you don't have to worry about Bionic which could be a loss of time.
I've got a hold of a proprietary JNI application which I need to build for a MIPS device. I've read "Initializing a Build Environment", parts of the NDK docs, some Google Groups threads and numerous StackOverflow questions, but I'm still short of my answer.
So far, I've checked out the Android source using Google's repo script and have it under ~/AndroidSource. I've also separately downloaded the SDK under ~/AndroidSDK and the NDK under ~/AndroidNDK. The code I'm trying to build is in a separate location. The SDK and NDK binaries are in my path. For building, I tried to use two different versions of the NDK as well as the one under the Android source tree, and experienced different sets of problems. My current setup uses NDK r8b, downloaded separately from the Android source.
The application has its Android.mk and jni/Android.mk. However, several directives in the latter point to paths such as
frameworks/base/include
system/core/include
with no prefixes. I thought these were meant to point to the respective directories in the Android source, so I symlinked them to the current directory. After some more symlinking and makefile and source hacking, I got the application to compile, but am currently stuck on the linking phase with lots of references to missing method bodies. During the whole time I knew I was doing something wrong.
I'm on a Linux x86_64 host, if it is of any concern.
So my question is:
What is the proper method to set up a build environment for JNI applications? What environment variables, symlinks and/or path expansions should I set up? Do I need to call any scripts once or before each ndk-build invocation?
Also, I'd be happy if you corrected me on any concepts or terminology I've gotten wrong.
Your approach wiyh symlinking the AOSP tree for system headers is correct. What you need now are the system libraries compiled for MIPS. The easiest way to get them is to adb pull them from a target device (or emulator image). But you can also build these libraries yourself, as part of the AOSP build (see build instructions for the source tree you downloaded).
If you still have any problems remaining, run your ndk-build with parameter V=1 and publish the link command and its results.
I use the following in my build (YMMV).
Explicitly invoke arm-linux-androideabi-gcc as your compiler or linker (should be in PATH).
NDK_PLATFORM=/path/to/android-ndk-r*/platforms/android-14
Pass -I"$(NDK_PLATFORM)/arch-arm/usr/include" to the compiler
Pass -nostdlib -L"$(NDK_PLATFORM)/arch-arm/usr/lib/" -lgcc -lc -lm to the linker
Can somebody help me write Android.mk for LibXtract or point me in correct directoin?
Here is source for lib - https://github.com/jamiebullock/LibXtract.git
Or mayby there is a way to use linux generated shared objects in Android?
Especially for bigger established projects, crafting Android.mk files is quite an effort. More so, if you are not familiar with Android NDK build architecture whose understanding requires digging deep into the documentation and Android NDK make files. I would suggest trying to use existing make files by setting CC to point to your NDK tool chain, and CFLAGS += -sysroot $(SYSROOT) where SYSROOT=${NDK_INSTALL_DIR}/platforms/android-<level>/arch-<arch>/ (depending on targeted Android API version and architecture). Even without knowing about your library, I would bet you should have good chance of success this way. Android NDK documentation (${NDK_INSTALL_DIR}/doc/STANDALONE-TOOLCHAIN.html) details the use of independent tool chain and also instructs how to create a standalone tool chain that will not require the use of -sysroot argument to xxx-gcc.
If you decide to use Android.mk instead, you might check existing projects -CSipSimple comes to my mind (PJSIP converted from standard form GNU make files).
Important is to create the shared objects using Android tool chains. It is possible to build them outside of your application source tree, and then just copy the shared objects into the package source libs/<architecture>/ directory.
Integration with your build system depends on details that are not known (including how smooth you desire this whole integration to be e.g. because of other people working with the same project). If you are creating an application from command line, the easiest would be to have GNU make file or shell script in the package root directory ensure libXtract.so and your application package is up-to-date by calling libXtract make file and ant to build and pack your Java application. If you are using ant there should be a way to specify using make to take care of libXtract.so. I am not sure if eclipse is completely relying on ant for building an application to know if this would be enough for enabling complete build by clicking mouse buttons from within eclipse, too.
The answer to this question says you could use cmake script to build Android.mk files - I have not tried this approach.