From 957fb43da39703dd176c34b16cd710505ceb148b Mon Sep 17 00:00:00 2001 From: misomosi Date: Sun, 21 Jun 2026 18:08:45 -0400 Subject: [PATCH] Add Android NDK barebones app --- android-native-app-barebones/.gitignore | 35 +++++++++++++++ .../AndroidManifest.xml | 20 +++++++++ android-native-app-barebones/LICENSE | 24 ++++++++++ android-native-app-barebones/README.md | 37 +++++++++++++++ android-native-app-barebones/build.bat | 36 +++++++++++++++ android-native-app-barebones/build.sh | 45 +++++++++++++++++++ android-native-app-barebones/main.c | 16 +++++++ 7 files changed, 213 insertions(+) create mode 100644 android-native-app-barebones/.gitignore create mode 100644 android-native-app-barebones/AndroidManifest.xml create mode 100644 android-native-app-barebones/LICENSE create mode 100644 android-native-app-barebones/README.md create mode 100644 android-native-app-barebones/build.bat create mode 100644 android-native-app-barebones/build.sh create mode 100644 android-native-app-barebones/main.c diff --git a/android-native-app-barebones/.gitignore b/android-native-app-barebones/.gitignore new file mode 100644 index 0000000..6a4d5ee --- /dev/null +++ b/android-native-app-barebones/.gitignore @@ -0,0 +1,35 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Build directory +build/ diff --git a/android-native-app-barebones/AndroidManifest.xml b/android-native-app-barebones/AndroidManifest.xml new file mode 100644 index 0000000..34b3ab9 --- /dev/null +++ b/android-native-app-barebones/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/android-native-app-barebones/LICENSE b/android-native-app-barebones/LICENSE new file mode 100644 index 0000000..fdddb29 --- /dev/null +++ b/android-native-app-barebones/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/android-native-app-barebones/README.md b/android-native-app-barebones/README.md new file mode 100644 index 0000000..f28a283 --- /dev/null +++ b/android-native-app-barebones/README.md @@ -0,0 +1,37 @@ +# android-native-app-barebones +The most elementary, stripped-down template of building an APK using Android tools + +## Required Environment Variables + +* __ANDROID_HOME__: Path where your [Android command line tools](https://developer.android.com/studio#command-line-tools-only) are installed +* __JAVA_HOME__: Path where your JDK is installed +* __PATH__: The ``bin`` folder from __JAVA_HOME__ must be included + +## Required SDKManager Installations + +The scripts work for the following package versions which can be installed via ``sdkmanager`` + +```sh +sdkmanager 'build-tools;36.0.0' 'ndk;29.0.13113456' 'platforms;android-35' +``` + +In addition, you should also install ``platform-tools`` via ``sdkmanager`` to use ``adb`` + +## Instructions + +You can simply invoke ``build.sh`` or ``build.bat`` for ``/bin/sh`` +or ``CMD.EXE`` respectfully and it should build ``build/app-signed.apk`` + +To keep the scripts simple and easy to read, the APK only is built for +AARCH64so you need a 64-bit ARM Android device handy or to emulate +such a device (caveat: this is slow to do on X86\_64). + +After this, set up an ADB daemon and install ``app-signed.apk`` using ``adb`` +and run it on your device. It should just be a black screen that doesn't crash. + +Additionally, you can look at logs via ``adb logcat "*:S barebones"`` +and you should find a nice little "hello" from the app you built. + +If, for whatever reason, it's erroring out, try to look at +``adb logcat *:E``. This will usually output a java exception +from your app which lets you know why your app failed to load. diff --git a/android-native-app-barebones/build.bat b/android-native-app-barebones/build.bat new file mode 100644 index 0000000..651781a --- /dev/null +++ b/android-native-app-barebones/build.bat @@ -0,0 +1,36 @@ +@echo off + +REM For simplicity, version are hardcoded for build tools, NDK, and SDK. +REM In addition, the architecture is hardcoded to AARCH64. +REM Feel free to change these to your liking! +REM Make sure to also edit AndroidManifest.xml if you change SDK versions +SET BUILD=build +SET JNI=lib\arm64-v8a +SET BUILD_TOOLS=%ANDROID_HOME%\build-tools\36.0.0 +SET ANDROID_NDK=%ANDROID_HOME%\ndk\29.0.13113456 +SET ANDROID_TOOLCHAIN=%ANDROID_NDK%\toolchains\llvm\prebuilt\windows-x86_64 +SET CC=%ANDROID_TOOLCHAIN%\bin\clang --target=aarch64-linux-android35 +SET ANDROID_JAR=%ANDROID_HOME%\platforms\android-35\android.jar +SET SYSROOT=%ANDROID_TOOLCHAIN%\sysroot +SET NATIVE_APP_GLUE_DIR=%ANDROID_NDK%\sources\android\native_app_glue +SET PLATFORM_TOOLS=%ANDROID_HOME%\platform-tools + +REM For simplicity, project hardcoded to "barebones" +REM Make sure to also edit AndroidManifest.xml if you change this +SET LIB=libbarebones.so +SET CFLAGS=-lm -lc -llog -landroid -ldl -g -Og -shared -fPIC --sysroot=%SYSROOT% +SET KEYSTORE=%BUILD%\barebones.keystore +SET KEYPASS=barebones + +@echo on + +MKDIR %BUILD%\%JNI% 2>NUL +if not exist %KEYSTORE% (%JAVA_HOME%\bin\keytool -genkeypair -validity 10000 -dname "CN=barebones,O=Android,C=ES" -keystore %KEYSTORE% -storepass %KEYPASS% -keypass %KEYPASS% -alias barebones -keyalg RSA) +%CC% -I %NATIVE_APP_GLUE_DIR% %NATIVE_APP_GLUE_DIR%\android_native_app_glue.c main.c -o %BUILD%\%JNI%\%LIB% %CFLAGS% + +%BUILD_TOOLS%\aapt package -f -M AndroidManifest.xml -I %ANDROID_JAR% -F %BUILD%\app.apk +PUSHD %BUILD% +%BUILD_TOOLS%\aapt add app.apk %JNI:\=/%/%LIB% +POPD +%BUILD_TOOLS%\zipalign -f 4 %BUILD%\app.apk %BUILD%\app-signed.apk +%BUILD_TOOLS%\apksigner sign --ks %KEYSTORE% --ks-pass pass:%KEYPASS% %BUILD%\app-signed.apk diff --git a/android-native-app-barebones/build.sh b/android-native-app-barebones/build.sh new file mode 100644 index 0000000..e68bcf2 --- /dev/null +++ b/android-native-app-barebones/build.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# For simplicity, version are hardcoded for build tools, NDK, and SDK. +# In addition, the architecture is hardcoded to AARCH64. +# Feel free to change these to your liking! +# Make sure to also edit AndroidManifest.xml if you change SDK versions +BUILD=build +JNI=lib/arm64-v8a +BUILD_TOOLS=$ANDROID_HOME/build-tools/36.0.0 +ANDROID_NDK=$ANDROID_HOME/ndk/29.0.13113456 +ANDROID_TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt +if [ -d "$ANDROID_TOOLCHAIN/windows-x86_64" ] ; then + # Those who use MSYS (like me) use these variables. + # As a bounus, it also works under busybox-w32. + ANDROID_TOOLCHAIN=$ANDROID_TOOLCHAIN/windows-x86_64 + EXT=".bat" +else + ANDROID_TOOLCHAIN=$ANDROID_TOOLCHAIN/linux-x86_64 + EXT="" +fi +CC=$ANDROID_TOOLCHAIN/bin/aarch64-linux-android35-clang +ANDROID_JAR=$ANDROID_HOME/platforms/android-35/android.jar +SYSROOT=$ANDROID_TOOLCHAIN/sysroot +NATIVE_APP_GLUE_DIR=$ANDROID_NDK/sources/android/native_app_glue +PLATFORM_TOOLS=$ANDROID_HOME/platform-tools + +# For simplicity, project hardcoded to "barebones" +# Make sure to also edit AndroidManifest.xml if you change this +LIB=libbarebones.so +CFLAGS="-lm -lc -llog -landroid -ldl -g -Og -shared -fPIC --sysroot=$SYSROOT" +KEYSTORE=$BUILD/barebones.keystore +KEYPASS=barebones + +set -e + +mkdir -p $BUILD/$JNI +if [ ! -f $KEYSTORE ] ; then + ($JAVA_HOME/bin/keytool -genkeypair -validity 10000 -dname "CN=barebones,O=Android,C=ES" -keystore $KEYSTORE -storepass $KEYPASS -keypass $KEYPASS -alias barebones -keyalg RSA) +fi +$CC -I $NATIVE_APP_GLUE_DIR $NATIVE_APP_GLUE_DIR/android_native_app_glue.c main.c -o $BUILD/$JNI/$LIB $CFLAGS + +# Only APKSigner out of all of these is a batch file on Windows +$BUILD_TOOLS/aapt package -f -M AndroidManifest.xml -I $ANDROID_JAR -F $BUILD/app.apk +(cd $BUILD && $BUILD_TOOLS/aapt add app.apk $JNI/$LIB) +$BUILD_TOOLS/zipalign -f 4 $BUILD/app.apk $BUILD/app-signed.apk +$BUILD_TOOLS/apksigner"$EXT" sign --ks $KEYSTORE --ks-pass pass:$KEYPASS $BUILD/app-signed.apk diff --git a/android-native-app-barebones/main.c b/android-native-app-barebones/main.c new file mode 100644 index 0000000..4d191d3 --- /dev/null +++ b/android-native-app-barebones/main.c @@ -0,0 +1,16 @@ +#include +#include +#include + +void handle_cmd(struct android_app *app, int32_t cmd) {} +void android_main(struct android_app *app) { + (void)__android_log_print(ANDROID_LOG_INFO, "barebones", "Barebones Android app says hello!"); + app->onAppCmd = handle_cmd; + while (!app->destroyRequested) { + struct android_poll_source *source; + int events; + switch (ALooper_pollOnce(-1, 0, &events, (void **)&source)) { + default: if (source) source->process(app, source); + } + } +} -- 2.49.1