From 06a6a1a473323235e75bd5e289cb091dfaae5c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cwuqie-xuanzhao=E2=80=9D?= Date: Mon, 8 Jun 2026 06:39:04 +0800 Subject: [PATCH] =?UTF-8?q?docs(ai):=20=E5=BC=BA=E5=8C=96=E6=9E=81?= =?UTF-8?q?=E7=AE=80=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=8E=20Linux=20?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E7=BA=A6=E6=9D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 收口 AGENTS/CLAUDE、verification 与 scripts_overview 中的极简工作流、gate 验收和同 build 目录串行构建要求,并补充 WSL GCC Linux 构建口径。 ## docs - 强化 AGENTS/CLAUDE 中的极简工作流、gate 验收和串行构建约束 - 补充 verification 和 scripts_overview 的 WSL GCC Linux 构建说明 - 新增 Linux GCC warning 后续处理 explore 文档 ## refactor - 清理 input/QmRt/gameclient 中无价值的本地 perf wrapper - 收敛 text/editor 的低风险编译 warning ## test - python qmclient_scripts/gate/check_docs.py - python qmclient_scripts/gate/check_gate.py --mode quick --base-ref origin/master - Linux package_default build via WSL cmake-build-linux-release --- AGENTS.md | 34 ++++++- CLAUDE.md | 34 ++++++- data/qmclient/icons/qm_icons_1x.png | Bin 3152 -> 3322 bytes data/qmclient/icons/qm_icons_2x.png | Bin 6619 -> 7116 bytes data/qmclient/icons/qm_icons_4x.png | Bin 14138 -> 15254 bytes docs/ai-workflow/verification.md | 27 ++++++ .../2026-06-08-linux-gcc-warning-followups.md | 88 ++++++++++++++++++ qmclient_scripts/scripts_overview.md | 2 + src/engine/client/input.cpp | 22 ++--- src/engine/client/text.cpp | 12 +-- src/game/client/QmUi/QmRt.cpp | 20 +--- src/game/client/gameclient.cpp | 22 ----- src/game/editor/editor.cpp | 2 +- 13 files changed, 193 insertions(+), 70 deletions(-) create mode 100644 docs/superpowers/explore/2026-06-08-linux-gcc-warning-followups.md diff --git a/AGENTS.md b/AGENTS.md index 1dafc7564..370b2e2b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,21 @@ QmClient(Q1menG Client)是基于 DDNet / TaterClient 的第三方定制客 | `docs/ai-workflow/git-workflow.md` | Git - commit、PR 标题/描述和最终汇报格式规范。 | 提交 git 和 PR 时 | | `qmclient_scripts/scripts_overview.md` | 脚本分层、推荐入口和 gate 工作流语义。 | 使用脚本时 | +### 极简速查 + +- 先定范围:一次只做一个功能或一个明确问题;超出当前需求的上游改动、协议/物理/预测/格式改动默认不做。 +- 启动顺序:先读匹配的 `docs/superpowers/plans/` 或 `docs/superpowers/specs/`;再读最小必要的 `docs/ai-workflow/` 规则;这轮涉及文档/入口/gate 时,先看 `check_docs.py` 是否也要同步修改。 +- 开工前先看真实代码:至少确认直接调用点、配置变量、翻译、测试和构建入口;不理解现状时不要直接写代码。 +- 实现时保持补丁聚焦:遵循 DDNet/QmClient 现有模式,不顺手重构无关代码,不把“现代化”当目标。 +- 验证时至少覆盖 build/test/gate,不能只跑 build/test 代替 gate。纯文档改动至少跑 `python qmclient_scripts/gate/check_docs.py`;常规代码改动至少跑 `python qmclient_scripts/gate/check_gate.py --mode quick --base-ref main`。 +- 同一 build 目录里的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 必须串行执行,不要并行;要并行只能拆到不同 build 目录。 +- 影响核心逻辑时,完成后必须派发一个新的只读子代理做代码审查;审查先列 findings,再给总体结论;审查问题修完后再准备提交。 +- 完成任务后:先按 `docs/ai-workflow/verification.md` 跑对应验证,至少覆盖当前改动的 build/test/gate;子代理指出的问题修完后,再考虑收口提交范围。 +- 改文档、入口、gate 或 governance 内容时,先同步对应规则/脚本,再跑 `python qmclient_scripts/gate/check_docs.py --sync-only --prefer agents` 和 `python qmclient_scripts/gate/check_docs.py`。 +- 提交 commit / PR 前,先确认 review findings 已收口、gate 证据已补齐;不要带着“只跑过 build/test、没跑 gate”的状态提交。 +- commit / PR 标题统一用 `(): <中文简述>`;正文先写问题/背景,再按 `fix`、`test`、`docs` 等分组。 +- 最终汇报必须写清:改了什么、跑了哪些验证、结果如何、还有哪些 gaps;没跑的不要说通过。 + ## 极简工作流 ### 启动顺序 @@ -33,25 +48,33 @@ QmClient(Q1menG Client)是基于 DDNet / TaterClient 的第三方定制客 - 先读 `docs/superpowers/plans/` 和 `docs/superpowers/specs/` 里与当前任务匹配的计划或规格。 - 再读与当前任务匹配的最小 `docs/ai-workflow/` 规则。 - 如果这轮涉及文档/入口/gate,先看 `check_docs.py` 是否也要同步修改。 -- 读取与任务匹配的聚焦 `docs/ai-workflow/` 文档。 -- 修改前检查附近源码、调用点、配置变量、翻译和测试。 +- 修改前检查附近源码、调用点、配置变量、翻译和测试;不理解现状时不要直接写代码。 ### 完成任务后 - 先按 `docs/ai-workflow/verification.md` 跑对应验证,至少覆盖当前改动的 build/test/gate。 +- 除非用户明确把任务限制为纯调查、纯文档同步或只要求某个单项命令,否则不要只用 build/test 代替 gate;代码改动完成后,至少补一条与范围匹配的 `python qmclient_scripts/gate/check_gate.py --mode ...` 验证。 +- 默认口径:纯文档 / harness 改动至少跑 `python qmclient_scripts/gate/check_docs.py`;常规代码改动至少跑 `check_gate.py --mode quick`;提交前如环境允许优先补到 `--mode default`;集中收口或准发布改动再用 `--mode full`。 +- 同一 build 目录中的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 必须串行执行,不要并行;要并行只能拆到不同 build 目录。 - 影响核心逻辑时,必须派发一个新的只读子代理,按 `docs/ai-workflow/review.md` 做代码审查。 - 子代理指出的问题修完后,再看这次改动能否最小化提交:只保留和当前任务直接相关的文件与说明。 ### 提交 commit / PR 前 - 先跑 `python qmclient_scripts/gate/check_docs.py`。 -- commit 和 PR 文案按 `docs/ai-workflow/git-workflow.md` 编写。 +- 不要带着“只跑过 build/test、没跑 gate”的状态进入 commit / PR;至少记录一条与本轮范围匹配的 gate 证据。 +- commit 和 PR 文案按 `docs/ai-workflow/git-workflow.md` 编写:标题统一用 `(): <中文简述>`,正文先写问题/背景,再按 `fix`、`test`、`docs` 等分组。 - 如果准备提 PR,先确保这轮审查结论已经收口,不要带着已知 review finding 进入 PR。 ### 修改文档后 -- 先判断这次文档改动是否改变了入口或规范;如果改变了,先同步修改 `check_docs.py` 或其约束,再跑文档检查 -- 最后运行 `python qmclient_scripts/gate/check_docs.py`,确认没有断链或镜像漂移。 +- 先判断这次文档改动是否改变了入口或规范;如果改变了,先同步修改 `check_docs.py` 或其约束,再跑文档检查。 +- 运行 `python qmclient_scripts/gate/check_docs.py --sync-only --prefer agents`,再运行 `python qmclient_scripts/gate/check_docs.py`,确认没有断链或镜像漂移。 + +### 最终汇报 + +- 最终汇报必须写清:改了什么、跑了哪些验证、结果如何、还有哪些 gaps。 +- 没跑的不要说通过;没收口的不要说完成。 ## 全局硬约束(简略版,详细看 `docs/ai-workflow/ddnet-development.md`) @@ -82,6 +105,7 @@ QmClient(Q1menG Client)是基于 DDNet / TaterClient 的第三方定制客 - 修改 `AGENTS.md`、`CLAUDE.md`、`docs/ai-workflow/`、workflow 脚本或 governance CI 后,运行 `python qmclient_scripts/gate/check_docs.py --sync-only --prefer agents`,再运行 `python qmclient_scripts/gate/check_docs.py` - Windows 上默认用 `qmclient_scripts/cmake-windows.cmd` 作为构建入口;常规构建/测试目录是 `cmake-build-release`,交互式完整构建命令:`qmclient_scripts/cmake-windows.cmd --build cmake-build-release --target game-client -j 14`。自动化子进程显式走 `cmd.exe` 宿主时再使用 `cmd /c qmclient_scripts/cmake-windows.cmd ...`;只有已确认当前 shell 已注入可用的 VS/MSVC 环境时,才直接使用裸 `cmake` - 构建目录名规范:debug - `cmake-build-debug`;release - `cmake-build-release`;release-pdb - `cmake-build-release-pdb` +- 同一 build 目录中的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 不要并行发起;这些目标会共享生成产物和中间文件,必须串行执行。需要并行时,只能拆到不同 build 目录。 ## 十二原则:软件工程 diff --git a/CLAUDE.md b/CLAUDE.md index 1dafc7564..370b2e2b0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,6 +26,21 @@ QmClient(Q1menG Client)是基于 DDNet / TaterClient 的第三方定制客 | `docs/ai-workflow/git-workflow.md` | Git - commit、PR 标题/描述和最终汇报格式规范。 | 提交 git 和 PR 时 | | `qmclient_scripts/scripts_overview.md` | 脚本分层、推荐入口和 gate 工作流语义。 | 使用脚本时 | +### 极简速查 + +- 先定范围:一次只做一个功能或一个明确问题;超出当前需求的上游改动、协议/物理/预测/格式改动默认不做。 +- 启动顺序:先读匹配的 `docs/superpowers/plans/` 或 `docs/superpowers/specs/`;再读最小必要的 `docs/ai-workflow/` 规则;这轮涉及文档/入口/gate 时,先看 `check_docs.py` 是否也要同步修改。 +- 开工前先看真实代码:至少确认直接调用点、配置变量、翻译、测试和构建入口;不理解现状时不要直接写代码。 +- 实现时保持补丁聚焦:遵循 DDNet/QmClient 现有模式,不顺手重构无关代码,不把“现代化”当目标。 +- 验证时至少覆盖 build/test/gate,不能只跑 build/test 代替 gate。纯文档改动至少跑 `python qmclient_scripts/gate/check_docs.py`;常规代码改动至少跑 `python qmclient_scripts/gate/check_gate.py --mode quick --base-ref main`。 +- 同一 build 目录里的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 必须串行执行,不要并行;要并行只能拆到不同 build 目录。 +- 影响核心逻辑时,完成后必须派发一个新的只读子代理做代码审查;审查先列 findings,再给总体结论;审查问题修完后再准备提交。 +- 完成任务后:先按 `docs/ai-workflow/verification.md` 跑对应验证,至少覆盖当前改动的 build/test/gate;子代理指出的问题修完后,再考虑收口提交范围。 +- 改文档、入口、gate 或 governance 内容时,先同步对应规则/脚本,再跑 `python qmclient_scripts/gate/check_docs.py --sync-only --prefer agents` 和 `python qmclient_scripts/gate/check_docs.py`。 +- 提交 commit / PR 前,先确认 review findings 已收口、gate 证据已补齐;不要带着“只跑过 build/test、没跑 gate”的状态提交。 +- commit / PR 标题统一用 `(): <中文简述>`;正文先写问题/背景,再按 `fix`、`test`、`docs` 等分组。 +- 最终汇报必须写清:改了什么、跑了哪些验证、结果如何、还有哪些 gaps;没跑的不要说通过。 + ## 极简工作流 ### 启动顺序 @@ -33,25 +48,33 @@ QmClient(Q1menG Client)是基于 DDNet / TaterClient 的第三方定制客 - 先读 `docs/superpowers/plans/` 和 `docs/superpowers/specs/` 里与当前任务匹配的计划或规格。 - 再读与当前任务匹配的最小 `docs/ai-workflow/` 规则。 - 如果这轮涉及文档/入口/gate,先看 `check_docs.py` 是否也要同步修改。 -- 读取与任务匹配的聚焦 `docs/ai-workflow/` 文档。 -- 修改前检查附近源码、调用点、配置变量、翻译和测试。 +- 修改前检查附近源码、调用点、配置变量、翻译和测试;不理解现状时不要直接写代码。 ### 完成任务后 - 先按 `docs/ai-workflow/verification.md` 跑对应验证,至少覆盖当前改动的 build/test/gate。 +- 除非用户明确把任务限制为纯调查、纯文档同步或只要求某个单项命令,否则不要只用 build/test 代替 gate;代码改动完成后,至少补一条与范围匹配的 `python qmclient_scripts/gate/check_gate.py --mode ...` 验证。 +- 默认口径:纯文档 / harness 改动至少跑 `python qmclient_scripts/gate/check_docs.py`;常规代码改动至少跑 `check_gate.py --mode quick`;提交前如环境允许优先补到 `--mode default`;集中收口或准发布改动再用 `--mode full`。 +- 同一 build 目录中的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 必须串行执行,不要并行;要并行只能拆到不同 build 目录。 - 影响核心逻辑时,必须派发一个新的只读子代理,按 `docs/ai-workflow/review.md` 做代码审查。 - 子代理指出的问题修完后,再看这次改动能否最小化提交:只保留和当前任务直接相关的文件与说明。 ### 提交 commit / PR 前 - 先跑 `python qmclient_scripts/gate/check_docs.py`。 -- commit 和 PR 文案按 `docs/ai-workflow/git-workflow.md` 编写。 +- 不要带着“只跑过 build/test、没跑 gate”的状态进入 commit / PR;至少记录一条与本轮范围匹配的 gate 证据。 +- commit 和 PR 文案按 `docs/ai-workflow/git-workflow.md` 编写:标题统一用 `(): <中文简述>`,正文先写问题/背景,再按 `fix`、`test`、`docs` 等分组。 - 如果准备提 PR,先确保这轮审查结论已经收口,不要带着已知 review finding 进入 PR。 ### 修改文档后 -- 先判断这次文档改动是否改变了入口或规范;如果改变了,先同步修改 `check_docs.py` 或其约束,再跑文档检查 -- 最后运行 `python qmclient_scripts/gate/check_docs.py`,确认没有断链或镜像漂移。 +- 先判断这次文档改动是否改变了入口或规范;如果改变了,先同步修改 `check_docs.py` 或其约束,再跑文档检查。 +- 运行 `python qmclient_scripts/gate/check_docs.py --sync-only --prefer agents`,再运行 `python qmclient_scripts/gate/check_docs.py`,确认没有断链或镜像漂移。 + +### 最终汇报 + +- 最终汇报必须写清:改了什么、跑了哪些验证、结果如何、还有哪些 gaps。 +- 没跑的不要说通过;没收口的不要说完成。 ## 全局硬约束(简略版,详细看 `docs/ai-workflow/ddnet-development.md`) @@ -82,6 +105,7 @@ QmClient(Q1menG Client)是基于 DDNet / TaterClient 的第三方定制客 - 修改 `AGENTS.md`、`CLAUDE.md`、`docs/ai-workflow/`、workflow 脚本或 governance CI 后,运行 `python qmclient_scripts/gate/check_docs.py --sync-only --prefer agents`,再运行 `python qmclient_scripts/gate/check_docs.py` - Windows 上默认用 `qmclient_scripts/cmake-windows.cmd` 作为构建入口;常规构建/测试目录是 `cmake-build-release`,交互式完整构建命令:`qmclient_scripts/cmake-windows.cmd --build cmake-build-release --target game-client -j 14`。自动化子进程显式走 `cmd.exe` 宿主时再使用 `cmd /c qmclient_scripts/cmake-windows.cmd ...`;只有已确认当前 shell 已注入可用的 VS/MSVC 环境时,才直接使用裸 `cmake` - 构建目录名规范:debug - `cmake-build-debug`;release - `cmake-build-release`;release-pdb - `cmake-build-release-pdb` +- 同一 build 目录中的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 不要并行发起;这些目标会共享生成产物和中间文件,必须串行执行。需要并行时,只能拆到不同 build 目录。 ## 十二原则:软件工程 diff --git a/data/qmclient/icons/qm_icons_1x.png b/data/qmclient/icons/qm_icons_1x.png index 4c4140f2f60eaf8964aa19226a6f310c939ce455..7ce2fc615d75ea8ae691345de8506c0d1c285fc8 100644 GIT binary patch delta 3318 zcmVkl82TBIB!9t4L_t(|ob8=ytX)+V$N&3Hr328{(h(49gjzs>0%ee?EfJ;F z#33XQArKPbgF`UHu?3ArkzfcK0yv=Xg_uTZRNBg*5P<>(3aPYZMpLG?w1t+jukYuF zy>`!f=iS?PhjZUh&p)|2_w2pSUTd$l=e_nhQi&2JN|Y!uOn(7{p_bwQ9(yvvP#Opb zK-*C99~1x`c5Tarwm6yN4(^NMJhA&hss zyPpOend3jGg`sem@&hm$c!r3TKzEMrC}26T2KaPNF&#yf$W+?BQh~|9<-jYzPT(4E zh@xfKEl4ZrD}Ox;OflsHJOWGt<^n6|kJZ3MKvxkmRFUgs;6~t$3jBM3KLHE9425Ed zjL>b$$4XqnCg4}VmB2a|{-l-8na#*xCBF?A3w#q;mQ(mLU;%In@Ec%zPKL$6q0Q>S z3skW)tRVF6j0apW`s6c

<8!3lkn(e`2;Q@th7 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 AT>t<8 delta 3147 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 Re_J{LNL^2@R>dy*e*nN6A`1Wj literal 6619 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 d@YoLT6>31z^H@N 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 diff --git a/docs/ai-workflow/verification.md b/docs/ai-workflow/verification.md index 4822dbcc0..654df6b83 100644 --- a/docs/ai-workflow/verification.md +++ b/docs/ai-workflow/verification.md @@ -28,6 +28,18 @@ cmake -G Ninja -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release cmake --build cmake-build-release --target game-client -j 14 ``` +说明:如果当前宿主是 Windows,但需要验证 Linux 构建,优先在 WSL Ubuntu 中使用 GCC/G++、CMake 和 Ninja 走原生 Linux 构建,不要复用 Windows 的 `cmake-build-release` 目录。推荐单独使用 `cmake-build-linux-release` 之类的目录,避免和 Windows 生成的 `CMakeCache.txt` 冲突。已验证可用的 WSL 口径示例: + +```pwsh +wsl env HOME=/home/ bash -lc 'set -e; . "$HOME/.cargo/env"; cd /mnt//; cmake -G Ninja -S . -B cmake-build-linux-release -DCMAKE_BUILD_TYPE=Release -DDOWNLOAD_GTEST=ON; cmake --build cmake-build-linux-release --target game-client -j 14' +``` + +如果需要 Linux 打包,可直接把 target 切到 `package_default`: + +```pwsh +wsl env HOME=/home/ bash -lc 'set -e; . "$HOME/.cargo/env"; cd /mnt//; cmake -G Ninja -S . -B cmake-build-linux-release -DCMAKE_BUILD_TYPE=Release -DDOWNLOAD_GTEST=ON; cmake --build cmake-build-linux-release --target package_default -j 14' +``` + ## 测试 Windows: @@ -40,6 +52,8 @@ qmclient_scripts/cmake-windows.cmd --build cmake-build-release --target run_rust 说明:常规运行/测试目录默认是 `cmake-build-release`;C++ 测试主路径是先构建 `testrunner`,再直接执行测试二进制。`default/full` gate 里的严格构建与静态分析会另外使用 `cmake-build-debug` 和 `cmake-build-analyze`。 +重要:同一 build 目录中的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 不要并行发起。它们会共享生成产物与中间文件,代理或脚本必须串行执行;如果确实要并行,只能拆到不同的 build 目录。 + Linux/macOS: ```sh @@ -47,6 +61,12 @@ cmake --build cmake-build-release --target run_cxx_tests cmake --build cmake-build-release --target run_rust_tests ``` +如果走 Windows 宿主下的 WSL Linux 验证,对应地把目录替换成独立的 Linux build 目录,例如: + +```pwsh +wsl env HOME=/home/ bash -lc 'set -e; . "$HOME/.cargo/env"; cd /mnt//; cmake --build cmake-build-linux-release --target run_cxx_tests -j 14; cmake --build cmake-build-linux-release --target run_rust_tests -j 14' +``` + ## Gate 模式 ```bash @@ -55,6 +75,13 @@ python qmclient_scripts/gate/check_gate.py --mode default --base-ref main python qmclient_scripts/gate/check_gate.py --mode full --base-ref main ``` +说明:除非用户明确把任务限制为纯调查、纯文档同步或只要求某个单项命令,否则不要只用 build/test 代替 gate。至少选择一条与本轮范围匹配的 gate 作为验收证据: + +- 纯文档 / harness 变更:`python qmclient_scripts/gate/check_docs.py` +- 常规代码改动:至少 `python qmclient_scripts/gate/check_gate.py --mode quick --base-ref main` +- 提交前日常严格门:优先 `python qmclient_scripts/gate/check_gate.py --mode default --base-ref main` +- 集中收口 / 准发布:`python qmclient_scripts/gate/check_gate.py --mode full --base-ref main` + 版本 / release 相关修改后,至少额外验证: ```bash diff --git a/docs/superpowers/explore/2026-06-08-linux-gcc-warning-followups.md b/docs/superpowers/explore/2026-06-08-linux-gcc-warning-followups.md new file mode 100644 index 000000000..afd890cfe --- /dev/null +++ b/docs/superpowers/explore/2026-06-08-linux-gcc-warning-followups.md @@ -0,0 +1,88 @@ +--- +type: question +date: 2026-06-08 +status: active +confidence: high +scope: + - src/game/client/gameclient.cpp + - src/game/client/components/menus_assets_editor.cpp + - src/base/str.cpp + - src/game/client/components/qmclient/perf_logging.h + - AGENTS.md + - docs/ai-workflow/verification.md + - qmclient_scripts/scripts_overview.md +commit: HEAD +related: + - file: 2026-06-02-设置页性能量化系统设计.md + relation: references +--- + +## Quick Answer + +当前 WSL Linux GCC 打包链路已经可用,剩余 warning 可以分成两类:一类是低风险源码卫生项,适合以后继续小步收敛;另一类更像真实缺陷或底层兼容性问题,不应混在“顺手消 warning”的补丁里。就当前证据看,`gameclient.cpp` 中未使用的 `LogSettingsLoadingPrewarmEvent` 属于低风险清理项,而 `menus_assets_editor.cpp` 的“返回局部变量地址”与 `str.cpp` 的底层字符串 helper 告警都值得单独立项分析。 + +工作流层面,现有根规则已经提到“至少覆盖 build/test/gate”,但入口文档没有把“不能只跑 build/test 代替 gate”写成更硬的验收要求。后续应把这条规则前置到 `AGENTS.md` / `CLAUDE.md` 一类入口文档,避免验收时只做构建与测试而绕过 `check_gate.py`。 + +## Key Evidence + +| # | Conclusion | Evidence | Location | +|---|-----------|----------|----------| +| 1 | WSL Linux GCC 打包链路已成立,后续 warning 收敛可以基于真实 Linux 编译结果进行 | 验证文档已经记录 Linux/macOS 原生 `cmake` 构建口径,并新增了 Windows 宿主下 `WSL Ubuntu + GCC/G++ + CMake + Ninja` 的独立 Linux 构建目录示例 | `docs/ai-workflow/verification.md:24-41` | +| 2 | `LogSettingsLoadingPrewarmEvent` 是当前剩余 warning 中最像低风险卫生项的一类 | 该函数完整定义在 `gameclient.cpp` 顶部,直接读取 perf 配置并写日志 payload;本轮 Linux GCC 构建中它被报为 `defined but not used`,且文件中没有后续调用证据 | `src/game/client/gameclient.cpp:96-110` | +| 3 | `menus_assets_editor.cpp` 的 warning 不应被当成纯 cosmetic 清理 | `AssetsEditorGetCachedImage` 在栈上构造 `CImageInfo Loaded`,再把它 `std::move` 到缓存条目后返回 `&NewEntry.m_Image`;GCC 已经对该函数报出 “may return address of local variable”,说明这里至少需要单独验证对象语义和移动后状态,而不是直接顺手压 warning | `src/game/client/components/menus_assets_editor.cpp:507-525` | +| 4 | `str.cpp` warning 触到的是底层字符串 helper,而不是单一业务文件 | `str_copy` 当前先 `dst[0] = '\0'`,再调用 `strncat(dst, src, dst_size - 1)`;GCC 对这类模式报出 `stringop-overflow`,说明后续若要处理,应从基础字符串 helper 和调用模式角度统一看,不适合夹带在业务补丁中 | `src/base/str.cpp:6-10` | +| 5 | perf 开关与阈值已经有公共 helper,不需要继续在每个文件复制一层本地 wrapper | `QmPerfEnabled()` 和 `QmPerfThresholdMs()` 已集中定义在 `perf_logging.h`,分别统一读取 `m_QmPerfDebug` / `m_QmPerfLogfile` 与 `m_QmPerfDebugThresholdMs` | `src/game/client/components/qmclient/perf_logging.h:14-21` | +| 6 | 入口工作流虽然提到 gate,但没有把“不能只用 build/test 替代 gate”写成明确验收约束 | 根规则当前在“完成任务后”只写到“至少覆盖当前改动的 build/test/gate”,而验证文档则单列了 `quick/default/full` gate 模式;这说明 gate 已存在,但入口表达仍可更硬,以减少只跑构建测试的灰区 | `AGENTS.md:39-49`, `docs/ai-workflow/verification.md:68-80`, `qmclient_scripts/scripts_overview.md:107-145` | + +## Details + +### 适合以后继续顺手收敛的项 + +- 未使用的本地 helper 或日志函数,例如 `LogSettingsLoadingPrewarmEvent` +- 纯命名遮蔽、无符号/有符号比较这类不会改变行为的编译器告警 +- 公共 perf helper 已存在但局部文件仍残留重复封装的场景 + +### 不适合混在“源码卫生小补丁”里的项 + +- 返回局部对象地址、生命周期、移动语义类 warning +- 底层字符串 helper、容器/内存管理模式类 warning +- 编译选项兼容性噪音,例如某些 clang-only 或 GCC-only flag 提示 + +### 对后续任务拆分的建议边界 + +如果以后继续处理 Linux GCC warning,建议至少拆成两个任务: + +1. `warning-cleanup-low-risk` + - 目标:清理未使用 helper、局部命名遮蔽、低风险类型告警 + - 验证:Linux `package_default` 或 `game-client` 构建 +2. `warning-investigate-real-bugs` + - 目标:分析 `menus_assets_editor.cpp`、`str.cpp` 等更像真实缺陷/底层问题的 warning + - 验证:除 Linux 构建外,还需要针对相关模块补测试或更细的定点验证 + +## Exploration Scope + +- Focused directory: `src/game/client/`, `src/base/`, 根工作流文档 +- Files involved: `src/game/client/gameclient.cpp`, `src/game/client/components/menus_assets_editor.cpp`, `src/base/str.cpp`, `src/game/client/components/qmclient/perf_logging.h`, `AGENTS.md`, `docs/ai-workflow/verification.md`, `qmclient_scripts/scripts_overview.md` +- Skipped: `menus_assets_editor.cpp` 的完整对象语义和 `str_copy` 全仓库调用面未做深挖;这里只记录“为什么它们不像纯 cosmetic warning” + +## Confidence Notes + +**confidence: high** + +- 剩余 warning 的分类判断直接来自当前 WSL Linux GCC 构建输出与真实源码位置 +- 入口工作流与 gate 约束缺口来自根规则文档与验证文档对照,而不是推测 +- 尚未深挖的部分已明确标记为后续调查范围,而没有在本报告中假装下结论 + +## Open Questions + +- `AssetsEditorGetCachedImage` 的 warning 是 GCC 误报、移动语义边界问题,还是确实存在返回悬空地址风险? +- `str_copy` 的 `strncat` 模式是否应该整体替换为更直接的 bounded copy 实现? +- 现有 `check_gate.py` 模式里,哪些任务类型最适合默认要求 `quick`,哪些应直接要求 `default`? + +## Related Documents + +- `2026-06-02-设置页性能量化系统设计.md` — 相关于后续 perf 量化系统继续建设,但本文只聚焦 Linux GCC warning 与 gate 工作流缺口 + +## Next Steps + +如果要继续收敛 Linux GCC warning,先做一个只覆盖低风险卫生项的小补丁;把 `menus_assets_editor.cpp` 和 `str.cpp` 留给单独的调查/修复任务。 diff --git a/qmclient_scripts/scripts_overview.md b/qmclient_scripts/scripts_overview.md index 391ff3c94..be0ef3e0b 100644 --- a/qmclient_scripts/scripts_overview.md +++ b/qmclient_scripts/scripts_overview.md @@ -159,6 +159,8 @@ python qmclient_scripts/gate/tools/refresh_allowlist.py --report tmp/check-gate- - 运行/测试目录默认是 `cmake-build-release` - 严格调试检查目录默认是 `cmake-build-debug` / `cmake-build-analyze` - Windows 默认通过 `qmclient_scripts/cmake-windows.cmd` 进入 CMake +- 在 Windows 宿主上验证 Linux 构建时,推荐通过 WSL Ubuntu + GCC/G++ + CMake + Ninja 走原生 Linux 口径,并使用独立目录(例如 `cmake-build-linux-release`),不要复用 Windows 的 `cmake-build-release` +- 同一 build 目录里的 `game-client`、`testrunner`、`run_cxx_tests`、`run_rust_tests`、`package_default` 必须串行执行,不要并行调度;并行验证只能通过拆分到不同 build 目录实现 ### 结果分类 diff --git a/src/engine/client/input.cpp b/src/engine/client/input.cpp index 27a90a7ba..40d948b58 100644 --- a/src/engine/client/input.cpp +++ b/src/engine/client/input.cpp @@ -7,13 +7,13 @@ #include #include -#include #include +#include #include #include #include -#include #include +#include #include @@ -43,20 +43,10 @@ namespace { -bool PerfDebugEnabled() -{ - return QmPerfEnabled(); -} - -double PerfDebugThresholdMs() -{ - return QmPerfThresholdMs(); -} - -void LogPerfStage(IClient *pClient, const char *pStage, const double DurationMs, const bool Force = false, const char *pExtra = nullptr) -{ - QmPerfLogStage("perf/input", pStage, DurationMs, Force, pClient, nullptr, nullptr, pExtra); -} + void LogPerfStage(IClient *pClient, const char *pStage, const double DurationMs, const bool Force = false, const char *pExtra = nullptr) + { + QmPerfLogStage("perf/input", pStage, DurationMs, Force, pClient, nullptr, nullptr, pExtra); + } } void CInput::AddKeyEvent(int Key, int Flags) diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp index f193be241..04ba5f316 100644 --- a/src/engine/client/text.cpp +++ b/src/engine/client/text.cpp @@ -1767,15 +1767,15 @@ class CTextRender : public IEngineTextRender IGraphics::CQuadItem aCursorQuads[2]; bool HasCursor = false; - const auto &&SetCursorQuad = [&](float CursorX, float CursorY) { + const auto &&SetCursorQuad = [&](float CursorPosX, float CursorPosY) { HasCursor = true; - aCursorQuads[0] = IGraphics::CQuadItem(CursorX - CursorOuterInnerDiff, CursorY, CursorOuterWidth, pCursor->m_AlignedFontSize); - aCursorQuads[1] = IGraphics::CQuadItem(CursorX, CursorY + CursorOuterInnerDiff, CursorInnerWidth, pCursor->m_AlignedFontSize - CursorOuterInnerDiff * 2); - pCursor->m_CursorRenderedPosition = vec2(CursorX, CursorY); + aCursorQuads[0] = IGraphics::CQuadItem(CursorPosX - CursorOuterInnerDiff, CursorPosY, CursorOuterWidth, pCursor->m_AlignedFontSize); + aCursorQuads[1] = IGraphics::CQuadItem(CursorPosX, CursorPosY + CursorOuterInnerDiff, CursorInnerWidth, pCursor->m_AlignedFontSize - CursorOuterInnerDiff * 2); + pCursor->m_CursorRenderedPosition = vec2(CursorPosX, CursorPosY); }; - const auto &&CheckCursorAtCharacter = [&](float CursorX, float CursorY) { + const auto &&CheckCursorAtCharacter = [&](float CursorPosX, float CursorPosY) { if(pCursor->m_CursorMode != TEXT_CURSOR_CURSOR_MODE_NONE && pCursor->m_GlyphCount == pCursor->m_CursorCharacter) - SetCursorQuad(CursorX, CursorY); + SetCursorQuad(CursorPosX, CursorPosY); }; const auto &&CheckSelectionSetAtCharacter = [&]() { if(pCursor->m_CalculateSelectionMode != TEXT_CURSOR_SELECTION_MODE_SET) diff --git a/src/game/client/QmUi/QmRt.cpp b/src/game/client/QmUi/QmRt.cpp index df8d1c133..e323c562f 100644 --- a/src/game/client/QmUi/QmRt.cpp +++ b/src/game/client/QmUi/QmRt.cpp @@ -16,20 +16,10 @@ namespace { -bool PerfDebugEnabled() -{ - return QmPerfEnabled(); -} - -double PerfDebugThresholdMs() -{ - return g_Config.m_QmPerfDebugThresholdMs > 0 ? g_Config.m_QmPerfDebugThresholdMs : 1.0; -} - -void LogPerfStage(IClient *pClient, const char *pStage, const double DurationMs, const bool Force = false, const char *pExtra = nullptr) -{ - QmPerfLogStage("perf/ui_runtime", pStage, DurationMs, Force, pClient, nullptr, nullptr, pExtra); -} + void LogPerfStage(IClient *pClient, const char *pStage, const double DurationMs, const bool Force = false, const char *pExtra = nullptr) + { + QmPerfLogStage("perf/ui_runtime", pStage, DurationMs, Force, pClient, nullptr, nullptr, pExtra); + } } void CUiRuntimeV2::Init(CGameClient *pGameClient) @@ -104,7 +94,7 @@ void CUiRuntimeV2::OnRender() if(g_Config.m_QmUiRuntimeV2Debug) { m_DebugLogAccumulator += Dt; - if(m_DebugLogAccumulator >= 2.0f && m_LastStats.m_AnimMs >= PerfDebugThresholdMs()) + if(m_DebugLogAccumulator >= 2.0f && m_LastStats.m_AnimMs >= QmPerfThresholdMs()) { m_DebugLogAccumulator = 0.0f; dbg_msg("qm_ui", "runtime active: nodes=%d, anim_ms=%.3f", m_LastStats.m_NodeCount, m_LastStats.m_AnimMs); diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 80baf9661..5bc75913b 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -124,16 +124,6 @@ namespace { constexpr int DEMO_INPUT_KEY_STATE_SIZE = KEY_LAST / 8; - bool PerfDebugEnabled() - { - return QmPerfEnabled(); - } - - double PerfDebugThresholdMs() - { - return QmPerfThresholdMs(); - } - #if defined(CONF_QM_LIVE_CLIENT) constexpr float LIVE_OBSERVER_UI_HEIGHT = 1200.0f; constexpr float LIVE_OBSERVER_PANEL_WIDTH = 230.0f; @@ -541,18 +531,6 @@ static void GenerateTimeoutCode(char *pTimeoutCode) } } -static void MigrateChatBubbleConfig() -{ - auto MigrateInt = [](int &NewValue, int LegacyValue, int NewDefault, int LegacyDefault) { - if(NewValue == NewDefault && LegacyValue != LegacyDefault) - NewValue = LegacyValue; - }; - auto MigrateCol = [](unsigned &NewValue, unsigned LegacyValue, unsigned NewDefault, unsigned LegacyDefault) { - if(NewValue == NewDefault && LegacyValue != LegacyDefault) - NewValue = LegacyValue; - }; -} - static void MigrateQmHudConfig() { auto MigrateInt = [](int &NewValue, int LegacyValue, int NewDefault, int LegacyDefault) { diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index cbbe66e24..91d842c6b 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -4692,7 +4692,7 @@ bool CEditor::BuildCollabUrl(const char *pPath, char *pBuffer, int BufferSize, c str_format(pBuffer, BufferSize, "%s%s?%s", QM_EDITOR_COLLAB_BASE_URL, pPath, pQuery); else str_format(pBuffer, BufferSize, "%s%s", QM_EDITOR_COLLAB_BASE_URL, pPath); - return str_length(pBuffer) + 1 < (size_t)BufferSize; + return (size_t)(str_length(pBuffer) + 1) < (size_t)BufferSize; } std::shared_ptr CEditor::MakeCollabJsonRequest(const char *pPath, const std::string &Body)