Android build reference
Android build architecture, configuration, and deployment with Qbs
Technical reference for the Android build infrastructure. Kiln, the default build path, builds OctoMY™ for Android with kiln build --os android and makes the packages with kiln package apk and kiln package aab (see the kiln reference). This page describes the Qbs Android pipeline, the second path until qbs retires, with Qt6.
Build Architecture
Qbs builds Android applications using its own packaging pipeline, without Gradle. The Android.sdk module handles:
- Resource compilation via AAPT2
- DEX compilation via d8
- APK/AAB assembly directly
This differs from CMake-based Qt6 projects, which use Gradle as an intermediary.
Android Version Targeting
| Property | Value | Meaning |
|---|---|---|
minSdkVersion |
28 | Minimum Android 9 (Pie) — Qt6 requirement |
targetSdkVersion |
35 | Android 15 — Google Play 2025 requirement |
compileSdkVersion |
35 | Compile against API 35 |
These values ensure compatibility with devices running Android 9 through Android 16, while meeting Google Play Store publishing requirements.
Project Structure
Each of the three applications has an android/ directory:
src/{agent,hub,remote}/android/
├── AndroidManifest.xml # App manifest (package, permissions, activity)
└── res/
├── drawable-hdpi/icon.png # App icon (high density)
├── drawable-mdpi/icon.png # App icon (medium density)
├── drawable-ldpi/icon.png # App icon (low density)
└── values/libs.xml # App name string resource
The signing keystore is stored separately at integration/cicd/targets/android-arm64/certificates/android_release.keystore.
AndroidManifest.xml
Each app's manifest declares the Qt6 Activity and application bindings:
<application android:name="org.qtproject.qt.android.bindings.QtApplication" ...>
<activity android:name="org.qtproject.qt.android.bindings.QtActivity"
android:exported="true" ...>
<meta-data android:name="android.app.lib_name" android:value="{appname}"/>
</activity>
<provider android:name="androidx.core.content.FileProvider" .../>
</application>
Key elements:
| Element | Purpose |
|---|---|
QtApplication |
Qt6 application class (handles library loading) |
QtActivity |
Default Qt6 activity (no custom subclass needed) |
android:exported="true" |
Required since Android 12 (API 31) for launcher activities |
android.app.lib_name |
Name of the native shared library to load |
FileProvider |
Required by Qt6 for file sharing intents |
Per-app differences:
| App | Package | Library Name |
|---|---|---|
| Agent | org.octomy.agent |
agent |
| Hub | org.octomy.hub |
hub |
| Remote | org.octomy.remote |
remote |
Qbs Configuration
AndroidOptions.qbs
Located at integration/qbs/imports/AndroidOptions.qbs, this Properties block configures the Android SDK when targeting Android:
The properties belong to the Android.sdk module:
| Property | Value | Description |
|---|---|---|
platform |
"android-35" |
Compile SDK version |
packageType |
the project's androidPackageType |
"apk" or "aab" |
aaptName |
"aapt2" |
Resource compiler |
dexCompilerName |
"d8" |
DEX compiler |
The value of Android.sdk.packageType is project.androidPackageType.
App.qbs Android Integration
App.qbs conditionally includes Android support:
- Dependencies:
Android.sdkandAndroid.ndk(when targeting Android) - Manifest: Points
Android.sdk.manifestFileto the per-appAndroidManifest.xml - Linker: Skips
--start-group/--end-groupflags (Android's lld resolves all archive symbols by default)
project.qbs
| Property | Default | Description |
|---|---|---|
androidPackageType |
"apk" |
Override with "aab" for Google Play |
BuildOptions.qbs Android Guards
The following desktop-only features are disabled on Android:
-fstack-clash-protection(not supported by NDK)-fuse-ld=mold/-fuse-ld=lld(NDK provides its own linker)cpp.cxxStandardLibrary(NDK always uses libc++)
QtDepends.qbs Module Exclusions
These Qt modules are excluded on Android builds:
| Module | Reason |
|---|---|
printsupport |
No printing support on Android |
shadertools-private |
Desktop-only |
serialport |
No serial port access on Android |
webenginecore / webenginewidgets |
Not available on Android |
Signing
The release keystore is at integration/cicd/targets/android-arm64/certificates/android_release.keystore. For release builds, configure signing via Qbs Android.sdk properties or environment variables.
ABI Support
OctoMY™ has two Android targets, both 64-bit:
| ABI | Status | Typical device |
|---|---|---|
arm64-v8a |
Supported: built, tested on devices, shipped | Modern phones (Android 9+) |
x86_64 |
A target, postponed until we have x86_64 Android hardware. It builds, and the hub runs on the API 35 emulator. Device tests and releases wait for hardware | x86_64 tablets and Chromebooks, the emulator |
How to build each ABI, and the folder of its Qt installation:
arm64-v8a—kiln package apk --arch arm64. Qt install path:Qt/6.10.1/android_arm64_v8a.x86_64—kiln package apk --arch x64. The build farm builds it asandroid/35/x86_64. Qt install path:Qt/6.10.1/android_x86_64.
Postponed is not dropped: x86_64 stays in the build matrix and in kiln.
armv7 / armeabi-v7a / any 32-bit ARM target is the opposite case. It is a
deliberate, permanent non-target and will not be re-added. The
justification (no 32-bit Android hardware in the target market, the Google
Play 64-bit policy since 2019, libnative's JIT being 64-bit by design) is in
the root AGENTS.md under "Android architecture support". Read that before
requesting a change to the Android ABIs.
Build, install and start
kiln is the Android path on a development machine. It builds both 64-bit ABIs
and installs and starts the application through adb:
kiln package apk src/hub --arch arm64 --install --launch
kiln package apk src/hub --arch x64 --install --launch # the API 35 emulator
--install runs adb install -r on the device that adb sees, or on the
device that android.device in .kiln.local names. --launch starts the
launcher activity of the manifest with am start -W -n <package>/<activity>.
Then it watches the process for 30 seconds (--launch-watch <seconds>, 0 to not
watch). If the process dies, kiln names the process and its ID and prints the
logcat lines about that ID. kiln refuses armv7, armeabi-v7a and every
other 32-bit ABI with a message that points to AGENTS.md.
The suites run on a device with kiln test --os android --arch arm64. See the
Build for Android howto.
qbs profile
The qbs profile android-arm64 stays for the build farm. The farm patches its
own qbs Android module at container start. The tree no longer carries the
patched module files or the script that installed them
(integration/qbs/vendor/, deleted in script-ports Phase 12). A stock qbs
fails the Android build, so use kiln on a development machine.
- Profile:
android-arm64 - ABI:
arm64-v8a qbs.architecture:arm64- Qt install path:
Qt/6.10.1/android_arm64_v8a - Typical device: modern phones (Android 9+)
AAB (Google Play) bundle
For Play Store distribution, build the App Bundle:
kiln package aab src/hub --arch arm64
arm64-v8a alone covers the vast majority of active Play Store devices.
SDK/NDK Requirements
| Component | Minimum Version |
|---|---|
| Android SDK Platform | API 35 |
| Android NDK | r26+ (r27.2+ recommended; r28+ gains 16 KB page support) |
| JDK | 17+ (21+ for Qt 6.11) |
| Qt | 6.10.0+ |
| Qbs | 2.0+ |
| Android OpenSSL | ssl_3 (extracted into the SDK root) |
See also
- Build for Android — Step-by-step build instructions
- Qbs Build System — Build system architecture
- Platform Support — Cross-platform overview