Permalink
Fetching contributors…
Cannot retrieve contributors at this time
309 lines (214 sloc) 9.39 KB
.. spelling::

  Gradle
  md

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.

Example

As an example let's take a look at simple project with one tiny :doc:`md5 package </packages/pkg/md5>` dependency. The project is a slight modification of the HelloJni sample.

Examples on GitHub

Note

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+:

Check you have Ninja build tool installed:

> which ninja
/usr/bin/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:

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

.. seealso::

  * `Android Studio: Use CMake 3.7 or higher <https://developer.android.com/studio/projects/add-native-code#vanilla_cmake>`__

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

Hint

Since local.properties 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:

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

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:

Note

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:

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

Note

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.

Project

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)

Warning

Please make sure to read documentation about :ref:`HUNTER_KEEP_PACKAGE_SOURCES <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

Integration

Here is a description of integration approach.

:doc:`CMake toolchain file </overview/customization/toolchain-id>` 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:

Note

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:

if(HELLOJNI_ANDROID_STUDIO)
  set(gen_toolchain "${CMAKE_CURRENT_BINARY_DIR}/generated/toolchain.cmake")
  configure_file(
      "${CMAKE_CURRENT_LIST_DIR}/cmake/template/toolchain.cmake.in"
      "${gen_toolchain}"
      @ONLY
  )
  set(CMAKE_TOOLCHAIN_FILE "${gen_toolchain}" CACHE PATH "" FORCE)
endif()

# ...

project(...)

Content of the latest toolchain.cmake.in template can be found here: