From fecff989e729e7cf6fc9b9b413524884d5d2c489 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Mon, 2 Nov 2026 00:41:19 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E4=BF=AE=E6=8E=89=E3=80=8C=E6=8A=8A?= =?UTF-8?q?=E6=B2=A1=E9=87=8F=E7=9A=84=E4=B8=9C=E8=A5=BF=E6=A0=87=E6=88=90?= =?UTF-8?q?=E5=AE=9E=E6=B5=8B=E3=80=8D=E7=9A=84=E5=9B=9B=E5=A4=84=E5=BC=95?= =?UTF-8?q?=E7=94=A8=EF=BC=88M82=20=E5=A4=8D=E5=AE=A1=20P2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 两个 GUI main.rs:把「不 dlopen 任何图形库」改成「不依赖任何图形库(缺失时不影响)」, 并把「实测见 §7」换成「§7.4 是依赖取证;耗时是结构性判断,没重量(§10-8)」 - packaging/README §1:§7.6(不存在)→ §7.4 - packaging/README §4:实测引用 §7.1 → §7.4(ELF 取证在 §7.4) - packaging/README §7.4 标题补 ELF DT_NEEDED,并记下复审在 bookworm-slim 里的真跑结果 - packaging/release-notes:ull 示例前补 chmod +x(Release 资产不带可执行位) --- crates/app-iced/src/main.rs | 5 +++-- crates/app/src/main.rs | 5 +++-- packaging/README.md | 11 ++++++++--- packaging/release-notes.md | 1 + 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/app-iced/src/main.rs b/crates/app-iced/src/main.rs index 2a4a46d..1965a58 100644 --- a/crates/app-iced/src/main.rs +++ b/crates/app-iced/src/main.rs @@ -42,8 +42,9 @@ fn main() -> ExitCode { /// 子命令命中 CLI 就跑 CLI 并以它的退出码收尾;返回 `None` 表示「这不是 CLI 调用,去开窗」。 /// -/// 这条路径上**不构造窗口、不探后端、不扫字体、不 dlopen 任何图形库**:服务器上 -/// `unlucky-launcher-iced launch …` 的耗时因此与首帧无关(实测见 packaging/README.md §7)。 +/// 这条路径上**不构造窗口、不探后端、不扫字体、不依赖任何图形库**(这些库缺失时同一条命令照样 +/// 跑完,实测见 packaging/README.md §7.4)。`unlucky-launcher-iced launch …` 的耗时因此与首帧无关—— +/// 这句是结构性判断,**没有重量**(原因见 §10-8)。 fn run_cli_if_requested(args: &[String]) -> Option { if !is_cli_invocation(args) { return None; diff --git a/crates/app/src/main.rs b/crates/app/src/main.rs index cd52129..644af3f 100644 --- a/crates/app/src/main.rs +++ b/crates/app/src/main.rs @@ -98,8 +98,9 @@ fn run_gui() -> Result<(), slint::PlatformError> { /// 子命令命中 CLI 就跑 CLI 并以它的退出码收尾;返回 `None` 表示「这不是 CLI 调用,去开窗」。 /// -/// 这条路径上**不构造窗口、不探后端、不扫字体、不 dlopen 任何图形库**:服务器上 -/// `unlucky-launcher launch …` 的耗时因此与首帧无关(实测见 packaging/README.md §7)。 +/// 这条路径上**不构造窗口、不探后端、不扫字体、不依赖任何图形库**(这些库缺失时同一条命令照样 +/// 跑完,实测见 packaging/README.md §7.4)。`unlucky-launcher launch …` 的耗时因此与首帧无关—— +/// 这句是结构性判断,**没有重量**(原因见 §10-8)。 fn run_cli_if_requested(args: &[String]) -> Option { if !is_cli_invocation(args) { return None; diff --git a/packaging/README.md b/packaging/README.md index a6f622d..eb9b13e 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -26,7 +26,7 @@ - **`ull` 是并列的裸资产,不塞进 tar.gz**:headless 用户要的就是「下一个小文件直接跑」;归档里放 LICENSE/NOTICE/README.md 是许可义务,而这三份本来就作为并列 Release 资产分发,裸 `ull` 不缺条款。 - `unlucky-launcher` 本体也认全部 CLI 子命令(M82),`ull` 不是第二个界面,而是**不链接图形栈**的 - 同一套命令(差异见 §4 与 §7.6)——两者都不是重复品。 + 同一套命令(差异见 §4 与 §7.4)——两者都不是重复品。 - `` 不带前导 `v`(tag 是 `v0.1.0`,文件名是 `0.1.0`)——由脚本统一裁剪。 - UNIX 归档内 `mtime`/`uid`/`gid` 归零、权限固定(二进制 0755、文本 0644), 同源构建的 sha256 不受打包时刻影响。 @@ -153,7 +153,7 @@ Windows ARM64 原生库(Mojang/LWJGL 只发 x64/x86),实际游玩仍走系 Debian/Ubuntu 一行:`sudo apt install libxkbcommon0 fontconfig libgl1 libegl1 libxcb1 libx11-6 libwayland-client0`。 运行期**不需要** `-dev` 包、不需要 Java(Java 是启动游戏时才由启动器自己管理的东西)。 -上表是**开窗**要用的库,不是进程启动时就要的:实测(§7.1)除 `libfontconfig.so.1` 外它们**都不在** ELF +上表是**开窗**要用的库,不是进程启动时就要的:实测(§7.4)除 `libfontconfig.so.1` 外它们**都不在** ELF 的 `DT_NEEDED` 里,由 `dlopen` 在创建窗口那一刻才加载。所以同一台没有 X11 / Wayland / GL 的机器上 `unlucky-launcher instances list` 照样跑得起来(GUI 二进制先分发后开窗),而 `ull` 连 fontconfig 都不需要。 arm64 侧是同一套(同一份依赖树、同一个 winit/femtovg 组合)。 @@ -264,7 +264,7 @@ reviewer-packaging 在 M46 review 里连续调 `stage_archive()` 两次 → ** `00000000`,归档内单顶层目录且含 `LICENSE`/`NOTICE`/`README.md`。 即"同源构建 → 同 sha256"在 tar 路径上成立,不随打包时刻漂移(见 §1 的约定细节)。 -### 7.4 运行时依赖证据(PE 导入表) +### 7.4 运行时依赖证据(PE 导入表 / ELF `DT_NEEDED`) `objdump -p target/release/unlucky-launcher.exe` 共 42 条 DLL 导入记录、33 个不同名字(大小写各记一次),全部是 Windows 自带: `KERNEL32/USER32/GDI32/ADVAPI32/SHELL32/SHLWAPI/ole32/oleaut32/combase/comctl32/dwmapi/dwrite/imm32/ @@ -285,6 +285,11 @@ GUI 的 ELF `DT_NEEDED` 只有 `libfontconfig.so.1` / `libgcc_s.so.1` / `libm.so `dlsym` / `dlclose`)。所以 §4 那张「开窗要的库」不是启动前提,缺了也不影响进程起来跑 CLI; `ull` 的 `DT_NEEDED` 连 fontconfig 都没有,只剩 glibc 那一组。 +**补一次真跑(M82 复审在 `debian:bookworm-slim` 上做的)**:镜像里 X11 / wayland / GL / EGL / xkbcommon / +libxcb 条目数 = 0,只把 fontconfig 那 7 个 `.so` 放进 `LD_LIBRARY_PATH`,跑**改动后**的二进制 → `--version` +与 `--help` exit 0、`instances list --json` 合法 JSON exit 0、`lst` exit 1 且带提示;`readelf -d` 复核仍是 +恰好 5 条 `DT_NEEDED`(无 `libstdc++`、无任何图形库),`ull` 4 条 —— 即「能跑完子命令」是实测,不是推论。 + ### 7.5 arm64 槽位的本机验证(脚本层取证,不假装跑得动 arm64 二进制) 本机没有 ARM 机器,也不具备 MSVC ARM64 链接库组合,所以只做**能真实证明的东西**(`python` 直接加载 diff --git a/packaging/release-notes.md b/packaging/release-notes.md index a91038f..e12d452 100644 --- a/packaging/release-notes.md +++ b/packaging/release-notes.md @@ -23,6 +23,7 @@ Every slot also ships the command line as its own small asset — `ull-{{VERSION (`.exe` on Windows): ```bash +chmod +x ull-{{VERSION}}-linux-x64 # Release 资产不带可执行位,先补上 ./ull-{{VERSION}}-linux-x64 instances list # servers / CI / Termux: no graphics stack needed unlucky-launcher instances list # desktops: the GUI binary answers the same commands ```