[cmake-developers] [Generator] Android.mk
ewmailing at gmail.com
Fri Jan 10 16:19:56 EST 2014
On 1/10/14, Stephen Kelly <steveire at gmail.com> wrote:
> Vince Harron wrote:
>> Android.mk files allow you to target multiple processor
>> architectures/variants in one make invocation without any reconfiguring
>> multiple build folders. All of those binaries are embedded into one
>> apk file that will run on any supported Android device.
> Sounds interesting.
>> I've just started playing with it like this as my Android.cmake
>> But it's critical to have Android as a separate CMAKE_SYSTEM_NAME because
>> there are many differences that you might want to switch on.
> Indeed. Disabling SONAME is another apparently:
>>> Why does that link also say that Android.mk files are only for creating
>> shared and static libraries? Am I missing something here?
>> All Android applications start life as Java processes. A java process
>> load a native shared library and invoke code within it. To emit a C/C++
>> executable on Android is the same as to emit a shared library, but linked
>> to something called the native_app_glue module.
> Interesting. What is the entry point?
> I don't decide whether such a generator gets in or not, but I don't see why
> it would not be accepted.
I agree that we should have a “native” Android NDK build generator.
There are some things that are harder to do outside the native build
process (some which have already been identified in this thread)
- Multiple architecture support (armeabi, armeabi-v7a, x86, mips).
Though these aren’t “fat” binaries in the NeXT/Apple model. They
merely introduce an extra subdirectory layer of indirection and place
each binary in the properly named folder. However, since the Android
model knows how to handle this, it would be very nice to have (because
my current workaround is to invoke CMake for each architecture and
then glue everything with my own post build scripts written in bash or
- I’m not sure if this is the SONAME example mentioned, but Android
can’t handle the .so version numbering scheme where version numbers
are put in the file name and symlinks are used to point a version-less
file to a specific version. The NDK design is to use Java’s
System.loadLibrary to load NDK modules, and it turns out that
loadLibrary can’t handle symlinks.
- gdb debugging does some voodoo that is technically open, but not
really well documented or fully understood. I’ve some people try to
recreate it and document it for external tools like CMake, but it’s
work. The native system generally sets this up for you. (Though I have
a lot of problems getting regular Android stuff to ‘just work’.)
However, as a counterpoint, I will say that the NDK is a
broken/incomplete piece of $%#!, and in most respects, CMake’s generic
makefile system is vastly better. So I would actually like to see
CMake’s generic generator extended for Android.
- For example, did you know that compiling for size (-Os) is not
supported by the NDK? This is the stupid platform that limits you to
50MB .apk’s. What the $%$ are they thinking? I have the misfortune of
verify it), the time involved has been measured in weeks spanning
months. Currently I’m trying to shrink the binaries because JSCore is
huge. Currently, the smallest I can get each architecture is about
30MB each. I’m building with CMake, so I can at least get access to
the -Os flags and actually control many build flags the NDK won’t let
me access. I would be totally screwed without this.
- Android introduced -mhard-float for processors that support it.
However, one serious problem is that you can’t use that on any code
that touches/crosses the Java JNI layer (because I think the Java VM
doesn’t expect arguments to be in float registers). Since Android
forces you to always go through Java, you always have to cross the JNI
layer somewhere. So, the obvious workaround is to specify CFLAGS per
file. But this is not possible with the native NDK build system. (I
haven’t checked r9c yet, which just came out.)
- Google hasn’t answered the question about how the NDK is going to
work with their switch to Gradle and IntelliJ. Honestly, Google has a
terrible track record with the NDK and I trust CMake a lot more than I
trust Google. (There's another story about Gyp lurking in here in
prior attempts to build JSCore before my involvement.)
This all said, I’ve forked the Android-CMake cross-compiler chain
(originally developed by the OpenCV people I believe) to keep it going
for the latest NDKs. I haven’t had much success with the direct
toolchain, but I have been very successful with the standalone
toolchain. I would like to rally more support to improve this
toolchain as well and maybe even get it included in some form in the
official CMake distribution. While it works, there are still lots of
pain points like multiple architectures which I already mentioned I
string together with Perl scripts.
That fork an be found here:
I have a good real world case of how all this works. It is good
because it is non-trivial and reflects real world usage, but also not
so complicated (unlike JSCore) where you’ll never figure it out.
This hello world is standard Android app that is written in Java with
JNI APIs that can call into C. The program uses ALmixer (my OpenAL
based audio library). ALmixer uses CMake to build. ALmixer has
dependencies on both Android’s OpenSL ES (provided in the NDK) and
also an Android fork of OpenAL-Soft. What is interesting about
OpenAL-Soft is that it has yet its own build system, so this example
shows how to string 4 different build systems together. (OpenAL-Soft,
ALmixer via Android CMake, the app’s ndk standard build system, and
the standard (though now deprecated because of the Gradle planned
switch) ant build system for the Java stuff. Part of the glue is using
the standard Android NDK external module system in this process.
Anyway, I would like to see CMake support both ways so we developers
can “pick our poison” when dealing with Android. And I welcome any
help improving Android CMake.
Beginning iPhone Games Development
More information about the cmake-developers