Skip to content

Add CMake-generated Android APK packaging - #105

Merged
Try merged 4 commits into
Try:masterfrom
Solessfir:android-platform
Sep 10, 2026
Merged

Try merged 4 commits into
Try:masterfrom
Solessfir:android-platform

Conversation

@Solessfir

@Solessfir Solessfir commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

First part of Android support, limited to APK packaging. Events, Vulkan swapchain handling and controllers are left for separate PRs.

  • Generate one build.gradle from CMake, with no root/app split. The application supplies its own manifest.
  • Define the native shared library and call add_android_apk(... CODE target ...) in the same CMakeLists.txt. Tempest includes the helper automatically. Gradle builds that same project, with packaging generation disabled in its inner build.
  • Use an installed Gradle for command-line builds. No wrapper files, settings.gradle or gradle.properties are included.
  • Respect CMake's Android ABI, minimum API, NDK path, STL and native build type settings.
  • Support application sources, resources, dependencies and signing, with optional release crash-symbol archives.
  • Include a small native packaging example, independent of the Tempest Android backend.
  • Leave desktop builds unchanged.

Usage

With JDK 17, Gradle 8.9, the Android SDK, CMake and Ninja configured (replace /path/to/ndk with the NDK installation directory):

cmake -S Examples/Android -B build/android-example -G Ninja -DCMAKE_TOOLCHAIN_FILE=/path/to/ndk/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-24 -DCMAKE_BUILD_TYPE=Release
cmake --build build/android-example --target TempestExample-apk

APK: build/android-example/TempestExample-apk/build/outputs/apk/release/TempestExample-apk-release.apk

A short usage example is in Examples/Android/README.md. Release builds use the local debug signing key unless distribution signing is configured.

Verified Windows command-line Release and Debug ARM64 builds, uncompressed native-library packaging, APK signing and 16 KiB alignment. Also checked custom NDK/API/STL settings and an x86_64 RelWithDebInfo build with a separate full symbol archive. Android Studio import has not been checked locally.

@Try

Try commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR @Solessfir !

We would have to split it into parts, as-is there are too many separated things to review.

Just some overall notes:

  • no need to have multiple build.gradle/settings.gradle files - those can be flatten into a single one
  • when list time I've tested gragle*.* files were unneeded. At least when project is opened in AndroidStudio, everything other than build.gradle can be auto-generated. (not sure about command-line)
    probably that part will require some iterations, before merge.

Afterward we can have a look separatly at:

  • event system
  • swapchain
  • controller

@Solessfir

Copy link
Copy Markdown
Contributor Author

Yep, makes sense. I'll split it up and start with the packaging part. I'll simplify the Gradle layout and check what's actually needed for both Android Studio and command-line builds. Then we can go through events, swapchain and controllers separately.

@Solessfir Solessfir changed the title Add Android support with CMake-generated APK packaging Add CMake-generated Android APK packaging Sep 8, 2026
@Solessfir

Copy link
Copy Markdown
Contributor Author

Done, narrowed this to packaging only and flattened it to a single build.gradle. No settings.gradle, gradle.properties or wrapper files now. Command-line builds use an installed Gradle.

Release and Debug builds work from the command line. The example uses Android's built-in NativeActivity, so it doesn't depend on the Tempest backend changes. I haven't checked Android Studio import locally yet.

Events, swapchain and controllers are kept out of this PR for separate review later.

Comment thread Engine/cmake/android/build.gradle.in Outdated
@DEPENDENCIES@.each { implementation it }
}

// Multi-gigabyte asset packages need full repackaging to avoid stale ZIP offsets.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need multi-gig .apk? I've been assuming that gothic-assets will be located somewhere in external-storage folder.

Comment thread Engine/cmake/android/build.gradle.in Outdated
}
packagingOptions {
jniLibs {
useLegacyPackaging true

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need it? You already have max-page-size=16384 CMakeLists.txt

Comment thread Engine/cmake/TempestAndroid.cmake Outdated
message(FATAL_ERROR "Android packaging requires an out-of-source build")
endif()

set(TEMPEST_ANDROID_COMPILE_SDK 35 CACHE STRING "Android compile and target SDK")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we rather about existing cmake variables here?

maybe only set some defaults...

Comment thread Engine/cmake/android/build.gradle.in Outdated
Comment thread Examples/Android/native/CMakeLists.txt Outdated
@Solessfir

Copy link
Copy Markdown
Contributor Author
  • Removed forced repackaging and legacy compression.
  • Reused standard CMake Android settings.
  • Made symbol archives optional.
  • Moved the manifest into the example app.

Comment thread Examples/Android/CMakeLists.txt Outdated
project(TempestAndroidPackaging LANGUAGES NONE)

include(../../Engine/cmake/TempestAndroid.cmake)
tempest_android_application(TempestExample

@Try Try Sep 9, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to have one cmake file instead of two?
Ideally, I'm thinking about:

# will be hidden at 'add_subdirectory(Tempest)' level
include(../../Engine/cmake/TempestAndroid.cmake)

and then:

# similar to old Tegra sdk
add_android_apk(target_name package manifest CPP_SOURCE ...)

and in OpenGothic we will add something similar to:

# at very start
if(ANDROID)
  add_library(Gothic2Notr SHARED) # generally same as regular PC build
else()
  add_executable(Gothic2Notr)
endif()
...
# close to the end
if(ANDROID)
  add_android_apk(Gothic2Notr_apk 
          MANIFEST AndroidManifest.xml.in 
          CODE Gothic2Notr
          PACKAGE_NAME "opengothic.gothic2"
      )
endif()

Comment thread Engine/cmake/TempestAndroid.cmake Outdated
endif()
get_filename_component(APP_NATIVE_SOURCE_DIR "${APP_NATIVE_SOURCE_DIR}" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
if(APP_NATIVE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR NOT EXISTS "${APP_NATIVE_SOURCE_DIR}/CMakeLists.txt")
message(FATAL_ERROR "NATIVE_SOURCE_DIR must name a separate native CMake project")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't need this (see comment in Examples/Android/CMakeLists.txt)

Comment thread Examples/Android/main.cpp
Comment thread Examples/Android/README.md
@Solessfir

Copy link
Copy Markdown
Contributor Author
  • One CMake project with add_android_apk(... CODE target ...).
  • Helper included automatically by Tempest.
  • No recursive packaging generation.
  • Shortened README and removed the signing tutorial.

@Try

Try commented Sep 10, 2026

Copy link
Copy Markdown
Owner

There are many small things that I wish to change, but this can wait :)
Looks good to merge, thanks!

@Try
Try merged commit 5b5304b into Try:master Sep 10, 2026
4 checks passed
@Solessfir
Solessfir deleted the android-platform branch September 12, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants