Crosscompiling a large C++ project for ARM/Android - issues and considerations - android

In our team we have a C++ project built on OpenCV and VLFeat written by a colleague who has just left.
I have been asked to cross-compile it for Nexus 4 (ARM), run it and profile it (gprof).
Hence, it is not necessary to pass through the Java wrappers and the NDK: no app is requested.
I am having big troubles with that because I am a complete novice in crosscompilation: all the guides and tutorial I find advice to use the NDK. For example, this book very nicely explain how to setup the whole system (using the NVIDIA Tegra development kit that bundles the Android SDK, NDK, Eclipse and OpenCV)
Do you think that crosscompiling such a big project with so many dependencies on arm it is a viable option? I am also concerned that, even in the case in which I will manage to cross-compile, the code won't work.
If yes, can you kindly point me to some resources which explain me how to do it (besides the OpenCV instructions, which have been not particularly useful)?
If no, I would really appreciate if somebody with more experience than me in the argument could debate the reasons why it is much better to use the NDK.
------------- EDIT ------------
For sake of completeness, I report my progresses.
I managed to cross-compile OpenCV for ARM, generating static libraries. I have also successfully crosscompiled VLFeat.
Now, it happens what I was afraid of: make throws up a huge list of undefined references. I have pasted the head of the &> output in this pastebin.
Any consideration? I am almost seriously convinced that a rough cross-compiling will never work, and it is better to re-do the entire project passing from the NDK. Obviously, I hope that somebody could contradict me.
Thanks in advance for your help, I do not know which way to turn.

You can just use NDK compilers and regular makefiles without using the NDKs build scripts. There is script that makes NDK compiler behave more like a regular GCC right here https://code.google.com/p/android-cruft/. The script was last updated 4 years ago, so it might need further facelift.
The biggest problem you might face is incompatibility in the C library or missing support for advanced C++ features. The Android is somewhat Frankenstein system, it uses linux as a kernel, but BSD like C library. Many low level utilities do not compile well for such environment. Also, a lot of C++ features depend on libg++ library which might have strong tie-ins into GNU C library.

I had a look at your pastebin. The first thing that stands out is libjpeg, or lack thereof. I don't know how your link step did not involve -ljpeg. You also need some pthread - related stuff. Note that Android supports almost all pthread APIs, including pthread_mutex_init(), but does not have libpthread; instead, all these functions are defined in libc. Maybe, other libraries are missing, too.

We're building a big app, including OpenCV, boost, libjpeg-turbo... For all this we use CMake to generate Makefiles that use the NDK.
Looking at your linking errors, it seems you're missing some libraries in your link command line. -ljpeg probably. For pthread, I'll have a look at how we handle it at work.

Related

Linking 3rd Party Libraries with VS Cross-Platform C++ Mobile App Project

I need some general guidance regarding the correct way to link either static or dynamic libraries in a Visual Studio Cross-Platform C++ Mobile App project.
Specifically, I'm trying to link my project with a libpng build, but I doubt this is specific to that library.
I have built libpng (and zlib) successfully. The Universal Windows App project in the solution runs and uses the libpng API just fine. The Android project, however, is giving me undefined reference errors to the libpng functions and very high blood pressure.
The various libpng types defined in headers are not causing errors, only the function definitions. I'm also fairly sure the compiler(s)/linker can find the files in the first place, since when I remove references to them from the project options, I get file not found errors instead of undefined references. I have little experience with Clang or GCC, and have never attempted to build with them from Visual Studio before.
I have already examined this SO question, but the accepted answer actually contains misinformation. I've also seen this other SO question, which seems to describe the same problem, but that question is concerned with Eclipse; its solution involves makefiles, which isn't applicable in my case.
I have tried every permutation I could come up with modifying various project settings in both the native activity and static library projects: adding various directories to project settings, forward-slashes-vs-backslashes, manually specifying -l commands on the command line to ensure the link order was correct, all for naught.
Clearly, I'm missing something (probably basic) to getting Clang or GCC to link with a third-party library in a Visual Studio project. I appreciate any thoughts anyone might offer me. Thank you.
Instead of banging my head on this any longer, I decided to build the libraries myself within the solution rather than link to them externally. (The provided Visual Studio templates make it trivial to drop in existing and have it work across all your projects right out of the box.)
This is less of an answer then an alternate solution, but it was the route I ended up taking, and in the end I think it was perhaps the better choice. (To state the obvious, if I end up needing those libraries for multiple projects, then this isn't the most efficient approach. But for now it wasn't worth the headache for me.)
Should anyone ever come across this question in the future and have an answer I would still very much appreciate hearing their input!

_GLIBCXX_USE_C99 is not defined, to_wstring not available

I've run into a very serious (IMO) problem. I am using the native cross platform tools in visual studio 2015.
Since several implementations of the standard library were downloaded by visual studio
C:\ProgramData\Microsoft\AndroidNDK\android-ndk-r10e\sources\cxx-stl\
I was surprised when I started finding stl classes that were not compiling.
I wrote off std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> not being available as a quirk of gnu-libstdc++.
I tried to set the stl to others to see if they were better. This was done in the visual studio project properties window.
No combination of toolset or STL made std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> available.
I moved on, saying "If I have to implement that one function myself it's not the end of the world."
However shortly afterward I tried to use to_wstring. Again the function was not recognized even though wstring was.
This was a step too far so I checked to see if gnu-libstdc++ had in fact implemented anything at all. In fact they had, see 21.5 of the standard is Y.
I was very confused now. I did some googling and found nothing more substantial than "set it to c++ 11."
Unless Visual Studio isn't doing anything with the following setting I assume GCC is being called correctly.
Eventually I opened up basic_string.h in visual studio to make sure that the function was actually there.
It was, line 3000:
inline wstring
to_wstring(int __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(int), L"%d", __val); }
Then I saw by the shading that it was being omitted by the preprocessor. Behold line 2847:
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
The problem was not __cplusplus nor _GLIBCXX_HAVE_BROKEN_VSWPRINTF. _GLIBCXX_USE_C99 was not defined.
Searching for this problem yielded a couple of stack overflow questions.
Most of the comments seemed to think the problem would be fixed with a new release of GCC. For instance GCC 4.4.5. However since visual studio downloaded 4.9... I don't think this is merely a problem with versions.
I followed the link there to a three year old bug report which contained the statement:
It's not possible to fix in GCC without extraordinary effort for a
single target, which is not going to happen. If a given target wants
to support C++11 features then it needs to provide the necessary C99
features. This is not a GCC issue.
Well, in visual studio I had set the C standard to C99, for the record C11 didn't make any difference.
I am really not sure how to proceed from here. It seems to me that somehow Visual Studio is not communicating to GCC what is or is not available. That is just a theory though.
I am opposed to trying to manually change a distribution on the stl. That defeats the purpose of a stl. At the same time this project I am undertaking may well be impossible without the standard library (given the time constraints). I am afraid to continue lest I find more critical functionality hidden due to lack of C library functions.
I have this insane hope that there is something I could change in visual studio, some setting or command line override that would fix this.
P.S. I have looked into developing the android part in eclipse or android studio. The NDK documentation mentions eclipse often, but the android SDK has scary messages about the ADT no longer being supported. On top of that I had issues out of the box debugging the native code (but those are beyond the scope). The android studio build system (gradle) doesn't seem friendly to custom folder structures in the least. All of our source is in TFS and I can't change that at this point.
This is known problem of Google's Android NDK - C++ Standard Library is broken there, unless you're using just small subset of C++ functionality. Macro _GLIBCXX_USE_C99 is defined (or not defined) in $NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ABI/include/bits/c++config.h at the moment when GNU libstdc++ is building (i.e. on Google's side, when they build NDK). Unfortunately, it's built on top of very limited libc (Google's Bionic), so GNU libstdc++ configuration scripts detect it and disable some parts (in particular, std::to_wstring), depending on that absent functionality in libc.
This is one of the main reason why I've started CrystaX NDK - alternative native development kit for Android. In CrystaX NDK, we pay special attention to completeness of libc, libstdc++, and conformance to standards in general. CrystaX NDK works as a drop-in replacement for Google's Android NDK, so most likely it will just work with Visual Studio too.

Profiling android-ndk plain C/C++ executable

What is the best way to profile plain C/C++ android executables on a rooted android device?
android-ndk-profiler seems to support only ndk libraries linked to Java.
Any suggestions?
Thanks
I was faced with the same question recently. After looking into several alternatives I decided the best option (the one I made to work, at any rate) was to build Valgrind for Android.
This page describes how to build Valgrind for Android. See also my GitHub project for a slightly different build procedure, usage notes and prebuilt Android ARMv7 binaries.
Android NDK profiler work by GCC compiler trick so should work independent
of JNI
This link has the details
http://code.google.com/p/android-ndk-profiler/wiki/HowItWorks
As long as you can insert the startup and cleanup code into your C/C++ code it should work
You can find all the information you will need here
http://code.google.com/p/android-ndk-profiler/

Can a library built in standard Linux be used in Android?

I wrote a library in latest Linux distribution, which depends on glibc and sockets. I hear that glibc is not supported in Android. Is there a way that I rebuild my code without much modification for Android and let it run? If yes, I will use JNI to call the code.
No, that's not possible. Android runs with bionic, and doesn't have glibc.
However you can try to build your code with NDK and fix the problems on the way to build it.
If you don't use anything glibc specific, it should be fairly easy.
It depends on what you mean by "uses glibc". If it uses non-standard extensions that only glibc implements, then you'll have some trouble. But Android's libc (called "bionic") supports most of POSIX, so if you aren't doing anything too unusual, it should work. The best way to find out is to try to build your library with the NDK and see what happens.

how to port Snort on Android OS

Is there a way to port Snort to Android OS? I have already ported
libpcap to Android and I have made some simple native sniffers which worked
perfectly.To do this, I used the NDK development kit that offers you some
tools for cross compiling C programs to ARM architecture.
Is this possible to do it for Snort. I know that Snort is a big project that
contains many source files and uses many modules such as Libpcap, PCRE,
Libdnet, Barnyard2, DAQ. I am wondering if is there a way to build
this code for Android.. E.g. by statically link all this modules.. Moreover an
other potential problem may be the fact that Android uses a subset of libc
(bionic), so maybe some basic functions are not available..
Have anyone done it before? Or, can some one give me some help on how
to start?
Lack of exception handling and STL was very painful when i ported using NDK. As snort is C based, that shouldn't be the case. I guess unicode handling (as ndk doesnt support wide char functionality) can get tricky.

Categories

Resources