diff --git a/README.termux.md b/README.termux.md index c874f97..14d54ed 100644 --- a/README.termux.md +++ b/README.termux.md @@ -3,6 +3,9 @@ 这条分支把启动器带到 **Termux(Android)**:用 glibc 工具链编出 `aarch64-unknown-linux-gnu` 二进制,在 **termux-x11** 里跑 GUI;同时补上 Termux 平台识别、系统 JDK 安装与中文字体。 +> 给主线的改动清单、兼容性说明与合并指南见 +> [`TERMUX-ADAPTATION.md`](TERMUX-ADAPTATION.md)。 + ## 已验证 | 项 | 状态 | 证据 | diff --git a/TERMUX-ADAPTATION.md b/TERMUX-ADAPTATION.md new file mode 100644 index 0000000..1048010 --- /dev/null +++ b/TERMUX-ADAPTATION.md @@ -0,0 +1,132 @@ +# Termux 适配:方案、改动清单与合并指南 + +> 分支:`termux-glibc`(基于 `origin/dev`,14 个提交,HEAD `38d3024`) +> 目的:让主线快速了解这组代码改了什么、为什么、怎么验证、如何合并。 + +## TL;DR + +- **构建**:为 Termux 编出 `aarch64-unknown-linux-gnu`(glibc)二进制,在 termux-x11 里跑 GUI。 + Android 原生 target 走不通(winit 的 android 后端需要 NativeActivity),所以不用它。 +- **已跑通**:GUI(CPU 与 GPU 两条渲染路径)、中文、横屏自适应、JDK 发现与系统包安装、 + MC 1.20.4(glibc JRE + arm64 natives + softpipe GL,真机进游戏)。 +- **未收口**:MC 启动参数支持(由主线后续补)、MC 硬件 GL(zink 卡 DRI3)、剪贴板/IME。 +- **对主线的影响**:所有行为都由 **运行时 Termux 识别 / `cfg(target_os = "linux")` / + 文件存在** 三选一 gate 住,Windows / macOS / 普通 Linux 的默认路径不变。 + +## 方案 + +### 1. 平台识别 + +`crates/core/src/platform/termux.rs`:用 `TERMUX_VERSION` 或默认 `PREFIX` +(`/data/data/com.termux/files/usr`)识别 Termux,推导 `$PREFIX` 与 `$PREFIX/lib/jvm`。 +不把路径写死到调用方,也不改 `OsFamily`(Android 上仍按 Linux 家族处理)。 + +### 2. JDK:发现 + 安装 + +- **发现**:`game/java/discover.rs` 的 Unix 扫描根追加 `$PREFIX/lib/jvm`, + 环境可注入(`standard_roots_in`)。补上「Termux 装了 openjdk 但没设 JAVA_HOME/PATH」的盲点。 +- **安装**:新增 `game/java/termux.rs`。Termux 的 openjdk 是 `.deb`(bionic), + 与 Temurin 的 zip/tar.gz 不是同一形态,所以**委托包管理器**: + - 内置 SAU / TUNA / USTC / 官方四个 termux-main 镜像,按顺序 `apt-get update && install`; + - lists/cache 隔离在 `$PREFIX/tmp/ull-java-termux/`,不污染用户 apt 配置;装完清理; + - 装完从 `$PREFIX/lib/jvm` 定位,幂等(已装则不走网络)。 +- **vendor 接线**:`JdkVendor::Termux`(17/21/25)。Termux 上缺省安装先试系统包, + 失败再走归档链;`--vendor termux` 只走系统包。设置白名单与契约测试同步。 + +### 3. 字体 + +`crates/app-iced/src/fonts.rs`:Termux 上把 `/system/fonts/NotoSansCJK-Regular.ttc` +注册进 cosmic-text(fontdb 不扫 Android 字体目录),中文不再显示方框。 + +### 4. 窗口(横屏优先) + +`app/boot/termux_window.rs`:Termux 上默认窗口按当前 X 屏幕等比自适应 +(日志 `size_source=termux-screen`),横屏铺满、竖屏不溢出; +`ULL_WINDOW_SIZE` 覆盖与 1180×760 验收基准不变。 + +### 5. GPU(启动器) + +- 驱动是自编的 **Mesa 26.2.6 + KGSL**,装在 `$PREFIX/glibc/{lib,share/vulkan/icd.d}`; + 构建/安装步骤见 `packaging/docs/termux-glibc-build.md` §5。 +- `app/boot/termux_gpu.rs`:glibc 构建 + Termux + ICD 文件存在时,在探测前设 + `VK_ICD_FILENAMES` / `VK_DRIVER_FILES`;用户显式设置不覆盖。 +- 实测 wgpu 选中 Adreno 840(turnip Mesa 26.2.6);无驱动自动降级 tiny-skia。 + +### 6. Minecraft 运行链 + +- **natives**:1.19+ 的清单把 natives 作为独立库条目(`org.lwjgl:...:natives-linux`), + Linux/aarch64 上改写成 `natives-linux-arm64`(`Library::linux_arm64_native_name`, + install 与 launch 共用);Mojang 的 `libraries.minecraft.net` 对 arm64 一律 404, + 下载兜底到阿里云 Maven(`install/libraries.rs`)。 +- **JVM**:用 glibc 的 Temurin JRE(patchelf 后直接执行),bionic 的 Termux JVM + 加载不了 glibc natives。 +- **GL**:glibc Mesa 的 zink 在 termux-x11 下卡 `DRI3 not available`, + 子进程默认带 `MESA_LOADER_DRIVER_OVERRIDE=swrast` + `LIBGL_ALWAYS_SOFTWARE=1` + (`launch/defaults.rs`,用户自定义环境变量可覆盖)。 + +## 改动清单 + +| 文件 | 改动 | 平台隔离 | +| --- | --- | --- | +| `core/platform/termux.rs`(新) | Termux 识别、`$PREFIX`/JVM 根 | 纯函数,按环境判断 | +| `core/platform/mod.rs` | 导出新模块 | — | +| `core/game/java/discover.rs` | `$PREFIX/lib/jvm` 扫描 | Unix + Termux 判断 | +| `core/game/java/termux.rs`(新) | 镜像/隔离 apt 安装、`installed_home` | 仅 Termux 可执行 | +| `core/game/java/vendor.rs` / `source.rs` / `install.rs` | `JdkVendor::Termux` 与安装分派 | Termux 上才启用 | +| `core/setting/keys.rs` + 契约测试 | 白名单加 `termux` | 跨平台可选,非 Termux 明确报错 | +| `cli/commands/java_vendors.rs`、`cli/cli/help.rs`、`presenter/host/java.rs` | 展示与帮助文案 | 展示层 | +| `core/game/library.rs` | `linux_arm64_native_name` / 分类器改写 | 仅 linux+arm64 | +| `core/game/install/libraries.rs` | 现代 natives 条目改写 + Maven 兜底 | 仅 linux+arm64 | +| `core/launch/defaults.rs` | Termux softpipe 环境默认值 | `cfg(linux)` + Termux | +| `presenter/host/launch.rs`、`cli/commands/snapshot.rs` | classpath 用改写后的 arm64 坐标 | 仅 linux+arm64 | +| `app-iced/fonts.rs` | Android CJK 字体注册 | 仅 Termux | +| `app-iced/boot/termux_window.rs`(新) | 横屏自适应 | 仅 Termux | +| `app-iced/boot/termux_gpu.rs`(新) | 自动启用自编 ICD | 仅 glibc+Termux+文件存在 | +| `app-iced/Cargo.toml` | 新增 `unlucky-core` 依赖 | 复用平台识别 | +| `README.termux.md`(新)、`packaging/docs/termux-glibc-build.md`(新) | 分支说明与构建配方 | 文档 | +| `README.md` / `README.zh-CN.md` / 支持矩阵两处 | Termux 行同步 | 文档 | + +## 行为变化与兼容性 + +- 新增 `JdkVendor::Termux` 会改变 `VENDOR_IDS` / `JDK_VENDORS` 的允许值集合 + (契约测试已同步)。非 Termux 上显式选它会在安装时明确报「只在 Termux 里可用」, + 默认回退序**不含** termux,PC 行为不变。 +- Linux/aarch64 的 LWJGL3 natives 会被改写;x86_64、Windows、macOS 不受影响。 +- `app-iced` 直接依赖 `unlucky-core`(此前通过 cli/presenter 间接依赖)。 +- 所有 Termux 专属路径都需要运行时识别或文件存在才会生效;普通 Linux 桌面不会触发。 + +## 合并指南 + +1. `git fetch origin && git rebase origin/dev`(分支基于 `7d8b3b9` 之后的 dev; + dev 若前进,先 rebase 再推)。 +2. PR base:`dev`。CI 门禁:`fmt` / `clippy --workspace --all-targets -D warnings` / + `test --workspace --all-targets` / `cargo deny`(本机没装 deny,PC 上补跑)。 +3. 本机已知、**不影响 PC CI** 的三条失败: + - `unlucky-core --test launch`:`/proc//task//children`(Android 内核没有) + - 同测试:长路径被脱敏成 `` + - `presenter settings_bridge`:mtime 热重载偶发(flaky,单跑 3 次 2 过 1 挂) +4. **不要提交**:`dist/`、`.gnu/`、任何 `ULL_MSA_CLIENT_ID` 值(仓库 Secret)。 +5. 合并后建议真机再跑一次:`--software-renderer` 截图 + `ull java install 17` + MC 启动。 + +## 验证矩阵(本机) + +| 项 | 结果 | +| --- | --- | +| GUI 截图(横屏 1657×1067) | ✅ 中文正常,`client_id=configured source=build` | +| GPU 渲染 | ✅ wgpu 选中 Adreno 840(turnip Mesa 26.2.6);降级路径也验证过 | +| `ull java install 17` | ✅ SAU 镜像约 20 s,装完清理,`java list` 可见 | +| MC 1.20.4 | ✅ 真机安装(740 MB)→ 主菜单 → 建世界 → 进游戏 | +| fmt / clippy / 核心测试 | ✅ 475 条核心测试通过,clippy 零告警 | + +## 后续路线 + +1. **MC 启动参数**(主线功能,另行排期):当前 `ull launch` 不接受自定义 JVM/游戏参数。 +2. **MC 硬件 GL**:修 glibc GLX 的 DRI3(让 zink 生效),或改用 VulkanMod。 +3. 剪贴板 / IME 在 termux-x11 下的行为验证。 +4. narrator/flite 与音频设备(当前缺失但不阻断)。 +5. GPU 驱动分发:目前每次都要按文档自编 Mesa;可考虑脚本化/预编译产物。 + +## 回滚策略 + +全部改动按提交分组(platform → fonts → docs → java → gpu → natives → mc), +可按组 revert;Termux 专属逻辑都有运行时/文件存在 gate,回滚不会波及 PC 路径。