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 ```