How to use Hunter in Android Studio?

CMake can be used as a build tool for native C/C++ libraries in Android Studio. If CMake project has third party dependencies these dependencies can be managed by Hunter.


As an example let’s take a look at simple project with one tiny md5 package dependency. The project is a slight modification of the HelloJni sample.

Examples on GitHub


The code was tested with Android Studio 3.2 version which currently is in beta stage .

Check you have at least CMake 3.9.2. Such requirement needed to work with Android NDK r16+:

> cmake --version

cmake version 3.9.2

CMake suite maintained and supported by Kitware (

Check you have Ninja build tool installed:

> which ninja

You can use your system package manager (e.g. on Ubuntu do sudo apt-get install ninja-build) or download it from GitHub releases, unpack and add to PATH:

Get the sources:

> git clone
> cd android-studio-with-hunter

Android Studio project configuration files resides in android-studio directory but before opening it you have to create file and add cmake.dir entry there.

You may want to add the paths to Android NDK/SDK as well (if ndk.dir and sdk.dir not present in then they will be set by Android Studio to default locations):

[android-studio-with-hunter]> cd android-studio
[android-studio-with-hunter/android-studio]> cat



Since contains information about local machine you should add it to .gitignore.

Please check that cmake.dir has such value that <cmake.dir>/bin/cmake executable exists.

At this moment you can launch Android Studio and open your project but note that Gradle will start configuring, it will trigger CMake configuration which will trigger Hunter builds for 3 architectures:

[android-studio-with-hunter/android-studio]> cat app/build.gradle

android {
    defaultConfig {
        abi {
            enable true

            include 'x86_64', 'armeabi-v7a', 'arm64-v8a'

            universalApk false

As an alternative you are able to build one architecture at a time using -Parch=:

[android-studio-with-hunter/android-studio]> ./gradlew asDebug -Parch=arm64-v8a

> Task :app:externalNativeBuildDebug
Build hello-jni arm64-v8a
[1/2] Building CXX object CMakeFiles/hello-jni.dir/hello-jni.cpp.o
[2/2] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/arm64-v8a/

30 actionable tasks: 2 executed, 28 up-to-date

CMake binary directory will be set to app/.externalNativeBuild/cmake/debug/arm64-v8a/, you can find CMake logs there:

[android-studio-with-hunter/android-studio]> grep 'Hunter-ID' app/.externalNativeBuild/cmake/debug/arm64-v8a/cmake_build_output.txt

[hunter] [ Hunter-ID: 4959eb9 | Toolchain-ID: 8e0b164 | Config-ID: 48b836e ]

Or even start CMake build without using Gradle:

[android-studio-with-hunter/android-studio]> touch ../CMakeLists.txt
[android-studio-with-hunter/android-studio]> cmake --build app/.externalNativeBuild/cmake/debug/arm64-v8a
[1/1] Re-running CMake...
-- [hunter *** DEBUG *** 2018-07-25T19:52:14] HUNTER_ROOT set using HOME environment variable
-- [hunter] [ Hunter-ID: 4959eb9 | Toolchain-ID: 8e0b164 | Config-ID: 48b836e ]
-- Configuring done
-- Generating done
-- Build files have been written to: /.../android-studio-with-hunter/android-studio/app/.externalNativeBuild/cmake/debug/arm64-v8a
[1/1] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/arm64-v8a/


Not all CMake files necessary for build will be created if initial configure step will fail. In this case you can add return() command right after first hunter_add_package call (this is where initialization is happening and all *-ID calculated) to mimic successful CMake configure step:

# ...
return() # Early exit

Run Gradle again:

[android-studio-with-hunter/android-studio]> ./gradlew asDebug -Parch=arm64-v8a

Remove return() from CMake code, now you will be able to run CMake:

[android-studio-with-hunter/android-studio]> cmake --build app/.externalNativeBuild/cmake/debug/arm64-v8a


At this step you may experience error:

[ERROR] [...] * What went wrong:
[ERROR] [...] Execution failed for task ':app:generateJsonModelDebug'.
[ERROR] [...] Conversion = c, Flags =

It is a known Android Studio bug and as workaround just run Gradle again. For continuous integration build set a 10 seconds sleep command between two Gradle launches.


Open Android Studio project, connect your device and click Run 'app' (Shift + F10). You should see HelloJni based application started:

HelloJni screenshot

If you take a look at CMakeLists.txt of the project you will find option for keeping third party sources:

option(HUNTER_KEEP_PACKAGE_SOURCES "Keep third party sources" ON)


Please make sure to read documentation about HUNTER_KEEP_PACKAGE_SOURCES before adding it to your project.

It means that debugger can be used to step into md5 package source code. Open hello-jni.cpp file and set breakpoint to md5_append call:

HelloJni breakpoint

Click Debug 'app' (Shift + F9) to run application in Debug mode. After application started click CALCULATE button on device. When debugger will reach md5_append call click Step Into (F7). As you can see debugger stepped into md5.c source code of third party md5 package and “data” with value “Some string” passed to “md5_append” function:

HelloJni debugger


Here is a description of integration approach.

CMake toolchain file used to customize third party packages builds in Hunter. And since Android Studio provide it’s own toolchain for build such action do introduce a little quirk. Some of the variables like ANDROID_ABI was read from command line and is not part of the toolchain, hence Hunter will not forward them to third parties. User also may want to add extra settings to toolchain. And one more problem is that variables provided by Android Studio toolchain little bit differs from ones expected by project that relies on CMAKE_ANDROID_* conventions (introduced in CMake 3.7).

As a workaround for all the issues above we can inject our own toolchain with FORCE.

Add extra CMake argument to build.gradle configuration:

externalNativeBuild {
    cmake {
        arguments '-DANDROID_STL=c++_static',
            // Extra custom variable to
            // trigger workaround code.


Please name this variable next to your project to avoid clashes with another projects that can be added by add_subdirectory.

Use this variable for triggering CMake workaround code, note that toolchain should be set before first project command:

  set(gen_toolchain "${CMAKE_CURRENT_BINARY_DIR}/generated/toolchain.cmake")
  set(CMAKE_TOOLCHAIN_FILE "${gen_toolchain}" CACHE PATH "" FORCE)

# ...


Content of the latest template can be found here: