I've been searching technical books and articles to find out more about writing programs for Android using the native development toolkit (NDK) and C/C++. Finding relevant information is extremely difficult. Most sources just say to use Android Studio (or for older articles, use Eclipse) and do not go into any details as to how things work beyond the IDE or wrapper script. It's extremely difficult to find documentation that explains what's going on underneath.
I'm working on porting some Open Source projects already written in C/C++ to Android. So, I find it extremely frustrating when the typical advice I read is to avoid the NDK and use Java (or Kotlin). References that state that usually go on to say that Java (or Kotlin) really is not that much slower than C/C++, so you would be getting no significant gain in performance by using it. That leads me to believe that there has to be some gain in performance (even if it is not what the authors deem 'significant') or the articles wouldn't be mentioning that C/C++ was considered faster in the first place. Such articles typically go on to state that it's much harder to work with the NDK and one is better off using languages recommended by Google. However, for developers who prefer C/C++ over Java or Kotlin development and who are already aware of potential pitfalls of the C/C++ languages and how best to avoid them, those developers could be far more proficient and productive using C/C++ over other options. So, why recommend avoiding the NDK and C/C++? Why not encourage developers to use the languages and tools they can leverage to their best advantage?
Speaking of using tools that developers are most productive with, I already have a cross-platform build system that greatly reduces the time I spend building and porting Open Source libraries. I wanted to be able to use my build system. However, IDEs (like Android Studio) don't integrate well with automated build systems. It took a lot of digging through articles and books on Android, but I was pleased to find out how to create a standalone tool chain to build Android C/C++ applications.
I was surprised at the lack of support for cross-platform compiling of certain Open Source libraries. It's difficult to find Android builds and patches to common Open Source libraries. Also, based on my experiences porting Open Source projects to Windows, I wonder how many Open Source library developers would welcome adding patches to make builds of their libraries for Android work out of the box. My past experience has proved that many library developers would prefer not to add support for more platforms. That means I'll probably end up adding my patches to my LM BLD scripts (
http://www.distasis.com/cpp/lmbld.htm ) rather than seeing the fixes I've submitted added in to the libraries themselves.
So, as I work my way through porting various Open Source applications to Android, I thought I'd share the few useful resources I found that help clarify how to build and share C/C++ Open Source applications on Android.
The best documentation I've located to date and the one I'd refer anyone interested in C/C++ programming for Android to is this one:
http://www.hanshq.net/command-line-android.htmlIt explains where to get the NDK and other needed libraries. It walks you through how to create an Android package (apk file) via the command line. It gives a good example of how to build a C application that can get a developer started.
If you're on a Linux system, you can use the package manager to download a version of Java. You'll need it to create Android packages. For Windows users, one option is to download a portable version of Java and make sure it's in your development path.
https://portableapps.com/apps/utilities/jdkportableThe Android developer web site actually has some decent information on how to create a stand-alone C/C++ toolchain. You currently need Python to create the toolchain, but they actually supply a version of Python for operating systems that don't easily offer one.
https://developer.android.com/ndk/guides/standalone_toolchain.html#selecting_your_toolchainSee also:
https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.htmlhttp://mobilepearls.com/labs/native-android-api/ndk/docs/STANDALONE-TOOLCHAIN.htmlWhen creating the stand-alone toolchain, you'll need to know what API you're targeting. More information on that is provided elsewhere:
https://source.android.com/setup/build-numbersTypical choices are to target the latest if you want to use all the newest features in Android or target an early enough version that the results will work on a majority of the Android devices out there. Which version is best will change over time as the majority of users buy newer devices and new innovations are added to newer APIs. Even though you mention the API when creating the standalone toolchain, the only place the information seems to be stored is in the llvm wrapper. So, you may need to add -D__ANDROID_API__ and the API you want to support to your compiler flags.
You'll also need to decide whether you want to target 32 or 64 bit platforms. Keep in mind that 32 bit code will work on 64 bit platforms, but the reverse is not true. There seems to be better support for large file access on 64 bit platforms though. Note that Google is pushing for latest API targets and 64 bit support for projects that will submitted to the Google Play Store. You'll need to build your application for each target you wish to support. So, if you want your programs to work on Android devices with arm chips or x86 based chips, you'll need to build libraries and applications for more than one system.
Google is also moving toward unified headers so they don't have to support a version of the C and C++ header files for each API they support. Depending on what version of the NDK you're using, you may want to add --unified-headers when creating your standalone toolchain.
I find it useful to know what native C/C++ functionality/which libraries are supported for various versions/APIs of Android:
https://developer.android.com/ndk/guides/stable_apisI thought this site had a good series of posts on how to port a SDL based application to Android:
http://blog.stuff-o-matic.com/post/2013/10/20/ASGP-s-Android-Port-Part-IV%3A-building-the-APKIf you're interested in using dynamic libraries, this site had some useful information:
https://www.andriydruk.com/post/introduction-to-c-for-android-developers/Testing the results you built may be difficult. My experience with using MoSync to build C/C++ Android applications showed how slow testing an application with an emulator could be. If you install Android Studio, it gives the option to install Intel HAXM (hardware accelerated execution manager). This can help speed up Android emulation. You can find HAXM and more information on it at the Intel web site.
You can also use VirtualBox and an Android virtual machine image for testing.
Android-X86 (
http://www.android-x86.org/ ) can provide images that work with targets compiled for x86 machines.
Another option is to use adb (Android Debug Bridge) to test the results on an actual Android device. Now that Windows Subsystem for Android is available, you can also us it to run Android apps and use adb to side load the applications you want to test. Here are a couple of articles that give examples of how to work with adb:
http://nickdesaulniers.github.io/blog/2016/07/01/android-cli/http://codeblog.vurdalakov.net/2016/12/build-and-run-native-c-cpp-android-apps-with-ndk.htmlOne thing to keep in mind if you're going to test on your own Android device is that Developer options must be activated on that device first. Here's an article on how to do that:
https://www.embarcadero.com/starthere/xe7/mobdevsetup/android/en/enabling_usb_debugging_on_an_android_device.htmlYou can also build or access Open Source console applications (even without turning on developer options) when you have a terminal emulator app installed on your system. This gives applications you're running in the terminal emulator (even one's you've built from source) the same rights at the terminal emulator. You can use command line or console based applications (such as those built with pdcurses/ncurses/netbsd-curses) with a terminal emulator. There are several terminal emulators available from the Google Play Store or F-Droid. Try some out and see which you like best.
One of the terminal emulator projects has a github project with information on some common Open Source library packages including commands for building and patches needed to compile. One thing to watch out for is that some of their patches are made directly to the standalone toolchain header files. If you don't have similar patches or add extra patches to the library's build script, you may not be able to compile successfully. One of these fixes is to help work-around 64 bit file handling support on 32 bit systems. Some Open Source projects don't build properly or need major work-arounds to handle this with earlier versions of the Android API for 32 bit systems. More information on how the Termux terminal emulator project builds their Open Source libraries and programs is available at their github site:
https://github.com/termux/termux-packages/tree/master/packagesAnother interesting resource if you want to see how various C/C++ projects are built and what patching might be needed is this one:
https://github.com/pelya/commandergeniusIt uses SDL 1.2/1.3 ported to Android and includes several Open Source libraries and several popular Open Source applications including DOSBox, Milkytracker, grafx2 and a SDL based X server.
A developer I correspond with wrote his own tutorial on how to build C/C++ applications using Allegro and Nano-X. He covers a lot of useful material about the NDK and C/C++ development including how to call Java functions from C/C++ and vice versa. He also explains how to use Allegro on Android.
https://wiki.allegro.cc/index.php?title=Running_Allegro_applications_on_AndroidLibraries such as SDL, Allegro and Nano-X provide support for building GUI applications on Android. Nano-X offers a subset of X11 functions so GUIs like FLTK and WxWidgets will work. PDCurses can be used in conjunction with SDL. Applications built using any of these libraries could potentially be ported to Android. Not all C/C++ applications provide interfaces that are user friendly for Android or for smaller screens and devices that may lack physical keyboards. However, if you create a well designed, portable interface for your program, there's no reason why it shouldn't work well on Android systems as well as PCs (Linux, Windows, BSD, etc.). Here's more information on some GUI libraries that work on Android:
https://github.com/georgp24/microwindows-android-binhttps://wiki.libsdl.org/Androidhttp://liballeg.org/readme.htmlMore recently, I ran across Android Apps in C. It uses Android Studio which is a lot of overhead if you just want to build an application. Also seems to use WSL on Windows instead of direct development on Windows. Seems to use the standard android_native_app_glue code. However, there may be other tips and tricks that are useful when creating a C/C++ application for Android. The project is at:
https://github.com/cnlohr/rawdrawandroidThat's pretty much all my searches have turned up as far as resources I've found useful for building C/C++ applications targeted to Android devices. If you have other reference recommendations that explain how things actually work (rather than glossing over the details and using a GUI interface), please let me know. If you'd like to share or compare notes on patches, compiler/linker options for building various Open Source libraries and applications, I'd enjoy hearing from you. You can discuss C/C++ Android development further with me and other interested developers on the
CppDesign mailing list.