- 头部:`14 个提交,HEAD 38d3024` 是写文档那一刻的自我指涉,永远不可能对——改成 `15 个提交,分叉点 87ab878,合并前 HEAD e987e02`。 - 合并指南第 1 步原来写 `git rebase origin/dev`,实际按用户令走 `--no-ff` 合并 (原 15 个提交一字未改地留在历史里,便于按组 revert),改为记录既成事实与 零文本冲突的交集(Cargo.lock / 两个 README / app-iced 的 Cargo.toml)。 - 新增第 6 条:PC 门禁发现、已就地修掉的两处——cfg(unix) 测试导入未 gate 导致 Windows clippy 判错;两个文件越 400 行红线后的拆分。这两条在 Termux 上跑门禁看不出来, 写进合并指南,免得下一个人以为「本机绿了就等于 PC 绿」。
9.0 KiB
9.0 KiB
Termux 适配:方案、改动清单与合并指南
分支:
termux-glibc(基于origin/dev,15 个提交,分叉点87ab878,合并前 HEADe987e02) 目的:让主线快速了解这组代码改了什么、为什么、怎么验证、如何合并。
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定位,幂等(已装则不走网络)。
- 内置 SAU / TUNA / USTC / 官方四个 termux-main 镜像,按顺序
- 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 桌面不会触发。
合并指南
→ 实际按用户令走git fetch origin && git rebase origin/dev--no-ff合并 (M156):git merge --no-ff origin/termux-glibc,15 个原提交一字未改地留在历史里, 按平台识别 → 字体 → 文档 → Java → GPU → natives → MC 的分组可整组 revert。 与 dev 前进的 12 个提交零文本冲突(交集只有Cargo.lock/ 两个 README /crates/app-iced/Cargo.toml)。- PR base:
dev。CI 门禁:fmt/clippy --workspace --all-targets -D warnings/test --workspace --all-targets/cargo deny(本机没装 deny,PC 上补跑)。 - 本机已知、不影响 PC CI 的三条失败:
unlucky-core --test launch:/proc/<pid>/task/<pid>/children(Android 内核没有)- 同测试:长路径被脱敏成
<opaque> presenter settings_bridge:mtime 热重载偶发(flaky,单跑 3 次 2 过 1 挂)
- 不要提交:
dist/、.gnu/、任何ULL_MSA_CLIENT_ID值(仓库 Secret)。 - 合并后建议真机再跑一次:
--software-renderer截图 +ull java install 17+ MC 启动。 - PC 门禁发现的两处、已在 M156 就地修掉(都只在 Windows/PC 侧才暴露,
所以在 Termux 上跑门禁看不出来):
game/java/discover.rs的两个#[cfg(unix)]测试,导入没跟着 gate → Windows 上-D warnings判「未使用导入」。已把两个use同样 gate 成#[cfg(unix)]; 代价是这两个用例在 Windows 上不编译(由 Linux CI 覆盖)。- 本分支把
game/java/install.rs(456 行)与game/install/libraries.rs(409 行) 顶过了 400 行红线(guards.yml的file-size)。已按步骤拆出install/termux_install.rs、install/one.rs、install/libraries/arm64_natives.rs, 行为不变、用例原样留在原处。
验证矩阵(本机)
| 项 | 结果 |
|---|---|
| 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 零告警 |
后续路线
- MC 启动参数(主线功能,另行排期):当前
ull launch不接受自定义 JVM/游戏参数。 - MC 硬件 GL:修 glibc GLX 的 DRI3(让 zink 生效),或改用 VulkanMod。
- 剪贴板 / IME 在 termux-x11 下的行为验证。
- narrator/flite 与音频设备(当前缺失但不阻断)。
- GPU 驱动分发:目前每次都要按文档自编 Mesa;可考虑脚本化/预编译产物。
回滚策略
全部改动按提交分组(platform → fonts → docs → java → gpu → natives → mc), 可按组 revert;Termux 专属逻辑都有运行时/文件存在 gate,回滚不会波及 PC 路径。