Modernise build system: NDK r30, AGP 9.1.1, targetSdk 36, Android 15 fixes#4
Closed
robmat wants to merge 16 commits intoMeridianOXC:oxce-plus-protofrom
Closed
Modernise build system: NDK r30, AGP 9.1.1, targetSdk 36, Android 15 fixes#4robmat wants to merge 16 commits intoMeridianOXC:oxce-plus-protofrom
robmat wants to merge 16 commits intoMeridianOXC:oxce-plus-protofrom
Conversation
Older Gradle/AGP versions fail with "Unable to get mutable Windows environment variable map" on newer JDK/Windows versions. Upgrading also pins the NDK version explicitly so the build is reproducible, raises minSdk to 21 (drops pre-Lollipop support nobody uses), replaces the deprecated jcenter() repository with mavenCentral(), and removes the grgit dependency in favour of a plain git shell call for the revision stamp. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AGP 8.x moves namespace out of AndroidManifest.xml into build.gradle, restructures .iml files, and generates new Android Studio project metadata. These are mechanical changes produced by the IDE on first open after the Gradle upgrade. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pulls in five fixes made to the submodule: null-check for empty-file SDL_RWops, null guards in loadSpk/loadBdy/loadDat, null-frame skips in the battlescape hair-bleach loops, and the corrected nativeSetPaths JNI symbol. Together these prevent SIGSEGV and UnsatisfiedLinkError crashes that occur when game data files are missing or corrupt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rties These files are generated locally by Android Studio and the CMake/Gradle build and should not be shared via version control as they contain machine-specific paths and transient state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AGP 9.1.1 and Gradle 9.3.1 are the current stable toolchain versions. The IDE project metadata (misc.xml) was regenerated by Android Studio after the toolchain update. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NDK r30 is the latest stable release and includes Clang 18 / libc++ 18. The three fixes in subsequent commits are required to build cleanly against it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ions) libc++ 18 (shipped with NDK r27+) removed non-standard char_traits specializations for types other than char/wchar_t/char8_t/char16_t/ char32_t. OpenXcom depends on two removed specializations: - char_traits<signed char> Engine/ModInfo.h: basic_string<signed char> - char_traits<unsigned int> Engine/Unicode.h: basic_string<Uint32> The compat header libcxx18_char_traits_compat.h provides full specializations for both and is force-included at the top of every C++ TU via the CMakeLists.txt -include flag so the types are visible before any OpenXcom header that uses them. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NDK r28+ promotes -Wincompatible-function-pointer-types to an error. SDL2's OpenGL ES2 renderer (SDL_gles2funcs.h) uses function pointer types whose const qualifiers differ from the system headers, triggering this error. Suppress it for the SDL2 target only. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…or NDK r30 NDK r30 marks ALooper_pollAll with __REMOVED_IN(1, ...), making any call to it a hard compile error. ALooper_pollOnce is the recommended replacement with an identical signature. The zero-timeout non-blocking poll used in SDL_ANDROID_SensorUpdate is semantically equivalent with either call. Committed on branch ndk30-compat of the SDL submodule. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AGP 8.13 removed support for getDefaultProguardFile('proguard-android.txt')
because it includes -dontoptimize which blocks R8. The optimizing variant
is the correct default; minifyEnabled is false so R8 does not actually run
for release builds anyway.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AGP 8.13 requires compileSdk >= 30 to compile Java 9+ language features used by the updated toolchain. Targeting SDK 35 (Android 15) is current best practice and required for Play Store submissions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…iance Android 12 (API 31) requires android:exported to be explicitly set on any activity that declares an intent-filter. compileSdk 35 enforces this at build time. PreloaderActivity is the LAUNCHER entry point so exported=true is correct. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WRITE_EXTERNAL_STORAGE has no effect on Android 11+ (API 30+) for apps targeting API 30+. PreloaderActivity needs broad write access to /sdcard/openxcom/ when extracting bundled ZIPs at first launch. On API 30+ use Environment.isExternalStorageManager() and redirect the user to the system "All files access" settings screen via ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION before proceeding. On API 23-29 the existing WRITE_EXTERNAL_STORAGE runtime request is kept. Below API 23 permission is granted implicitly as before. MANAGE_EXTERNAL_STORAGE is declared in the manifest with android:minSdkVersion="30" so it is only requested on devices that recognise it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous targetSdk 28 was a temporary workaround to preserve legacy external storage access. With the MANAGE_EXTERNAL_STORAGE permission and runtime request now in place for Android 11+, it is safe to target the current API level (Android 16). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Android 15 (targetSdk >= 35) enforces edge-to-edge mode and ignores both Theme.NoTitleBar.Fullscreen and setSystemUiVisibility(). OpenXcom is always a fullscreen game, so system bars must be hidden via the new WindowInsetsController API on API 30+. On API 30+: always hide status and navigation bars, with BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE so a swipe can reveal them briefly. setDecorFitsSystemWindows(false) prevents the system from reserving inset space for the bars. On API 11-29: the existing setSystemUiVisibility() path is kept. Also adds onWindowFocusChanged() in OpenXcom.java to re-apply the UI state when the activity regains focus (e.g. returning from a dialog). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
….1, targetSdk 36) - Updated required versions: NDK r30 (30.0.14904198), compileSdk 35, targetSdk 36, Gradle 9.3.1, AGP 9.1.1 - Added NDK compatibility notes section covering libc++18 char_traits shim, NDK r28+ function pointer error suppression, and NDK r30 ALooper_pollAll removal - Added Android 11+ MANAGE_EXTERNAL_STORAGE permission notes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Owner
|
Thank you very much. I cannot look at this right now. |
Owner
|
Slightly modified and merged manually. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the build system and Android runtime code up to date so the project builds with the current stable toolchain and runs correctly on Android 11–15.
Only tested by playing the game daily on a physical Android device. No automated tests were run.
Build system
compileSdktargetSdkminSdkOther housekeeping: switched from
jcenter()tomavenCentral(), pinned the NDK version explicitly, replaced thegrgitrevision stamp with a plaingitshell call, migrated ProGuard file toproguard-android-optimize.txt(required by AGP 8.13+).NDK r30 compatibility (three issues)
1. libc++ 18 — removed
char_traitsspecialisations (NDK r27+)libc++ 18 (NDK r27+) removed non-standard
char_traitsspecialisations forsigned charandunsigned int. OpenXcom uses both (ModInfo.h,Unicode.h). A small compat header (libcxx18_char_traits_compat.h) is force-included for all C++ TUs via CMake.2.
-Wincompatible-function-pointer-typesis now an error (NDK r28+)SDL2's OpenGL ES2 renderer (
SDL_gles2funcs.h) has a benign const-qualifier mismatch in its function pointer table. Suppressed for the SDL2 target only.3.
ALooper_pollAllremoved (NDK r30)ALooper_pollAllis marked__REMOVED_IN(1)in NDK r30 — hard compile error. Fixed by replacing it withALooper_pollOnce(identical signature, same semantics for a zero-timeout poll) in the SDL submodule. That fix is tracked separately at StoddardOXC/SDL#1 — the SDL submodule pointer here depends on that PR being merged and the pointer updated before this lands.Android 11+ storage (
targetSdk 36)WRITE_EXTERNAL_STORAGEhas no effect on Android 11+ (API 30+) when targeting API 30+.PreloaderActivityneeds broad write access to/sdcard/openxcom/to extract bundled ZIPs at first launch. AddedMANAGE_EXTERNAL_STORAGEpermission with a runtime request flow that redirects the user to the system "All files access" settings screen on API 30+. LegacyWRITE_EXTERNAL_STORAGEruntime request is kept for API 23–29.Android 15 fullscreen (
targetSdk 35+)Android 15 enforces edge-to-edge mode and ignores both
Theme.NoTitleBar.FullscreenandsetSystemUiVisibility()for apps targeting API 35+. Since OpenXcom is always fullscreen,UiVisibilityChangernow unconditionally hides status and navigation bars viaWindowInsetsControlleron API 30+, withBEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPEso a swipe can reveal them briefly. The legacy path is kept for API 11–29.Android 12 manifest (
compileSdk 35)AGP enforces
android:exportedon any activity with an intent-filter whencompileSdk >= 31. Addedandroid:exported="true"toPreloaderActivity.SDL submodule dependency
The SDL submodule currently points to a commit on
robmat/SDL:ndk30-compat(theALooper_pollAllfix, see StoddardOXC/SDL#1). Before this PR is merged, the submodule pointer should be updated to point to the merged upstream commit inStoddardOXC/SDL.