80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
# file: scripts/build_android_rust.py
|
|
# version: 1
|
|
|
|
"""Build one Android Rust game entrypoint and stage it as Gradle jniLibs."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import pathlib
|
|
import subprocess
|
|
import sys
|
|
import zipfile
|
|
|
|
ABI_TO_TRIPLE = {
|
|
"arm64-v8a": "aarch64-linux-android",
|
|
"armeabi-v7a": "armv7-linux-androideabi",
|
|
"x86_64": "x86_64-linux-android",
|
|
"x86": "i686-linux-android",
|
|
}
|
|
GAME_TO_MODULE = {"reflex": "game-reflex-poc", "snake": "game-snake-poc"}
|
|
|
|
def read_sdl3_aar_name(properties_path: pathlib.Path) -> str:
|
|
"""Read the configured SDL3 AAR filename."""
|
|
for raw_line in properties_path.read_text(encoding="utf-8").splitlines():
|
|
line = raw_line.strip()
|
|
if line.startswith("sdl3AarName="):
|
|
return line.split("=", 1)[1].strip()
|
|
raise RuntimeError("sdl3AarName is missing from Android/gradle.properties")
|
|
|
|
def extract_sdl3_link_library(aar_path: pathlib.Path, abi: str, output_dir: pathlib.Path) -> pathlib.Path:
|
|
"""Extract the SDL3 shared library used only for the Rust linker search path."""
|
|
expected = f"jni/{abi}/libSDL3.so"
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
with zipfile.ZipFile(aar_path) as archive:
|
|
if expected not in archive.namelist():
|
|
raise RuntimeError(f"{expected} is missing from {aar_path}")
|
|
target = output_dir / "libSDL3.so"
|
|
target.write_bytes(archive.read(expected))
|
|
return target
|
|
|
|
def main() -> int:
|
|
"""Build the requested game entrypoint for one Android ABI."""
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("game", choices=sorted(GAME_TO_MODULE))
|
|
parser.add_argument("--abi", choices=sorted(ABI_TO_TRIPLE), default="arm64-v8a")
|
|
parser.add_argument("--release", action="store_true")
|
|
arguments = parser.parse_args()
|
|
root = pathlib.Path(__file__).resolve().parent.parent
|
|
aar_name = read_sdl3_aar_name(root / "Android" / "gradle.properties")
|
|
aar_path = root / "Android" / "libs" / aar_name
|
|
if not aar_path.is_file():
|
|
print(f"missing SDL3 AAR: {aar_path}", file=sys.stderr)
|
|
return 2
|
|
link_dir = root / "Android" / "build" / "rust-link" / arguments.abi
|
|
try:
|
|
extract_sdl3_link_library(aar_path, arguments.abi, link_dir)
|
|
except (OSError, RuntimeError, zipfile.BadZipFile) as error:
|
|
print(str(error), file=sys.stderr)
|
|
return 2
|
|
module = GAME_TO_MODULE[arguments.game]
|
|
output = root / "Android" / module / "src" / "main" / "jniLibs"
|
|
environment = os.environ.copy()
|
|
rustflags = environment.get("RUSTFLAGS", "").strip()
|
|
link_flag = f"-L native={link_dir}"
|
|
environment["RUSTFLAGS"] = f"{rustflags} {link_flag}".strip()
|
|
environment["CARGO_NDK_PLATFORM"] = "21"
|
|
command = [
|
|
"cargo", "ndk", "-t", arguments.abi, "-o", str(output), "build",
|
|
"-p", "game-android-entrypoint", "--no-default-features", "--features", arguments.game,
|
|
]
|
|
if arguments.release:
|
|
command.append("--release")
|
|
completed = subprocess.run(command, cwd=root, env=environment, check=False)
|
|
return completed.returncode
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|