From 284d0332dd9a667104efab7b40e6f9a36b98abf2 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Wed, 7 May 2025 12:58:24 -0400 Subject: [PATCH 1/7] Annual versions bump for the Android platform - gradle: 8.2 -> 8.11.1 - androidx.constraintlayout:constraintlayout: 2.1.4 -> 2.2.1 - Android gradle plugin: 8.2.0 -> 8.6.1 - Android compile sdk: 34 -> 35 - Android target sdk: 34 -> 35 - Android build tools: 34.0.0 -> 35.0.0 - kotlin: 1.9.20 -> 2.1.20 - androidx.fragment:fragment: 1.7.1 -> 1.8.6 - OpenXR vendors plugin: 3.1.2-stable -> 4.0.0-stable --- .gitignore | 1 + platform/android/export/export_plugin.cpp | 2 +- platform/android/java/app/build.gradle | 2 +- platform/android/java/app/config.gradle | 14 +++++++------- platform/android/java/app/settings.gradle | 3 ++- platform/android/java/editor/build.gradle | 2 +- .../java/gradle/wrapper/gradle-wrapper.properties | 2 +- platform/android/java/settings.gradle | 4 ++-- 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 8adc7b786c6..97cf4e62555 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,7 @@ local.properties *.iml .gradletasknamecache project.properties +platform/android/java/build/ platform/android/java/*/.cxx/ platform/android/java/*/build/ platform/android/java/*/libs/ diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 4a3b1fc0984..490b5c14a2d 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -287,7 +287,7 @@ static const char *AAB_ASSETS_DIRECTORY = "assetPacks/installTime/src/main/asset static const int OPENGL_MIN_SDK_VERSION = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' static const int VULKAN_MIN_SDK_VERSION = 24; -static const int DEFAULT_TARGET_SDK_VERSION = 34; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' +static const int DEFAULT_TARGET_SDK_VERSION = 35; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' #ifndef ANDROID_ENABLED void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) { diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index d4c62dad3c0..f17a3015cde 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -90,7 +90,7 @@ android { jvmTarget = versions.javaVersion } - assetPacks = [":assetPacks:installTime"] + assetPacks = [":assetPacksInstallTime"] namespace = 'com.godot.game' diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 52c47c5d395..db5a5e0b8df 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,19 +1,19 @@ ext.versions = [ - androidGradlePlugin: '8.2.0', - compileSdk : 34, + androidGradlePlugin: '8.6.1', + compileSdk : 35, // Also update 'platform/android/export/export_plugin.cpp#OPENGL_MIN_SDK_VERSION' minSdk : 21, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' - targetSdk : 34, - buildTools : '34.0.0', - kotlinVersion : '1.9.20', - fragmentVersion : '1.7.1', + targetSdk : 35, + buildTools : '35.0.0', + kotlinVersion : '2.1.20', + fragmentVersion : '1.8.6', nexusPublishVersion: '1.3.0', javaVersion : JavaVersion.VERSION_17, // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated. ndkVersion : '23.2.8568313', splashscreenVersion: '1.0.1', - openxrVendorsVersion: '3.1.2-stable' + openxrVendorsVersion: '4.0.0-stable' ] diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle index e758d4e99a7..9c7a8149aed 100644 --- a/platform/android/java/app/settings.gradle +++ b/platform/android/java/app/settings.gradle @@ -15,4 +15,5 @@ pluginManagement { } } -include ':assetPacks:installTime' +include ':assetPacksInstallTime' +project(':assetPacksInstallTime').projectDir = file("assetPacks/installTime") diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle index bfc123c8cd8..d0fc08e47fa 100644 --- a/platform/android/java/editor/build.gradle +++ b/platform/android/java/editor/build.gradle @@ -184,7 +184,7 @@ dependencies { implementation "androidx.window:window:1.3.0" implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion" - implementation "androidx.constraintlayout:constraintlayout:2.1.4" + implementation "androidx.constraintlayout:constraintlayout:2.2.1" implementation "org.bouncycastle:bcprov-jdk15to18:1.78" // Meta dependencies diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties index 471fefaf905..642629c8b84 100644 --- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Jan 17 12:08:26 PST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/platform/android/java/settings.gradle b/platform/android/java/settings.gradle index 41418a4a45e..46476137823 100644 --- a/platform/android/java/settings.gradle +++ b/platform/android/java/settings.gradle @@ -25,5 +25,5 @@ include ':lib' include ':nativeSrcsConfigs' include ':editor' -include ':assetPacks:installTime' -project(':assetPacks:installTime').projectDir = file("app/assetPacks/installTime") +include ':assetPacksInstallTime' +project(':assetPacksInstallTime').projectDir = file("app/assetPacks/installTime") From 0e7b0677017cd9afd3ee79e3ce8ffe6d9f57f040 Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Sun, 11 May 2025 21:02:44 +0200 Subject: [PATCH 2/7] [Android] Store native libraries uncompressed in APK --- platform/android/export/export_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 490b5c14a2d..9b2329dab61 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -791,7 +791,7 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj String abi = abis[abi_index].abi; String dst_path = String("lib").path_join(abi).path_join(p_so.path.get_file()); Vector array = FileAccess::get_file_as_bytes(p_so.path); - Error store_err = store_in_apk(ed, dst_path, array); + Error store_err = store_in_apk(ed, dst_path, array, Z_NO_COMPRESSION); ERR_FAIL_COND_V_MSG(store_err, store_err, "Cannot store in apk file '" + dst_path + "'."); } } From 731fa536fe9f7a28d470c7d52ae95469ede64e86 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Sun, 20 Apr 2025 23:51:10 -0700 Subject: [PATCH 3/7] Update the project NDK to the latest LTS version (r27c) --- platform/android/SCsub | 32 ++++++++++++++----- platform/android/detect.py | 2 +- platform/android/java/app/config.gradle | 2 +- .../java/scripts/publish-module.gradle | 6 +++- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/platform/android/SCsub b/platform/android/SCsub index 2260a84a760..c859373eaa0 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -1,6 +1,7 @@ #!/usr/bin/env python from misc.utility.scons_hints import * +import platform import subprocess import sys @@ -50,18 +51,34 @@ lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSU env.Depends(lib, thirdparty_obj) lib_arch_dir = "" +triple_target_dir = "" if env["arch"] == "arm32": lib_arch_dir = "armeabi-v7a" + triple_target_dir = "arm-linux-androideabi" elif env["arch"] == "arm64": lib_arch_dir = "arm64-v8a" + triple_target_dir = "aarch64-linux-android" elif env["arch"] == "x86_32": lib_arch_dir = "x86" + triple_target_dir = "i686-linux-android" elif env["arch"] == "x86_64": lib_arch_dir = "x86_64" + triple_target_dir = "x86_64-linux-android" else: print_warning("Architecture not suitable for embedding into APK; keeping .so at \\bin") -if lib_arch_dir != "": +host_subpath = "" +if sys.platform.startswith("linux"): + host_subpath = "linux-x86_64" +elif sys.platform.startswith("darwin"): + host_subpath = "darwin-x86_64" +elif sys.platform.startswith("win"): + if platform.machine().endswith("64"): + host_subpath = "windows-x86_64" + else: + host_subpath = "windows" + +if lib_arch_dir != "" and host_subpath != "": if env.dev_build: lib_type_dir = "dev" elif env.debug_features: @@ -82,9 +99,7 @@ if lib_arch_dir != "": out_dir + "/libgodot_android.so", "#bin/libgodot" + env["SHLIBSUFFIX"], Move("$TARGET", "$SOURCE") ) - stl_lib_path = ( - str(env["ANDROID_NDK_ROOT"]) + "/sources/cxx-stl/llvm-libc++/libs/" + lib_arch_dir + "/libc++_shared.so" - ) + stl_lib_path = f"{env['ANDROID_NDK_ROOT']}/toolchains/llvm/prebuilt/{host_subpath}/sysroot/usr/lib/{triple_target_dir}/libc++_shared.so" env_android.Command(out_dir + "/libc++_shared.so", stl_lib_path, Copy("$TARGET", "$SOURCE")) def generate_apk(target, source, env): @@ -99,10 +114,11 @@ if lib_arch_dir != "": else: gradle_process = ["./gradlew"] - gradle_process += [ - "generateGodotEditor" if env["target"] == "editor" else "generateGodotTemplates", - "--quiet", - ] + if env["target"] == "editor": + gradle_process += ["generateGodotEditor", "generateGodotHorizonOSEditor", "generateGodotPicoOSEditor"] + else: + gradle_process += ["generateGodotTemplates"] + gradle_process += ["--quiet"] if env["debug_symbols"]: gradle_process += ["-PdoNotStrip=true"] diff --git a/platform/android/detect.py b/platform/android/detect.py index cac7c3f48d4..6ddc9179936 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -64,7 +64,7 @@ def get_android_ndk_root(env: "SConsEnvironment"): # This is kept in sync with the value in 'platform/android/java/app/config.gradle'. def get_ndk_version(): - return "23.2.8568313" + return "27.2.12479018" # This is kept in sync with the value in 'platform/android/java/app/config.gradle'. diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index db5a5e0b8df..197d5f82c4f 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -11,7 +11,7 @@ ext.versions = [ nexusPublishVersion: '1.3.0', javaVersion : JavaVersion.VERSION_17, // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated. - ndkVersion : '23.2.8568313', + ndkVersion : '27.2.12479018', splashscreenVersion: '1.0.1', openxrVendorsVersion: '4.0.0-stable' diff --git a/platform/android/java/scripts/publish-module.gradle b/platform/android/java/scripts/publish-module.gradle index 32b749e493d..c2c905a6e40 100644 --- a/platform/android/java/scripts/publish-module.gradle +++ b/platform/android/java/scripts/publish-module.gradle @@ -43,7 +43,11 @@ afterEvaluate { name = 'Rémi Verschelde' email = 'rverschelde@gmail.com' } - // Add all other devs here... + developer { + id = 'godotengine' + name = 'Godot Engine contributors' + email = 'contact@godotengine.org' + } } // Version control info - if you're using GitHub, follow the From cc7fbe6aec1611de4d6c0246145efdc574a596d4 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Tue, 13 May 2025 08:27:36 -0700 Subject: [PATCH 4/7] Bump the NDK to version 28.1.13356709 Doing so automatically adds support for 16kib page to the Godot Android shared libraries. See https://developer.android.com/guide/practices/page-sizes#compile-16-kb-alignment for details. --- platform/android/detect.py | 2 +- platform/android/java/app/config.gradle | 2 +- platform/android/java/nativeSrcsConfigs/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/android/detect.py b/platform/android/detect.py index 6ddc9179936..013b66a73b7 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -64,7 +64,7 @@ def get_android_ndk_root(env: "SConsEnvironment"): # This is kept in sync with the value in 'platform/android/java/app/config.gradle'. def get_ndk_version(): - return "27.2.12479018" + return "28.1.13356709" # This is kept in sync with the value in 'platform/android/java/app/config.gradle'. diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 197d5f82c4f..77e63df2f38 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -11,7 +11,7 @@ ext.versions = [ nexusPublishVersion: '1.3.0', javaVersion : JavaVersion.VERSION_17, // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated. - ndkVersion : '27.2.12479018', + ndkVersion : '28.1.13356709', splashscreenVersion: '1.0.1', openxrVendorsVersion: '4.0.0-stable' diff --git a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt index a5ecafeb09d..1584c6fd5ce 100644 --- a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt +++ b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt @@ -1,5 +1,5 @@ # Non functional cmake build file used to provide Android Studio editor support to the project. -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.10) project(godot) set(CMAKE_CXX_STANDARD 14) From 8f2ad2eb427217432a5f223cf33222a9b8162d93 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Mon, 19 May 2025 10:50:43 -0700 Subject: [PATCH 5/7] Update to the AAB directory layout Follow-up to https://github.com/godotengine/godot/pull/106152 to address the regression described in https://github.com/godotengine/godot/issues/106582 --- platform/android/export/export_plugin.cpp | 2 +- .../installTime => assetPackInstallTime}/build.gradle | 2 +- platform/android/java/app/build.gradle | 2 +- platform/android/java/app/settings.gradle | 3 +-- platform/android/java/settings.gradle | 4 ++-- 5 files changed, 6 insertions(+), 7 deletions(-) rename platform/android/java/app/{assetPacks/installTime => assetPackInstallTime}/build.gradle (65%) diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 9b2329dab61..89befcc277e 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -283,7 +283,7 @@ static const int EXPORT_FORMAT_APK = 0; static const int EXPORT_FORMAT_AAB = 1; static const char *APK_ASSETS_DIRECTORY = "assets"; -static const char *AAB_ASSETS_DIRECTORY = "assetPacks/installTime/src/main/assets"; +static const char *AAB_ASSETS_DIRECTORY = "assetPackInstallTime/src/main/assets"; static const int OPENGL_MIN_SDK_VERSION = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' static const int VULKAN_MIN_SDK_VERSION = 24; diff --git a/platform/android/java/app/assetPacks/installTime/build.gradle b/platform/android/java/app/assetPackInstallTime/build.gradle similarity index 65% rename from platform/android/java/app/assetPacks/installTime/build.gradle rename to platform/android/java/app/assetPackInstallTime/build.gradle index 46fa046ed4f..f10ddb340c7 100644 --- a/platform/android/java/app/assetPacks/installTime/build.gradle +++ b/platform/android/java/app/assetPackInstallTime/build.gradle @@ -3,7 +3,7 @@ plugins { } assetPack { - packName = "installTime" // Directory name for the asset pack + packName = "assetPackInstallTime" // Directory name for the asset pack dynamicDelivery { deliveryType = "install-time" // Delivery mode } diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index f17a3015cde..1501b0fd344 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -90,7 +90,7 @@ android { jvmTarget = versions.javaVersion } - assetPacks = [":assetPacksInstallTime"] + assetPacks = [":assetPackInstallTime"] namespace = 'com.godot.game' diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle index 9c7a8149aed..63183d2d5d0 100644 --- a/platform/android/java/app/settings.gradle +++ b/platform/android/java/app/settings.gradle @@ -15,5 +15,4 @@ pluginManagement { } } -include ':assetPacksInstallTime' -project(':assetPacksInstallTime').projectDir = file("assetPacks/installTime") +include ':assetPackInstallTime' diff --git a/platform/android/java/settings.gradle b/platform/android/java/settings.gradle index 46476137823..e2ed6f0a899 100644 --- a/platform/android/java/settings.gradle +++ b/platform/android/java/settings.gradle @@ -25,5 +25,5 @@ include ':lib' include ':nativeSrcsConfigs' include ':editor' -include ':assetPacksInstallTime' -project(':assetPacksInstallTime').projectDir = file("app/assetPacks/installTime") +include ':assetPackInstallTime' +project(':assetPackInstallTime').projectDir = file("app/assetPackInstallTime") From c5db2cfec29de1b23aac1cacfac3584aea383c5c Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Thu, 4 Sep 2025 21:42:35 +0200 Subject: [PATCH 6/7] [.NET] Require `net9.0` for Android exports To ensure Android exports are compatible with the new Play Store requirement that all `.so` libraries included are aligned to 16k, we now require C# projects to target `net9.0` which uses the correct alignment (as opposed to the current one of 4k). The thirdparty jar library has also been updated to the one from the 9.0.4 runtime package so it's compatible with non-gradle builds targeting `net9.0`. Non-android projects are not affect, the minimum TFM is still `net8.0`. --- .../ProjectGenerator.cs | 4 ++++ ...m.Security.Cryptography.Native.Android.jar | Bin 8552 -> 12999 bytes ...Cryptography.Native.Android.jar.source.txt | 1 + platform/android/export/export_plugin.cpp | 7 ++++--- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 modules/mono/thirdparty/libSystem.Security.Cryptography.Native.Android.jar.source.txt diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs index e969f31c8bc..b4992d0bf48 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs @@ -26,6 +26,10 @@ namespace GodotTools.ProjectEditor var mainGroup = root.AddPropertyGroup(); mainGroup.AddProperty("TargetFramework", GodotMinimumRequiredTfm); + // Non-gradle builds require .NET 9 to match the jar libraries included in the export template. + var net9 = mainGroup.AddProperty("TargetFramework", "net9.0"); + net9.Condition = " '$(GodotTargetPlatform)' == 'android' "; + mainGroup.AddProperty("EnableDynamicLoading", "true"); string sanitizedName = IdentifierUtils.SanitizeQualifiedIdentifier(name, allowEmptyIdentifiers: true); diff --git a/modules/mono/thirdparty/libSystem.Security.Cryptography.Native.Android.jar b/modules/mono/thirdparty/libSystem.Security.Cryptography.Native.Android.jar index 736603088187993cf62014b17e619502133dc211..7dd662be19553489e94d4e051a81bb209413337c 100755 GIT binary patch literal 12999 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 C;lyVE diff --git a/modules/mono/thirdparty/libSystem.Security.Cryptography.Native.Android.jar.source.txt b/modules/mono/thirdparty/libSystem.Security.Cryptography.Native.Android.jar.source.txt new file mode 100644 index 00000000000..188b63e09dd --- /dev/null +++ b/modules/mono/thirdparty/libSystem.Security.Cryptography.Native.Android.jar.source.txt @@ -0,0 +1 @@ +https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.android-arm64/9.0.4 diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 89befcc277e..77466612a47 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -2542,6 +2542,7 @@ bool _validate_dotnet_tfm(const String &required_tfm, String &r_error) { List args; args.push_back("build"); args.push_back(project_path); + args.push_back("/p:GodotTargetPlatform=android"); args.push_back("--getProperty:TargetFramework"); int exitcode; @@ -2576,9 +2577,9 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref Date: Thu, 4 Sep 2025 10:56:35 -0700 Subject: [PATCH 7/7] Fix the issue preventing installing C# binaries on Android devices with api <= 29 --- platform/android/java/app/config.gradle | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 77e63df2f38..d37a33b47ee 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -411,7 +411,13 @@ ext.shouldUseLegacyPackaging = { -> return Boolean.parseBoolean(legacyPackagingFlag) } - // Default behavior for minSdk >= 23 + if (getExportMinSdkVersion() <= 29) { + // Use legacy packaging for compatibility with device running api <= 29. + // See https://github.com/godotengine/godot/issues/108842 for reference. + return true + } + + // Default behavior for minSdk > 29. return false }