[CMake] CMake integration in Gradle (Android Studio)

Eric Wing ewmailing at gmail.com
Mon Oct 31 14:39:15 EDT 2016


So I have been using (a custom) CMake + Android Studio/Gradle for some
years now. I only recently saw that both official CMake is adding
Android support, and that the official Android tools are supporting
CMake. I’m actually still confused on the differences between the two
and what each offers in terms of features.

My custom/jury-rigged CMake is derived from the OpenCV Android
toolchain which has forked around for many years. Currently, I have a
combination of custom shell scripts + modified toolchain + modified
CMake to make things work.


My cross-platform requirements have been:

- Must generate be able to generate a new Android Studio/Gradle
project, like how Xcode, Visual Studio, etc. are generated.

- Must handle multiple Android architectures (armv5, armv7, x86, arm64, x86_64)

- Must be able to handle both the native code stuff, and the annoying
Android specific Java code in order to build a complete/working
Android application that can be installed/run through the normal
Android Studio/Gradle user interface.

- Should work on Mac, Linux, and Android



The way it currently works is:

- I have a front end scripts you must run which ultimately invoke
cmake -G “Unix Makefiles” for the Android NDK. These scripts feed my
android toolchain as well as provide the locations to the Android NDK
and SDK. Also, these scripts will generate Gradle and Android Studio
projects. (I basically brute force stripped down a real Gradle/Studio
project and figured out what values I need to inject into it to use as
a template. Many of the injected values are provided from CMake
variables I define in my project CMakeLists.txt)

- The Gradle/Studio project generated has a custom Groovy script phase
that when building, invokes an external shell script as part of the
build process. This external script ultimately calls CMake to build
the native components of the project.

- Because CMake doesn’t handle multiple architectures for Android, my
script actually generates multiple CMake projects, one for each
architecture, separated into directory structures that try to mimic
the official names of the different Android architectures. (This is
kind of brute force, and is not currently easy to opt-out of different
architectures.)

- At the end of the script phase, I use a CMake “install” to copy the
build products for each architecture to the correct location in the
Gradle/Studio Java layout, so the Java part of the build will continue
on doing the right thing.

- The rest of the Gradle/Studio build will continue on and build the
Android Java parts of the project. (I have a specific convention for
where the Android/Java files go in my project structure. Unlike the
annoying thing that Google forced us to do with ndk-build, the Java
stuff is no longer at the root of the source tree, but parked in a
special Android subdirectory. The former was a stupid/evil requirement
for every pre-existing cross-platform project out there, and an
arrogant presumption for new projects, so I did away with it.)



Here are a few videos that show the workflow (in my SDK called Blurrr)

"Workflow" in Swift: The Android Addendum (shows just the Android part)
https://www.youtube.com/watch?v=w6FY_qSi8yY


Workflow": Cross-platform Dev in Swift
(This shows the same project as above, but for the non-Android
platforms, showing it is indeed a single, unified CMake project that
can drive Linux, OS X, iOS, Windows, and Raspberry Pi (and Android).
https://www.youtube.com/watch?v=w8ftI9mpGdY


Blurrr Introduction Part 3 (Shows the different build platforms in a
little more detail. This video is the oldest, so things have improved
a bit.)
https://www.youtube.com/watch?v=exPtM-02YRY



So my wish list for the new CMake versions is that is handles all of
this. (Multi-arch and Gradle/Studio generation especially.)

I have not yet investigated how hard it will be to migrate to one of
the two other versions of CMake. Since Swift is one of my supported
languages, this currently requires me to use a forked CMake I’ve been
working on. However, I am happy to work with people who want to try to
integrate some of my features directly into CMake if they are still
missing (such as the Gradle/Studio generation).

Thanks,
Eric


More information about the CMake mailing list