mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			209 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import os
 | |
| import sys
 | |
| import platform
 | |
| import subprocess
 | |
| 
 | |
| from typing import TYPE_CHECKING
 | |
| 
 | |
| if TYPE_CHECKING:
 | |
|     from SCons import Environment
 | |
| 
 | |
| 
 | |
| def get_name():
 | |
|     return "Android"
 | |
| 
 | |
| 
 | |
| def can_build():
 | |
|     return os.path.exists(get_env_android_sdk_root())
 | |
| 
 | |
| 
 | |
| def get_opts():
 | |
|     from SCons.Variables import BoolVariable
 | |
| 
 | |
|     return [
 | |
|         ("ANDROID_HOME", "Path to the Android SDK", get_env_android_sdk_root()),
 | |
|         (
 | |
|             "ndk_platform",
 | |
|             'Target platform (android-<api>, e.g. "android-' + str(get_min_target_api()) + '")',
 | |
|             "android-" + str(get_min_target_api()),
 | |
|         ),
 | |
|         BoolVariable("store_release", "Editor build for Google Play Store (for official builds only)", False),
 | |
|     ]
 | |
| 
 | |
| 
 | |
| def get_doc_classes():
 | |
|     return [
 | |
|         "EditorExportPlatformAndroid",
 | |
|     ]
 | |
| 
 | |
| 
 | |
| def get_doc_path():
 | |
|     return "doc_classes"
 | |
| 
 | |
| 
 | |
| # Return the ANDROID_HOME environment variable.
 | |
| def get_env_android_sdk_root():
 | |
|     return os.environ.get("ANDROID_HOME", os.environ.get("ANDROID_SDK_ROOT", ""))
 | |
| 
 | |
| 
 | |
| def get_min_sdk_version(platform):
 | |
|     return int(platform.split("-")[1])
 | |
| 
 | |
| 
 | |
| def get_android_ndk_root(env):
 | |
|     return env["ANDROID_HOME"] + "/ndk/" + get_ndk_version()
 | |
| 
 | |
| 
 | |
| # This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
 | |
| def get_ndk_version():
 | |
|     return "23.2.8568313"
 | |
| 
 | |
| 
 | |
| # This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
 | |
| def get_min_target_api():
 | |
|     return 21
 | |
| 
 | |
| 
 | |
| def get_flags():
 | |
|     return [
 | |
|         ("arch", "arm64"),  # Default for convenience.
 | |
|         ("target", "template_debug"),
 | |
|     ]
 | |
| 
 | |
| 
 | |
| # Check if Android NDK version is installed
 | |
| # If not, install it.
 | |
| def install_ndk_if_needed(env):
 | |
|     print("Checking for Android NDK...")
 | |
|     sdk_root = env["ANDROID_HOME"]
 | |
|     if not os.path.exists(get_android_ndk_root(env)):
 | |
|         extension = ".bat" if os.name == "nt" else ""
 | |
|         sdkmanager = sdk_root + "/cmdline-tools/latest/bin/sdkmanager" + extension
 | |
|         if os.path.exists(sdkmanager):
 | |
|             # Install the Android NDK
 | |
|             print("Installing Android NDK...")
 | |
|             ndk_download_args = "ndk;" + get_ndk_version()
 | |
|             subprocess.check_call([sdkmanager, ndk_download_args])
 | |
|         else:
 | |
|             print("Cannot find " + sdkmanager)
 | |
|             print(
 | |
|                 "Please ensure ANDROID_HOME is correct and cmdline-tools are installed, or install NDK version "
 | |
|                 + get_ndk_version()
 | |
|                 + " manually."
 | |
|             )
 | |
|             sys.exit()
 | |
|     env["ANDROID_NDK_ROOT"] = get_android_ndk_root(env)
 | |
| 
 | |
| 
 | |
| def configure(env: "Environment"):
 | |
|     # Validate arch.
 | |
|     supported_arches = ["x86_32", "x86_64", "arm32", "arm64"]
 | |
|     if env["arch"] not in supported_arches:
 | |
|         print(
 | |
|             'Unsupported CPU architecture "%s" for Android. Supported architectures are: %s.'
 | |
|             % (env["arch"], ", ".join(supported_arches))
 | |
|         )
 | |
|         sys.exit()
 | |
| 
 | |
|     if get_min_sdk_version(env["ndk_platform"]) < get_min_target_api():
 | |
|         print(
 | |
|             "WARNING: minimum supported Android target api is %d. Forcing target api %d."
 | |
|             % (get_min_target_api(), get_min_target_api())
 | |
|         )
 | |
|         env["ndk_platform"] = "android-" + str(get_min_target_api())
 | |
| 
 | |
|     install_ndk_if_needed(env)
 | |
|     ndk_root = env["ANDROID_NDK_ROOT"]
 | |
| 
 | |
|     # Architecture
 | |
| 
 | |
|     if env["arch"] == "arm32":
 | |
|         target_triple = "armv7a-linux-androideabi"
 | |
|     elif env["arch"] == "arm64":
 | |
|         target_triple = "aarch64-linux-android"
 | |
|     elif env["arch"] == "x86_32":
 | |
|         target_triple = "i686-linux-android"
 | |
|     elif env["arch"] == "x86_64":
 | |
|         target_triple = "x86_64-linux-android"
 | |
| 
 | |
|     target_option = ["-target", target_triple + str(get_min_sdk_version(env["ndk_platform"]))]
 | |
|     env.Append(ASFLAGS=[target_option, "-c"])
 | |
|     env.Append(CCFLAGS=target_option)
 | |
|     env.Append(LINKFLAGS=target_option)
 | |
| 
 | |
|     # LTO
 | |
| 
 | |
|     if env["lto"] == "auto":  # LTO benefits for Android (size, performance) haven't been clearly established yet.
 | |
|         env["lto"] = "none"
 | |
| 
 | |
|     if env["lto"] != "none":
 | |
|         if env["lto"] == "thin":
 | |
|             env.Append(CCFLAGS=["-flto=thin"])
 | |
|             env.Append(LINKFLAGS=["-flto=thin"])
 | |
|         else:
 | |
|             env.Append(CCFLAGS=["-flto"])
 | |
|             env.Append(LINKFLAGS=["-flto"])
 | |
| 
 | |
|     # Compiler configuration
 | |
| 
 | |
|     env["SHLIBSUFFIX"] = ".so"
 | |
| 
 | |
|     if env["PLATFORM"] == "win32":
 | |
|         env.use_windows_spawn_fix()
 | |
| 
 | |
|     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"
 | |
| 
 | |
|     toolchain_path = ndk_root + "/toolchains/llvm/prebuilt/" + host_subpath
 | |
|     compiler_path = toolchain_path + "/bin"
 | |
| 
 | |
|     env["CC"] = compiler_path + "/clang"
 | |
|     env["CXX"] = compiler_path + "/clang++"
 | |
|     env["AR"] = compiler_path + "/llvm-ar"
 | |
|     env["RANLIB"] = compiler_path + "/llvm-ranlib"
 | |
|     env["AS"] = compiler_path + "/clang"
 | |
| 
 | |
|     env.Append(
 | |
|         CCFLAGS=(
 | |
|             "-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing".split()
 | |
|         )
 | |
|     )
 | |
| 
 | |
|     if get_min_sdk_version(env["ndk_platform"]) >= 24:
 | |
|         env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
 | |
| 
 | |
|     if env["arch"] == "x86_32":
 | |
|         # The NDK adds this if targeting API < 24, so we can drop it when Godot targets it at least
 | |
|         env.Append(CCFLAGS=["-mstackrealign"])
 | |
|     elif env["arch"] == "arm32":
 | |
|         env.Append(CCFLAGS="-march=armv7-a -mfloat-abi=softfp".split())
 | |
|         env.Append(CPPDEFINES=["__ARM_ARCH_7__", "__ARM_ARCH_7A__"])
 | |
|         env.Append(CPPDEFINES=["__ARM_NEON__"])
 | |
|     elif env["arch"] == "arm64":
 | |
|         env.Append(CCFLAGS=["-mfix-cortex-a53-835769"])
 | |
|         env.Append(CPPDEFINES=["__ARM_ARCH_8A__"])
 | |
| 
 | |
|     # Link flags
 | |
| 
 | |
|     env.Append(LINKFLAGS="-Wl,--gc-sections -Wl,--no-undefined -Wl,-z,now".split())
 | |
|     env.Append(LINKFLAGS="-Wl,-soname,libgodot_android.so")
 | |
| 
 | |
|     env.Prepend(CPPPATH=["#platform/android"])
 | |
|     env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"])
 | |
|     env.Append(LIBS=["OpenSLES", "EGL", "android", "log", "z", "dl"])
 | |
| 
 | |
|     if env["vulkan"]:
 | |
|         env.Append(CPPDEFINES=["VULKAN_ENABLED"])
 | |
|         if not env["use_volk"]:
 | |
|             env.Append(LIBS=["vulkan"])
 | |
| 
 | |
|     if env["opengl3"]:
 | |
|         env.Append(CPPDEFINES=["GLES3_ENABLED"])
 | |
|         env.Append(LIBS=["GLESv3"])
 | 
