As far as I know one can can write apps on Android and iOS in C/C++, instead of Java and Objective-C.
Since both C and C++ rely upon their Standard Libraries, where and how the C/C++ Standard Library is implemented in such OSes? Is it part of something bigger like e.g. the Android NDK? If it isn't, can I use a different implementation if needed?
There are several concepts at play here, I'm going to try to keep it brief. Android uses Bionic as its C library. It also lists different C++ libraries, however, they recommend you stick with libc++ (Clang) since they have stopped supporting libstdc++ (what they call gnustl) and STLPort is ancient. Now even though they call libstdc++ the system runtime, for libstdc++ in particular, the support library is called actually libsupc++. In order to have exception and RTTI support, you need to implement/build this, which doesn't seem to be the case for Android.
For Apple, it's a different story. XCode is the IDE (not the compiler!) On old versions of Mac, they shipped an ancient version of GCC. There was a transition period where they used llvm-gcc and symlinked gcc to clang. Now the latest version of XCode only supports LLVM/Clang. By default, Mac uses libc++, but you can select libstdc++ if you prefer. Keep in mind that although Clang tries to be as ABI-compatible with GCC as possible, it's probably not wise to mix libraries compiled by libc++/libstdc++.
Can you use a different C library in your toolchain? Not easily. You would need to port the C library of choice (i.e, Newlib) to the platform which is not trivial. Further, you would need to build a cross compiler toolchain that not only targets that system but also uses the new library. You will have to look into people who have already done this for you.
Now even if it was easy, there really isn't a good reason to. More often than not you only want to swap out selective parts of the library, like malloc. Android in particular can use jemalloc for example.
Related
I'm starting my first piece of Android programming, porting some libraries written in C and C++ to Android. I am not building an app, except for testing the libraries: the product is the libraries, which will be supplied to my customers. The libraries are mathematical modelling, running on the device, and have no web or cloud interfaces: customers who want to run them in the cloud already do that, using the Linux or Windows builds.
My initial customer is using NDK 14b. I could use that, or I could use the latest NDK, 16b. If I compile C code with NDK 16b, a compatible instruction set and the same C++ run-time and target API version as my customer, will they be able to use static libraries that I've built in their NDK 14b app?
The other way around is also interesting: if I use NDK 14b, and another customer comes along who uses NDK 16b, will static libraries I've built with 14b work in their 16b-built app? I'd be targeting an equal or earlier API to them, and the same instruction set and C++ run-time.
Addendum, much later: Building .so libraries turned out to be so easy that I've never used anything else.
You kindof cannot target the same C++ runtime when you use a different NDK release. The STL versions do not change too much, but there is no contract of their stability.
Except from this remark, static lib from NDK r16 will cooperate correctly with r14 and vice versa, but the bigger the gap is, the more glitches you should expect to handle.
In general, NDK improvements involve bug fixing, so there is an incentive to use the latest release. But major progress is done in support of newer platform versions. This means that if your library will be linked into an app that targets Lollipop, the advantages of r16 will be less prominent.
Note that if you can ship your library as a linked shared library (so), your interdependency with the host app will be significantly less, and in my experience this improves stability and reduces clashes. If that is relevant, this way is also more secure.
I built a library(.so) that is being called from JNI code in some android app. The JNI code is built using NDK.
If I build the library using android tool-chain, the library works well when called from JNI code.
If I build the library using another tool-chain (used on the same ARM device for none android applications), the library crashes when called from JNI code.
why do we need to use android tool-chain (or NDK) for compiling c/c++ code running in the context of an android app? why not use other tool-chains?
You can use other toolchains, but it requires special care.
Maybe a good starter would be to learn the UBERTC and Linaro Wiki.
The main difference is that NDK compilers are tuned for bionic (Android variant of C runtime libraries). Originally, bionic was a modest subset of Linux runtime. On latest platforms, most of the gap is closed, but now there are many extensions that you probably need.
Also, Android dynamic linker may require (depending on target platform) a set of ELF flags that are automatically delivered by NDK binutils, like PIC, id, and others.
It is quite possible to use arm-linux toolchain to build a statically linked executable that will run on Android, but for a library that must play well on the JNI environment the effort is probably not worth it.
Note that NDK provides tools to create a standalone toolchain, which behaves very similar to other toolchains you may be familiar with. This approach makes it easy to adopt 3rd-party libraries with sophisticated build scripts.
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.
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.
Since Objective-C exists and is supported even in MinGW, by passing -x objective-c, is there a hack to achieve this with Android SDK? I've did a rudimentary test on a colleague's machine where it appears that language objective-cis not supported.
I am not interested in getting UIKit or AppKit, or even Foundation, to work; I've written most of an OpenGLES game in Objective-C, and successfully ported it to Mac OS X and Windows; I am fairly certain I could easily port it to GNU/Linux once I get time to figure out enough of GNUStep (and even without it, I could create the classes to get the game running).
I'm just interested in the base language and basic runtime (including properties, if possible); even NSObject can be easily written to the extent I need it.
In the meantime, I've managed to compile some Objective-C code, and have written a guide for this:
Developing Objective-C apps for Android using Mac OS X
There are more details in my answer below.
The Apportable platform includes a Clang compiler integration with the Android NDK. It also includes a bunch of other useful features if you want to go beyond basic Objective-C language and runtime support.
You probably have to recompile the ndk gcc's sources with that option enabled. At the extreme you might have to find the code for that option upstream and add it to the ndk gcc's sources.
Porting runtime libraries to work on top of bionic instead of glibc may be more interesting.
Note that android doesn't really handle pure-native binaries very well, you will need to either be called as a jni library from a java wrapper application which you will have to call back up through for audio or forked and exec'd off of one (not recommended, and leaving you with device-dependent hacks for audio).
There is this Google Code project: http://code.google.com/p/android-gcc-objc2-0/ however I have not tested it yet.
Also, I have inquired on the Cocotron mailing list whether or not this compiler is usable with Cocotron's Foundation and CoreFoundation; one person responded that it is not, and that he has worked on the problem: http://groups.google.com/group/cocotron-dev/browse_thread/thread/448355f2a6c9c28e#
In the meantime, I've managed to compile some Objective-C code, and have written a guide for this:
* Developing Objective-C apps for Android using Mac OS X
Clang is included in NDK nowadays if that's all you need.