From 7ed51168d6224c3fcdf7b6e69f9bfb5c3b1cdab3 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Thu, 8 Oct 2026 23:01:36 +1300 Subject: [PATCH] Android: sync NDK / API / build-tools with apothecary Match apothecary's Android CI (build-android.yml, android_configure.sh) so the core, the template and the prebuilt libs use the same toolchain: - NDK r29 29.0.14206865 (template + core gradle ndkVersion, cmake.sh, of.yml env); previously 28.2 in gradle, "27" / newest folder in cmake.sh and the runner's latest NDK in CI - min API 25 (template was 24, core gradle and cmake.sh were 34, so the core wouldn't load below Android 14) - build-tools 37.0.0 (was 35.0.0) - cmake.sh: use the pinned $NDK under the SDK (or ANDROID_NDK_ROOT / ANDROID_NDK_HOME) instead of silently taking the newest ndk folder, which also picked up half-installed NDKs; ANDROID_PLATFORM follows ANDROID_API; honour ANDROID_HOME / ANDROID_SDK_ROOT on macOS - android.toolchain.cmake: NDKs ship only darwin-x86_64 (universal) / linux-x86_64, so fall back to the x86_64 prebuilt when the arm64 host folder doesn't exist (failed on Apple silicon before) --- .github/workflows/of.yml | 5 +++- .../CMake/toolchain/android.toolchain.cmake | 8 +++++ .../project/android/cmake.sh | 30 +++++++++++++------ .../openframeworksAndroid/build.gradle | 6 ++-- scripts/templates/android/ofApp/build.gradle | 6 ++-- 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/.github/workflows/of.yml b/.github/workflows/of.yml index f821702a1a9..e596ed3b8b6 100644 --- a/.github/workflows/of.yml +++ b/.github/workflows/of.yml @@ -453,7 +453,10 @@ jobs: TARGET: ${{ matrix.cfg.target }} ARCH: ${{ matrix.cfg.opt }} ANDROID_SDK_ROOT: $ANDROID_HOME - ANDROID_NDK_ROOT: $ANDROID_NDK_LATEST_HOME + # keep in sync with apothecary build-android.yml (NDK r29, min API 25); + # cmake.sh resolves $ANDROID_HOME/ndk/$NDK, gradle uses ndkVersion + NDK: "29.0.14206865" + ANDROID_API: "25" steps: - name: checkout openFrameworks diff --git a/libs/openFrameworksCompiled/project/CMake/toolchain/android.toolchain.cmake b/libs/openFrameworksCompiled/project/CMake/toolchain/android.toolchain.cmake index 868716f4ede..0fc80a37a5d 100644 --- a/libs/openFrameworksCompiled/project/CMake/toolchain/android.toolchain.cmake +++ b/libs/openFrameworksCompiled/project/CMake/toolchain/android.toolchain.cmake @@ -60,6 +60,14 @@ if(NOT DEFINED HOST_PLATFORM) else() message(FATAL_ERROR "Unsupported host platform: ${CMAKE_HOST_SYSTEM_NAME} (${CMAKE_HOST_SYSTEM_PROCESSOR})") endif() + # NDKs up to at least r29 ship only darwin-x86_64 (universal binaries) and + # linux-x86_64; use an arm64 host folder only when the NDK actually has one. + if(NOT EXISTS "${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_PLATFORM}") + string(REPLACE "-arm64" "-x86_64" HOST_PLATFORM_FALLBACK "${HOST_PLATFORM}") + if(EXISTS "${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${HOST_PLATFORM_FALLBACK}") + set(HOST_PLATFORM "${HOST_PLATFORM_FALLBACK}") + endif() + endif() endif() message(STATUS "Android ABI: ${ANDROID_ABI}") diff --git a/libs/openFrameworksCompiled/project/android/cmake.sh b/libs/openFrameworksCompiled/project/android/cmake.sh index 02bf05db114..5562018f888 100755 --- a/libs/openFrameworksCompiled/project/android/cmake.sh +++ b/libs/openFrameworksCompiled/project/android/cmake.sh @@ -13,9 +13,11 @@ APOTHECARY_LEVEL="$(cd "$SCRIPT_DIR/../.." && pwd)" export MAKE_TARGET="${MAKE_TARGET:-cmake}" export CPP_STANDARD="${CPP_STANDARD:-23}" export C_STANDARD="${C_STANDARD:-17}" -export NDK_VERSION_MAJOR="${NDK_VERSION_MAJOR:-27}" -export ANDROID_API="${ANDROID_API:-34}" #minimum Android API supported. 34 default -ANDROID_PLATFORM="android-34" # Usually must be >= 24 for modern libraries and NDKs. +# Keep in sync with apothecary (.github/workflows/build-android.yml, configure/android_configure.sh) +export NDK="${NDK:-29.0.14206865}" # pinned NDK (major.minor.build) under $ANDROID_SDK_PATH/ndk +export NDK_VERSION_MAJOR="${NDK_VERSION_MAJOR:-${NDK%%.*}}" +export ANDROID_API="${ANDROID_API:-25}" # min compile API (Android 7.1). Not the SDK version. +ANDROID_PLATFORM="android-${ANDROID_API}" DEFAULT_ARCHS="armeabi-v7a arm64-v8a x86_64" TOOLCHAIN_FILE="$(pwd)/../CMake/toolchain/android.toolchain.cmake" CMAKELISTS_DIR="$(pwd)/openframeworksAndroid" @@ -37,7 +39,7 @@ else fi if [[ "$OS_TYPE" == "macOS" ]]; then echo "Running on macOS" - export ANDROID_SDK_PATH="$HOME/Library/Android/sdk" + export ANDROID_SDK_PATH="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-$HOME/Library/Android/sdk}}" elif [[ "$OS_TYPE" == "Windows" ]]; then echo "Running on Windows (Git Bash)" WIN_USER=$(whoami) @@ -63,13 +65,23 @@ else exit 1 fi -# Find latest NDK inside the SDK directory -ANDROID_NDK_PATH=$(ls -d "$ANDROID_SDK_PATH/ndk/"* 2>/dev/null | sort -V | tail -n 1) -export ANDROID_NDK_ROOT=$ANDROID_NDK_PATH +# NDK: the pinned $NDK under the SDK, else ANDROID_NDK_ROOT / ANDROID_NDK_HOME. +# Never fall back to "newest folder" silently: a newer or half-installed NDK +# (no source.properties) builds a core that doesn't match the apothecary libs. +ANDROID_NDK_PATH="" +if [ -f "$ANDROID_SDK_PATH/ndk/$NDK/source.properties" ]; then + ANDROID_NDK_PATH="$ANDROID_SDK_PATH/ndk/$NDK" +elif [ -n "${ANDROID_NDK_ROOT:-}" ] && [ -f "$ANDROID_NDK_ROOT/source.properties" ]; then + ANDROID_NDK_PATH="$ANDROID_NDK_ROOT" +elif [ -n "${ANDROID_NDK_HOME:-}" ] && [ -f "$ANDROID_NDK_HOME/source.properties" ]; then + ANDROID_NDK_PATH="$ANDROID_NDK_HOME" +fi if [ -n "$ANDROID_NDK_PATH" ]; then - echo "Latest Android NDK found at: $ANDROID_NDK_PATH" + export ANDROID_NDK_ROOT=$ANDROID_NDK_PATH + echo "Android NDK: $ANDROID_NDK_PATH ($(grep -m1 Pkg.Revision "$ANDROID_NDK_PATH/source.properties" | cut -d= -f2 | tr -d ' '))" else - echo "No NDK found inside SDK directory." + echo "Android NDK $NDK not found in $ANDROID_SDK_PATH/ndk (and ANDROID_NDK_ROOT / ANDROID_NDK_HOME not set)." + echo "Install it with: sdkmanager \"ndk;$NDK\" or set NDK=" exit 1 fi ANDROID_CMAKE_PATH=$(ls -d "$ANDROID_SDK_PATH/cmake/"* 2>/dev/null | sort -V | tail -n 1) diff --git a/libs/openFrameworksCompiled/project/android/openframeworksAndroid/build.gradle b/libs/openFrameworksCompiled/project/android/openframeworksAndroid/build.gradle index cbb9bd03311..c11061924ee 100644 --- a/libs/openFrameworksCompiled/project/android/openframeworksAndroid/build.gradle +++ b/libs/openFrameworksCompiled/project/android/openframeworksAndroid/build.gradle @@ -18,11 +18,11 @@ tasks.register("prepareKotlinBuildScriptModel"){} android { namespace 'cc.openframeworks.android' compileSdkVersion 34 - ndkVersion '28.2.13676358' - buildToolsVersion '35.0.0' + ndkVersion '29.0.14206865' + buildToolsVersion '37.0.0' defaultConfig { - minSdkVersion 34 + minSdkVersion 25 targetSdkVersion 34 versionCode 12 versionName "12" diff --git a/scripts/templates/android/ofApp/build.gradle b/scripts/templates/android/ofApp/build.gradle index 04f60c08f17..dcc9fda1188 100644 --- a/scripts/templates/android/ofApp/build.gradle +++ b/scripts/templates/android/ofApp/build.gradle @@ -170,9 +170,9 @@ println "Include directories: " + addonIncludeDirs android { compileSdkVersion 34 - buildToolsVersion '35.0.0' + buildToolsVersion '37.0.0' //ndkPath "/Users/x/android-ndk-r21e" // Point to your own NDK if needed - ndkVersion '28.2.13676358' // use android studio side loaded ndk + ndkVersion '29.0.14206865' // keep in sync with apothecary build-android.yml buildFeatures { prefab true } @@ -189,7 +189,7 @@ android { } defaultConfig { applicationId "cc.openframeworks.androidAssimpExample" // IMPORTANT : THIS DEFINES THE ID OF THE APK - minSdkVersion 24 + minSdkVersion 25 targetSdkVersion 34 versionCode 12 versionName '12.0'