Cross-compiling for Android from Windows

In this short guide you can learn how to build the source code of the ApertusVR libraray for Android.

Introduction

ApertusVR is a cross platform library, which means, we support various operating systems, included Android, as well.

The following guide will go through a step-by-step tutorial on how you can build the source code for Android using a Windows PC.

If you are new to Android development, we highly recommend you the official Android documentations. From now, we will assume, that you are familiar, at least with the basics.

Requirements

For the cross compilation process, you have to obtain the following softwares:

  • Android Studio v. 3.6 or later versions (any other tools related with Android Studio will be discussed in the Configuring Android Studio section)

  • Git for Windows

  • That's all!

Download Android build source.

Just like the other parts of the library, the Android source files are hosted on GitHub. To obtain it, you have to make a folder for it on your personal Windows device. In this tutorial we will assume, that your chosen folder is C:\ApertusVR.

The Android source files are available in the android branch. This means, that after you navigated to C:\ApertusVR, you should use the following command in Git bash:

$ git clone -b android --single-branch https://github.com/MTASZTAKI/ApertusVR.git

Or alternatively you can use Git GUI, as well.

If everything worked properly, you should see something similar to the picture below

C:\ApertusVR\ApertusVR\

Configuring Android Studio

For Android Studio to work properly, you will need the following toolsets:

  1. Android SDK

  2. Android NDK

Android SDK

ApertusVR supports Android 6.0 (Marshmallow) or higher versions. In correlation with this, the library works with API level 23, or later releases. This implies, that according to the SDK Platform release notes, the minimum requirement is:

  • Android SDK Platform-tools r23

  • Android SDK Tools 24.3.4

If Android Studio does not find any of the Android SDK versions, it will offer you to download the latest release. This may not the version you want (e.g. your debugging Anroid device only supports former versions), so you can also download other releases in Settings > System Settings > Android SDK > SDK Tools.

Android NDK

The ApertusVR library is written in C++, which means, in order to build on Android, we use the native language toolset provided by Google, called Android NDK (native developement kit). For more information see the official Android NDK documentation.

The version we use is 20.0.5594570. You can download it with Android Studio's SDK Manager. Go Settings > Appearance & Behavior > System Settings > Android SDK > SDK Tools. Then click Show Package Details in the bottom right corner. Choose NDK (Side by side) 20.05594570, but do not click on Apply yet.

ApertusVR uses CMake as its main build tool. Good news is that Android Studio accidentally has support for CMake projects too. In order to use it, on the same page where you picked the NDK version, you can mark the appropriate CMake version, which is 3.10.2.

NDK and CMake in the Android SDK manager.

Then click Apply, and wait until the install finishes.

Building the ApertusVR library

If you deployed everything as discussed above, we can actually start to build our source files. However, before we dive into it, we will go through some important notes, which helps you understand the build process.

Project structure

Now if you open the C:\ApertusVR\ApertusVR\androidx folder, you should see something like this:

C:\ApertusVR\ApertusVR\androidx

Here the most important for us, is the apertusvr-android subfolder, which contains the Android Studio project. Let's see what we can find in it!

Open Android Studio, and go File > Open, then navigate to the project folder, and click Ok to open the project file. When it is opened, it may takes some time for Android Studio to configure the project. If it is done, open the left panel called 1:Project:

Then open the Android view:

Now we can see how the project structure actually looks like. The following lines will explain what you see on the right picture.

We have two Android library containing java (and c++) files. These libraries will became Android archive files (*.aar), similar to a Java archive file (*.jar). These two libraries are:

  • apertusvr, which contains the ApertusCore C++ library, and the consisting JNI-binds and wrappers. If you are not familiar with the ApertusVR architecture, check out the Developers/Architecture chapter in the documentation. The module embraces the whole ApertusVR C++ project, which consists of shared libraries. These shared libs are all linked against the apeJNIStarter, which is also a shared library. Then apeJNIStarter and apeJNIPlugin (the library which implements the JNI-binds) are loaded in the ApertusJNI class file with Java's System.loadLibrary().

  • apefilamentrender, which is ApertusVR's main render plug-in on the Android platform. It uses the Google supported Filament engine. This plug-in is written entirely in Java, and uses the ApertusVR Java interface.

The last component of the project is a sample app. This is the one component which becomes an apk file, containing the business logic of our application, which depends on the ApertusVR library.

Dependencies

In this subsection we discuss what are the dependencies of the Android build, and what you should know about them. You can skip this subsection if you are not intrested in modifying them. ApertusVR is dependent on several 3rd party libraries. The three most important for ApertusCore are the followings:

And we use the mentioned Filament engine for rendering, as well. All of them are included as a prebuilt library except RakNet, which was added as a subdirectory in the CMake project.

The prebuilt C++ library dependencies are stored in the ApertusVR\androidx\libs folder. Note that, becouse cURL is dependent on the OpenSSL library, thus you can find its prebuilt *.so files in the libs folder too. If you want your own build (e.g. you need a specific version) you have to build them for each supported Android ABI. To do that follow the instructions in OpenSSL's and cURL's github repository:

You can also build your own Zip version for Android. The easiest way to do it, is with CMake and Ninja, by providing a toolchain file for cross-compiling (the same you use for the ApertusVR-Android) build, e.g. the android.toolchain.cmake file in the ...\AndroidSdk\ndk\<ndk-version>\build\cmake folder.

Then you should manually set the CMake flags for a specific ABI, generate, then repeate with an other ABI... Then you can obtain the builds using Ninja.

Lastly, Filament is included as an Android archive file, you can find it in: ApertusVR\androidx\apertusvr-android\apefilamentrender\libs\. If you want newer version, you have to replace what you found in this folder, then modify the build.gradle file (see in the next subsection).

Gradle

Android Studio uses the build automation tool called Gradle. We will only discuss what we need to build the source code, but further information about the build tool can be found on the official website.

For each existing component of our project (e.g. libraries) we have a corresponding build.gradle file. Other than that, we also have a build.gradle file for the whole project, where you can configure options for all modules globally. And lastly there is a settings.gradle file, where you can modify the project settings (e.g. including other modules). You can see these on the picture below.

Gradle files

Build directory

What is most important for us, in the first place is the build.gradle (ApertusVR-Android). If you open it, you should see in the allprojects configuration that there's a variable called buildDir. Currently it looks like this:

allprojects {
repositories {
google()
jcenter()
flatDir {
dirs 'libs'
}
}
buildDir = "c:/ApertusVR/build/android/${rootProject.name}/${project.name}"
}

Here you can see, that the basic configuration is that the build directory of your project will be C:\ApertusVR\build\android. If you want your built files put somewhere else, you should set this variable to point to the appropriate directory. So, if you want your build files to be at D:\FooBar\, then type buildDir = "d:/FooBar/${rootProject.name}/${project.name}".

CMake and NDK

As you know, the ApertusVR library is written in C++14, and we use CMake for build automation. When you look at the build.gradle (:apertusvr) file, you should see the following commands:

externalNativeBuild {
cmake {
path file('../../../CMakeLists.txt')
}
}

This tells Gradle, that we want to include a CMake project into our Android library, but we also have to tell Gradle where is our root CMakeLists.txt file. If, for some reason you want to change the project structure, you should modify this for Gradle, to be able to find the CMake project, which builds the ApertusVR C++ library. If it is done, then the rest of the native build is only depends on the CMake project.

The second thing, you should pay attention to, is in the defaultConfig:

externalNativeBuild {
cmake {
cppFlags "-std=c++14"
}
}
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86'
}

By this few commands, we tell Gradtle, that:

  • We want C++14 version support of STL for our native C++ project.

  • Our native project only works with 'arm64-v8a', 'armeabi-v7a' and 'x86' ABI filters.

SDK version

As it has been said, basically we support AndroidSDK version 23 and higher. You can change this per module in the defualtConfig:

defaultConfig {
//...
minSdkVersion 23
targetSdkVersion 29
//...
}

Dependencies

The 3rd party JVM dependencies used by the modules (like Filament) are included with the api command. E.g. in the Filament case it looks like this in build.gradle(:apefilamentrender)

dependencies {
//...
api(name: 'filament-20200403-android', ext: 'aar')
api(name: 'filament-utils-20200403-android', ext: 'aar')
}

If you want to add other dependencies, or change Filament to a new version, you have to copy it's *.aar file into the .../<modulename>/libs/ folder, or if you want to use other folder, you have to change the flatDir in build.gradle(ApertusVR-Android):

allprojects {
repositories {
// ...
flatDir {
dirs 'libs'
}
}
// ...
}

Start the build

If you configured the project for your own wish, based on the text below, you can finally start the build by clicking Build > Make Project (or by using the small green hammer).

You will get several warning during the build process, but you shouldn't bother yourself with them, they won't cause any runtime misbehaviour. So if you see something similar like on the picture below, your build is fine:

However, there's one thing remained before you can enjoy the pleasure of programming with ApertusVR on Android.

Debug configurations

The fact, that we changed the default build directory implies, that Android Studio's debugger won't find our native libraries, thus we can not debug native code, if we don't tell the debugger, where it can find them.

Assume that you didn't changed the buildDir variable in the project's build.gradle file, so your build directory is at C:\ApertusVR\build\android. Now if you successfully built the project, then you should have directories there like: C:\ApertusVR\build\android\ApertusVR-Android\apertusvr\intermediates\cmake\debug\<abi>. Where <abi> is one of the three supported ABIs (arm64-v8a, armeabi-v7a, x86). In those folders there are several *.so files. To be able to debug native code, we will tell Android Studio, that it can find these libraries there to fill its symbol table for debugging.

To do this, go Run > Edit Configurations > Debugger. Then here, we should fill in the Symbol Directories field. Click on the + button in the top right corner, like you see on the image:

Then navigate to the directories we just discovered in a few lines above. Then add all the ABI named folders:

If you did it right, then you should see something like this:

Now everything is set up, you can start programming and debugging your app!

Sample app

For running the basic sample app, you have to copy its resources to your Android device. The basic sample app uses the models available in the ApertusVR/sample/virtualLearningFactoryToolkit/models folder.

After you connected your debug Android device, open the Device Explorer in the left right corner.

Then copy the model files to data/data/org.apertusvr.app/files:

If you did everything right, you can start the sample app by clicking Run > Run 'app'. Then after installing, you should see something similar to the picture presented here: