From 592f0c26f617875c33c48260e26a313426fbc815 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Thu, 5 Nov 2026 17:58:03 +0800 Subject: [PATCH] =?UTF-8?q?docs(packaging):=20M131=20=E5=8E=8B=E5=9B=9E=20?= =?UTF-8?q?400=20=E8=A1=8C=E5=86=85=EF=BC=8C=E5=88=A0=20Slint=20=E9=81=97?= =?UTF-8?q?=E7=95=99=E7=A5=88=E4=BD=BF=E5=8F=A5/=E8=BD=AF=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=9D=97=EF=BC=8C=E4=BF=AE=20smoke=20=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=20bin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - packaging/README.md 401 -> 398 行(回归 file-size 红线内) - §5 删 SLINT_BACKEND=winit-software 命令块;现役入口改注 iced 的 --software-renderer - §8 删「关于页保留 AboutSlint、不得移除」两句祈使句,只留 v0.1.0 资产事实段 - §7 抬头标明连字符产物名属哪次实测(现名形态写下划线 0.2.0),§7.3/§7.5 同步标注 - §11 删「该脚本现在会失败」的过期提醒,记录 M131 真跑证据 - linux-smoke-docker.sh: --bin/产物路径/target 全改 unlucky-launcher-iced(cargo clean -p 同步改 unlucky-app-iced,原来的 unlucky-app 已被 workspace exclude、清不掉陈旧产物) --- packaging/README.md | 49 ++++++++++++++++----------------- packaging/linux-smoke-docker.sh | 8 ++++-- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/packaging/README.md b/packaging/README.md index 0408af6..cafdd9e 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -180,14 +180,14 @@ macOS 产物是**裸二进制**而非 `.app` bundle:符合单文件承诺, ## 5. 软渲染兜底(无 GPU / 老驱动 / 远程桌面) -M118(D26):以下是**历史实现(Slint 版,默认 `renderer-femtovg`/GL)**的兜底路径,已不在默认构建与发布矩阵内(`crates/app` 被 workspace `exclude`,源码仅作参考、不编译)。现役 GUI 是 iced 版:`unlucky-launcher-iced --software-renderer`(= `ICED_BACKEND=tiny-skia`)走 tiny-skia 光栅化。v0.1.0 的产物仍认下面两条: +**现役入口(iced 版)**:`unlucky-launcher-iced --software-renderer`(等价 `--renderer=cpu`,即 `ICED_BACKEND=tiny-skia`) +走 tiny-skia 光栅化,这是现役构建唯一的软渲染入口——CI 的 runtime-smoke 与 `packaging/linux-smoke-docker.sh` 都这么跑(§11)。 -```bash -unlucky-launcher --software-renderer # 启动参数(本仓库解析后设 SLINT_BACKEND) -SLINT_BACKEND=winit-software unlucky-launcher # 环境变量(Slint 原生开关) -``` +**历史资产(`v0.1.0` 的 Slint 版)**:那批已发布二进制仍认 `unlucky-launcher --software-renderer` +(解析在 `crates/app/src/main.rs` 的 `apply_renderer_flag()`,只认完全相等的那个串)。 +这条 Slint 路径(默认 `renderer-femtovg`/GL)已不在默认构建与发布矩阵内——`crates/app` 被 workspace `exclude`, +源码仅作参考、不编译——所以它**对现役 `unlucky-launcher-iced` 无效**,别照抄到 iced 版上。 -- 参数解析在 `crates/app/src/main.rs` 的 `apply_renderer_flag()`,只认完全相等的 `--software-renderer`。 - 软渲染是 CPU 光栅化,无 GPU 也能出图;代价是动画与大窗口重绘更慢(Metro 纯色界面影响有限)。 - 截图通道 `--screenshot `:历史实现 `crates/app/src/screenshot.rs`,现役 `crates/app-iced/src/shot/`; 软渲染下照样出图,是 CI 与远程机唯一可靠的"真出图"证据(发布冒烟见 §7,本机实跑 `--software-renderer --screenshot`)。 @@ -220,7 +220,7 @@ SLINT_BACKEND=winit-software unlucky-launcher # 环境变量(Slint 构建环境:rustc 1.99.1 stable / `x86_64-pc-windows-gnu`(MinGW 链接器)。§7.2/§7.3 的早数字是另有 worker 并发做全量 debug 构建时测的(偏悲观);§7.1 的三行 M96 数据是空载冷编译。 -**本节以下所有输出里的 `0.1.0` 都是当时那次运行的真实输出(workspace 版本那时是 `0.1.0`),属实测记录,不随后续版本号改动而回填**;当前版本见 `Cargo.toml` 的 `[workspace.package] version`。§2 的校验机制不依赖任何写死的数字,改版本号不会让它失效。 +**本节以下所有输出里的 `0.1.0` 都是当时那次运行的真实输出(workspace 版本那时是 `0.1.0`),属实测记录,不随后续版本号改动而回填**;当前版本见 `Cargo.toml` 的 `[workspace.package] version`。§2 的校验机制不依赖任何写死的数字,改版本号不会让它失效。产物名同理且更容易被误读成现状:§7.3 / §7.5 里的 `unlucky-launcher-0.1.0-windows-*.exe`(**连字符**)是 2026-11-01 那几次实测的原文,D49(2026-11-05)才改成下划线形态——同一槽位现在叫 `unlucky-launcher_0.2.0_windows_x64.exe`(规则见 §1);拿旧名去 Release 页或磁盘上找文件必然找不到,那不代表发布挂了。 ### 7.1 体积与冷构建耗时(实测字节数,不是估算) @@ -247,7 +247,7 @@ crate + 链接 + 机械盘 IO——定位是 **SSD 机器与增量重编**,不 | `unlucky-launcher.exe --software-renderer --screenshot … --data-dir …`(Slint 版,历史实测) | exit 0,产出 1180×760 PNG(3,588,298 B);看图确认 Metro 实例页(侧栏/搜索/空态/AI 助手面板)正常渲染 → **软渲染路径真的能出图**,不依赖 GL | | `unlucky-launcher.exe --version` | **无输出**,8 秒后被 timeout 杀掉(exit 124)——GUI 当时不解析 `--version`,会直接开窗口。M82 后已修(走 CLI 分发,见 §10-1)| -### 7.3 打包验证(本机 Windows 槽位真跑) +### 7.3 打包验证(本机 Windows 槽位真跑;产物名是 D49 改名前的形态) ``` smoke: ull.exe --version -> 0.1.0 (ok) @@ -301,23 +301,22 @@ libxcb 条目数 = 0,只把 fontconfig 那 7 个 `.so` 放进 `LD_LIBRARY_PATH |--------|------| | 宿主判定注入 | `win32/AMD64`→`windows-x64`、`win32/ARM64`→`windows-arm64`、`linux/x86_64`→`linux-x64`、`linux/aarch64`→`linux-arm64`、`linux/arm64`→`linux-arm64`、`darwin/arm64`→`macos-arm64`、`darwin/x86_64`→`macos-x64`、`freebsd/riscv64`→exit 1 | | 文件头架构识别 | 真 `unlucky-launcher.exe`→`x64`;合成 PE `0xAA64`→`arm64` / `0x8664`→`x64`;ELF `0xB7`→`arm64` / `0x3E`→`x64`;Mach-O `0x0100000C`→`arm64` / `0x01000007`→`x64`;垃圾字节→`None`(拒绝出包) | -| `windows-arm64` stub 全流程 | 把真 exe 的 PE 机器码改成 ARM64 当 stub:`arch: … -> arm64 (ok for windows-arm64)`、`smoke: skipped (host is windows-x64, artifact is windows-arm64)`、产物 `unlucky-launcher-0.1.0-windows-arm64.exe` 14.01 MiB,`SHA256SUMS.txt` 行名一致 | +| `windows-arm64` stub 全流程 | 把真 exe 的 PE 机器码改成 ARM64 当 stub:`arch: … -> arm64 (ok for windows-arm64)`、`smoke: skipped (host is windows-x64, artifact is windows-arm64)`、产物 `unlucky-launcher-0.1.0-windows-arm64.exe`(当次实测的连字符名)14.01 MiB,`SHA256SUMS.txt` 行名一致 | | 架构守卫真拦 | x64 二进制冒充 `--slot windows-arm64` → exit 1:`is a x64 binary but slot windows-arm64 says arm64` | -| `linux-arm64` stub 归档 | 成员 `unlucky-launcher-0.1.0-linux-arm64/{LICENSE,NOTICE,README.md,unlucky-launcher}`,权限 0644/0755、`uid=gid=0`、mtime 0、gzip 头 mtime 字段 `00 00 00 00`;连调两次 sha256 完全一致(`f949d0f5…`)→ 可复现规则与 x64 同源 | +| `linux-arm64` stub 归档 | 成员 `unlucky-launcher-0.1.0-linux-arm64/{LICENSE,NOTICE,README.md,unlucky-launcher}`(旧连字符名,当次实测),权限 0644/0755、`uid=gid=0`、mtime 0、gzip 头 mtime 字段 `00 00 00 00`;连调两次 sha256 完全一致(`f949d0f5…`)→ 可复现规则与 x64 同源 | | `windows-x64` 原生回归 | `arch: … -> x64`、`smoke: ull.exe --version -> 0.1.0 (ok)`、产物 14.01 MiB、`sha256sum -c SHA256SUMS.txt` OK(这一次用的是当前工作树的二进制,与 §7.3 那次不是同一次构建,sha256 自然不同) | -**没在本地验证、只能由 CI 补的**:`windows-arm64` 的交叉链接与真实 ARM64 导入表、`linux-arm64` 在 -原生 arm64 runner 上的真跑。本机连 `raw.githubusercontent.com` 都解析不了,所以 runner 镜像里到底装没装 -ARM64 的 MSVC 库**没法在这里查证**——`release.yml` 为此加了一道链接前的体检(查 `libcmt.lib` 与 -`um/arm64/kernel32.lib`,缺了直接给"加 `VC.Tools.ARM64` 组件或改原生 runner"的提示),首跑即见分晓。 -merge 后由 tower 重指 tag 重跑流水线,两槽位进 `SHA256SUMS.txt` 即算闭环。 +**没在本地验证、只能由 CI 补的**:`windows-arm64` 的交叉链接与真实 ARM64 导入表、`linux-arm64` 在原生 arm64 +runner 上的真跑(本机连 `raw.githubusercontent.com` 都解析不了,查不到 runner 镜像里装没装 ARM64 的 MSVC 库)。 +`release.yml` 为此加了一道链接前体检(查 `libcmt.lib` 与 `um/arm64/kernel32.lib`,缺了直接给"加 `VC.Tools.ARM64` +或改原生 runner"的提示);merge 后重跑流水线,两槽位进 `SHA256SUMS.txt` 即算闭环。 ## 8. 发行合规 - `LICENSE`(Apache-2.0 全文)与 `NOTICE`(含 Slint Royalty-Free 2.0 义务说明)随包分发, 三份文本在 UNIX 归档内、在 Windows 侧作为并列 Release 资产。 -- Slint 的 RF 2.0 义务:关于页保留 `AboutSlint` 部件(已在 UI 内),不得移除; - 选 RF 分支即不触发 GPL 分支义务(见 `deny.toml` 的许可证白名单注释)。 +- Slint 的 RF 2.0 义务只跟 `v0.1.0` 那批资产:当时关于页有 `AboutSlint` 部件、选的是不触发 GPL 分支的 RF 分支 + (见 `deny.toml` 的许可证白名单注释)。现役 iced UI 里没有、也不需要任何 Slint 部件。 - **M118 后这条义务只跟着已发布的 `v0.1.0` 资产走**:`crates/app` 已被 workspace `exclude`,发布矩阵里再没有链接 Slint 的二进制,新的 iced 版产物不链接 Slint;`deny.toml` 那条 RF-2.0 allow 因此暂时是死条目(不删,留给将来真有别的路径引入 Slint 时兜底)。 - `README.md`(英文主版)随包分发;中文版 `README.zh-CN.md` 留在仓库不进包(避免包体噪音)。 - 依赖许可门禁不变:`deny.toml` 白名单(Apache-2.0 / MIT / BSD / Zlib / BSL-1.0 / ISC / CC0 / Unlicense / @@ -347,13 +346,12 @@ experimental / not part of this release matrix)——改一边必须同步另 ## 10. 已知边界 / 后续 -1. **GUI 的 `--version` 已解决**(M82):`unlucky-launcher --version` 现在命中子命令分发,输出与 - `ull --version` 同一条版本 + 系统摘要后退出,不再开窗。§7.2 里「无输出、8 秒后被 timeout 杀掉」那行 - 是**改之前**的实测记录,留作对照。版本自证的另外两条(产物名里的 ``、tag 交叉校验)不变。 +1. **GUI 的 `--version` 已解决**(M82):现在命中子命令分发,输出与 `ull --version` 同一条版本 + 系统摘要后退出, + 不再开窗;§7.2 里「无输出、8 秒后被 timeout 杀掉」那行是**改之前**的记录,留作对照。 2. **签名/公证**:Windows 无 Authenticode、macOS 无 codesign/notarize(都要证书/开发者账号), 当前以 SHA256SUMS + Release 说明作为完整性参考。 3. **macOS `.app` bundle / `.dmg`**:与单文件承诺冲突,暂不做;若用户要 Dock 图标再单开 mission。 -4. **Linux musl 静态版**:可彻底摆脱 glibc 地板,但 Slint 在 musl 上需额外验证,未纳入本矩阵。 +4. **Linux musl 静态版**:可彻底摆脱 glibc 地板,但现役 iced 版(winit + wgpu)在 musl 上的可行性未验证,未纳入本矩阵。 5. **`ull` 已随包**(M82 起):每个槽位与 GUI 并列发一份裸 `ull`,进同一份 `SHA256SUMS.txt`,矩阵 完整性检查按「GUI 与 CLI 各自都要有」分开查(`release.yml`)。等 CI 首跑确认这条在真流水线上有效。 6. **本机 GNU 链接器的已知无害告警**:`cargo build --release`(GNU 工具链)会打一行 @@ -365,9 +363,6 @@ experimental / not part of this release matrix)——改一边必须同步另 本机能做且已做的是脚本层取证(见 §7.5):宿主判定注入(`win32/ARM64`、`linux/aarch64` 等全槽位)、 可执行文件头架构识别(真 x64 exe + 合成 PE/ELF/Mach-O 头)、以及把真 exe 的 PE 机器码改成 ARM64 当 stub 走完命名/校验/归档全流程 —— 不假装能在 x64 上执行 arm64 二进制。 -8. **M82 的体积/首帧没重量**:改的时候本机三个 worker 同时在编(全量 release profile 要 400+ crate), - 这两个数留给空闲窗口补。结构性判断(**不是实测**):分发发生在 `MainWindow::new()` 与后端探测之前, - GUI 路径只多一次 argv 解析,所以首帧成本没有增加的理由;CLI 路径的耗时则天然与首帧无关。 ## 11. CI 运行时冒烟(Linux 真渲染一帧) @@ -385,8 +380,10 @@ experimental / not part of this release matrix)——改一边必须同步另 更不证明视觉正确**——视觉靠人眼看 artifact。 - 只覆盖 Linux x64;macOS 是 dispatch-only 探针(无实测证据),Windows 已有本机人眼验收。 -**本地复跑**:`bash packaging/linux-smoke-docker.sh . D:/tmp/ull-smoke`(输出目录别写 `/tmp`,Git Bash 下会静默落进 Docker VM;脚本内部用 `cygpath -m` 归一并回显真实路径)。**M118 提醒**:该脚本仍按 Slint 版 bin `unlucky-launcher` 编译与启动(`linux-smoke-docker.sh:81/83/88`),而 `crates/app` 已被 workspace `exclude`,**这条命令现在会失败**。 -在它把 bin 换成 `unlucky-launcher-iced` 之前,本地要复刻请直接照 `ci.yml` 的 runtime-smoke 三步手跑:`cargo build --bin unlucky-launcher-iced --locked` → `xvfb-run … --software-renderer --screenshot --data-dir ` → `python3 packaging/check_screenshot.py --json`。 +**本地复跑**:`bash packaging/linux-smoke-docker.sh . D:/tmp/ull-smoke`——脚本逐步复刻这个 job(同样的 apt 依赖、 +`--bin unlucky-launcher-iced`、同样的 `xvfb-run … --software-renderer --screenshot --data-dir`);输出目录别写 `/tmp`, +Git Bash 下会静默落进 Docker VM(脚本内部用 `cygpath -m` 归一)。 +**M131 真跑过一次**(本机 Docker / Debian 12 容器 / 2026-11-05):`exit=0`,截图 1180×760、`[ok] 截图非空白`。 ## 12. 文件清单 diff --git a/packaging/linux-smoke-docker.sh b/packaging/linux-smoke-docker.sh index 9d08aff..8a124ac 100644 --- a/packaging/linux-smoke-docker.sh +++ b/packaging/linux-smoke-docker.sh @@ -15,6 +15,8 @@ # 两者图形栈(X11/xvfb/Mesa 软渲染)来源不同,因此本脚本证明的是「Linux 上这条通道能真跑出图」, # 不能代替官方 runner 的首跑验证。 # - 国内网络慢时可换 TUNA 镜像:脚本默认就用 TUNA 的 Debian 源(`ULL_APT_MIRROR` 可覆盖)。 +# - 受检 bin 是 iced 版 `unlucky-launcher-iced`,与 `ci.yml` 的 runtime-smoke 逐步对应(M118:Slint 版 +# bin/包 `unlucky-launcher`/`unlucky-app` 已随 `crates/app` 退出 workspace,改了这里要两边一起改)。 set -euo pipefail @@ -79,13 +81,13 @@ MSYS_NO_PATHCONV=1 docker run --rm \ if [ "$ULL_SMOKE_SKIP_BUILD" != "1" ]; then # 共享热缓存卷可能喂陈旧产物(踩坑记录 N7):先清掉受检 crate 再编 # 清不掉就算了(N7 兜底用);CI 里**没有**对应两行,别误抄进 ci.yml —— 那边每次都是干净 runner - cargo clean -p unlucky-app || true - cargo build --bin unlucky-launcher --locked -j 6 + cargo clean -p unlucky-app-iced || true + cargo build --bin unlucky-launcher-iced --locked -j 6 fi mkdir -p /out/data set +e xvfb-run -a --server-args="-screen 0 1280x1024x24" \ - /target/debug/unlucky-launcher --software-renderer \ + /target/debug/unlucky-launcher-iced --software-renderer \ --screenshot /out/runtime-smoke.png --data-dir /out/data code=$? set -e