I recently developed a project in C which makes use of the function clock_gettime() in linux. The linking for this on my Ubuntu desktop is achieved using the linker flag:
gcc -lrt foo.c
I was excited to read that I could cross-compile my project for the Android in the post below.
http://benno.id.au/blog/2007/11/13/android-native-apps
I've tried this on trivial projects though using the command:
arm-linux-gnueabi-gcc -static foo.c -o foo
Rather than the command:
arm-none-linux-gnueabi-gcc -static foo.c -o foo
referred to in the link, and they do indeed compile and link fine, but when I try with my project requiring clock_gettime() and the linking:
-ltr
It fails with:
undefined reference to `clock_gettime'
I've read that library specified by -lrt doesn't exist for the Android, and I've found posts other places claiming that folks are using clock_gettime() on Android projects, but I haven't been able to find the right library to link to for this. Can anyone tell me what I need to link to for the ARM to make this work?
Or make any other suggestions as to alternatives that will work on the Android.
I am very much interested in leveraging my existing makefiles from my Desktop linux projects to what extent I can, but reconfiguring them to work with the cross-compile tool chain if possible, so any suggestions which would allow for that would be very greatly appreciated.
Android's "bionic" C library has a wrapper for the clock_gettime() syscall. If you build using the Android NDK you'll get that automatically. Otherwise you need to add a bionic library to your toolchain somehow.
Alternatively, you could call the syscall directly via assembly (from memory, the first argument goes in R0, the second in R1, you put the syscall number in R7, issue "SWI $0" and find the result code in R0).
Alternatively: why are you bothering with clock_gettime? Is there any reason you can't simply use gettimeofday()?
Related
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.
I've seen other questions like this, but they don't seem to solve my problem. I am trying to build a C++/Android project on Windows for the first time, and have a few questions:
1) Android NDK docs said cygwin is required, some people on internet say it isn't. I have tried both. But I'm getting many errors in building our project using ndk-build on both cmd.exe and cygwin window. On cygwin it says
*** target pattern contains no '%'. Stop.
I searched that there might be some windows style path there in the make files. Someone said use : $(shell cygpath -u $(path)) instead of $(path) ... It's not helping.
2) Since it's a big project, I wanted to check which all are the places where it's taking a windows style path. But even the simple #echo commands for echoing their values is not working.
#echo $(path)
Some on the internet said we can use this style:
.PHONY: print_vals
print_vals:
<tab>#echo $(path)
but that is not working either. Android NDK development on Windows is difficult :(.
First, Cygwin is not required to run ndk-build on Windows, only to run ndk-gdb, and there is also a python version (ndk-gdb.py) that doesn't require Cygwin anyway.
Second, there must be something weird in your Android.mk file(s). If you don't know how GNU Make works, you should really restrict yourselves to the features described by the NDK documentation (e.g. $NDK/docs/ANDROID-MK.html and $NDK/docs/HOWTO.html)
It's hard to tell exactly why you're seeing this message, but it's very likely because you're using absolute Windows file paths in direct target definitions.
Finally, you cannot use echo to debug Makefiles, use $(info path=$(path)) instead.
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
Im trying to carry out static source code analysis for my android native project written in C/C++ using scan-build.
I tried the instructoins on this page(http://clang.llvm.org/get_started.html#build) for building and running scan-build. All these are done in Ubuntu 10.10, 64bit version.
Since I'm building my project in android source, the compilers used are gcc and g++ located in android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/.
It is said that I can configure scan-build to work with gcc/g++ using --use-c++ and --use-cc options.
But when I run the command: (./run_scanbuild.sh is the build script)
scan-build --use-cc=/home/chulwoo/8655_GB_AU_2_30/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gcc --use-c++=/home/chulwoo/8655_GB_AU_2_30/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-g++ ./run_scanbuild.sh
it says :
scan-build: 'clang' executable not found in '/home/chulwoo/Clang/llvm/tools/clang/tools/scan-build/bin'.
scan-build: Using 'clang' from path: /home/chulwoo/Clang/build/Debug+Asserts/bin//clang
Seems the --use-c++ and --use-cc options are simply ignored.
Does any one know how to make scan-build work with android prebuilt gcc/g++ ?
Or, is it feasible to build my project using Clang in android?
Thanks in advance.
Jin.
Okay ,this was a stupid question.
Just build it with following command, and it surely will generate static-analysis result.
Here lets assume that gcc is used for building.
scan-build gcc ...whatever you wanna give as options...
The scan-build is really a nice tool, hope you guys enjoy it.