Skip to content

fix(build): 修复 Debug 构建链接失败(托盘守卫 + big-obj) - #906

Merged
qiin2333 merged 2 commits into
masterfrom
fix/build-debug-link
Aug 6, 2026
Merged

fix(build): 修复 Debug 构建链接失败(托盘守卫 + big-obj)#906
qiin2333 merged 2 commits into
masterfrom
fix/build-debug-link

Conversation

@qiin2333

@qiin2333 qiin2333 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

概述

#845 摘出两处独立的构建修复。#845 的主体(VDD 模式 XML 缓存)在当前 SETMODES 架构下已无收益且有回归风险,建议单独关掉,本 PR 不含那部分。

两处问题都只在 Release CI 矩阵之外触发,所以 CI 一直是绿的。

变更内容

1. main.cpp 托盘守卫

main.cpp 的 3 处 system_tray:: 引用是全仓库仅剩的未加守卫的调用点——vdd_utilsstreamprocesspairingaudiotray_state,以及 main.cpp 自己的 end_tray() 两处,全都有 #if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1

托盘统一到 GUI agent 之后,Windows 默认配置是 SUNSHINE_ENABLE_TRAY=ON + SUNSHINE_ENABLE_LEGACY_TRAY=OFF(见 cmake/prep/options.cmake),推导出 SUNSHINE_TRAY=0 / SUNSHINE_GUI_TRAY=1。此时 src/tray/system_tray.cpp 整个文件体被 #if SUNSHINE_TRAY >= 1 包住,是个空编译单元,不产生任何符号

Release 能链接过只是因为 constexpr bool tray_is_enabled = false 让优化器在链接器看到之前就删掉了分支;-O0 不删,于是默认配置的 Debug 构建链接失败

2. -Wa,-mbig-obj

confighttp.cpp 等模板密集编译单元超过 COFF 32767 段上限,汇编器静默写坏 COMDAT 符号表,Debug 链接报大量 typeinfo/内联符号未定义。

设计取舍

为什么加守卫而不是删掉这几行。 托盘统一到 GUI agent 是 Windows-only 的。Linux 上 cmake/compile_definitions/linux.cmake 在 appindicator + libnotify 存在时仍设 SUNSHINE_TRAY=1mainThreadLoop 里的 process_tray_events() 就是 Linux 托盘的事件泵,init_tray() 也是活代码。删掉会直接破坏 Linux。tray_state.cpptray_owner() 返回 core / gui / disabled 三态,也印证三种配置都还在支持范围内。

mainThreadLoop#else 分支为什么阻塞而不是留空。 run_loop 目前只由托盘条件置位,所以 SUNSHINE_TRAY=0 时那段不可达。但如果只写 #if/#endif,将来一旦有别的 main-thread 特性把 run_loop 置真,函数会直接返回到 main() 并立刻走完整个关闭流程。#elseshutdown_event->view() 保持了阻塞语义。

[[maybe_unused]] 加守卫后 tray_is_enabled 在 Windows + SUNSHINE_TRAY=0 下失去唯一读者(mainThreadLoop 里那处在 #ifndef _WIN32 内)。GCC 的 -Wunused-const-variable 在 C++ 下不随 -Wall 开启,所以现网 msys2 GCC 不会报;但 clang 会,BUILD_WERROR=ON 时是 error。加 [[maybe_unused]] 以免依赖编译器特定的告警行为。

测试

未做完整构建验证——本地无 cmake/ninja 环境,且 CI 只跑 Release(问题本身不在 Release 中出现)。已验证的部分:

  • mainThreadLoop / 托盘初始化两段连同预处理条件抽成独立编译单元,在 SUNSHINE_TRAY × _WIN32 四种组合下用 -Wall -Wno-sign-compare -Werror(项目实际告警配置)全部通过
  • 复核全仓库 system_tray:: 引用,确认改后无遗漏的未守卫调用点
  • -Wa,-mbig-objcmake/targets/common.cmake 只作用于 COMPILE_LANGUAGE:CXXwindows.cmake 无 MSVC/clang-cl 分支,CI 用 msys2 ucrt64 GCC,与文件内既有的 GCC 专用 flag 一致

需要 reviewer 补的验证:Windows Debug(MSYS2 UCRT64)默认配置全量重编译 + 链接,以及一次 Linux 构建确认托盘仍正常。

🤖 Generated with Claude Code

Two independent link failures, both only reachable outside the Release CI
matrix, cherry-picked from #845 (the rest of that PR is superseded by the
SETMODES architecture).

main.cpp held the only three unguarded system_tray:: references in the tree.
Since the Windows tray moved to the bundled GUI agent, SUNSHINE_ENABLE_TRAY=ON
with SUNSHINE_ENABLE_LEGACY_TRAY=OFF (the default) yields SUNSHINE_TRAY=0, and
system_tray.cpp is then an empty translation unit. Release links anyway because
`constexpr bool tray_is_enabled = false` lets the optimizer drop the branches
before the linker sees them; at -O0 it does not, so the default configuration
fails to link. Guard the three sites to match every other call site.

The in-process tray is still the live path on Linux (SUNSHINE_TRAY=1 whenever
appindicator and libnotify are present), so these calls are kept rather than
removed. The #else branch in mainThreadLoop blocks on shutdown_event instead of
falling through: run_loop is only ever set by the tray today, but a fall-through
would return into main() and tear the host down if that ever changes.

confighttp.cpp exceeds the 32767-section COFF limit, where the assembler
silently emits a corrupt symbol table and its COMDAT entries (typeinfo, inline
members) resolve as undefined. -Wa,-mbig-obj fixes it; the flag is scoped to
CXX, and the Windows toolchain is MinGW GCC only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: baffb5f2-1aea-47d3-89ce-3f9a657bf0bf

📥 Commits

Reviewing files that changed from the base of the PR and between 2308db0 and cc3daf6.

📒 Files selected for processing (1)
  • cmake/compile_definitions/windows.cmake
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmake/compile_definitions/windows.cmake
📜 Recent review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Windows

Summary by CodeRabbit

  • 兼容性改进

    • Windows 构建现支持包含大量模板代码的项目,提升 GNU 编译环境下的构建兼容性。
  • 错误修复

    • 未启用系统托盘时,应用不再处理无效的托盘事件。
    • 优化无托盘模式下的关闭等待逻辑,提升运行稳定性。

Walkthrough

Windows GNU C++ 构建新增 -Wa,-mbig-obj。系统托盘变量、事件循环和初始化逻辑增加 SUNSHINE_TRAY 条件处理。未启用系统托盘时,主线程等待关闭事件。

Changes

构建与系统托盘

Layer / File(s) Summary
Windows 汇编器选项
cmake/compile_definitions/windows.cmake
Windows GNU C++ 构建新增 -Wa,-mbig-obj,用于大型模板翻译单元,并避免向 clang MinGW 传递该选项。
系统托盘条件编译与事件循环
src/main.cpp
tray_is_enabled 增加 [[maybe_unused]]。启用 SUNSHINE_TRAY 时处理托盘事件并初始化系统托盘;未启用时等待关闭事件。

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确概括了托盘守卫和 big-obj 编译选项两项 Debug 构建修复,内容清晰且与主要变更相关。
Description check ✅ Passed 描述具体说明了两类构建问题、实现方案、设计取舍和测试状态,与变更内容直接相关。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/build-debug-link

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cmake/compile_definitions/windows.cmake (1)

21-21: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

按 GCC 编译器类型限定 -Wa,-mbig-obj

include(${CMAKE_MODULE_PATH}/compile_definitions/windows.cmake) 对所有 Windows C++ 配置生效,而该选项是 GNU/MinGW 汇编器选项;MSVC 或 clang-cl 等编译器会拒绝它并导致构建失败。CUDA 继承路径也会将 SUNSHINE_COMPILE_OPTIONS--compiler-options=... 转发到 CUDA 主机编译。只在对已验证支持的 GNU MinGW C++ 编译器添加该选项;例如使用 $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wa,-mbig-obj>,或先在工具链中限制 Windows 构建为 GCC/MinGW。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmake/compile_definitions/windows.cmake` at line 21, 仅在 GNU/MinGW C++ 编译器下向
SUNSHINE_COMPILE_OPTIONS 添加 -Wa,-mbig-obj;使用基于 COMPILE_LANG_AND_ID
的生成器表达式或等效编译器条件,确保 MSVC、clang-cl 及 CUDA 主机编译转发路径不会接收到该选项。

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@cmake/compile_definitions/windows.cmake`:
- Line 21: 仅在 GNU/MinGW C++ 编译器下向 SUNSHINE_COMPILE_OPTIONS 添加 -Wa,-mbig-obj;使用基于
COMPILE_LANG_AND_ID 的生成器表达式或等效编译器条件,确保 MSVC、clang-cl 及 CUDA 主机编译转发路径不会接收到该选项。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 889e67a8-980d-47ab-b6c4-ea236f09c654

📥 Commits

Reviewing files that changed from the base of the PR and between cd3f8f9 and 2308db0.

📒 Files selected for processing (2)
  • cmake/compile_definitions/windows.cmake
  • src/main.cpp
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Windows
🧰 Additional context used
📓 Path-based instructions (2)
cmake/**

⚙️ CodeRabbit configuration file

cmake/**: CMake 构建系统文件。审查跨平台兼容性、现代 CMake 实践。

Files:

  • cmake/compile_definitions/windows.cmake
src/**/*.{cpp,c,h}

⚙️ CodeRabbit configuration file

src/**/*.{cpp,c,h}: Sunshine 核心 C++ 源码,自托管游戏串流服务器。审查要点:内存安全、 线程安全、RAII 资源管理、安全漏洞。注意预处理宏控制的平台相关代码。

Files:

  • src/main.cpp
🔇 Additional comments (3)
src/main.cpp (3)

108-113: LGTM!


134-141: LGTM!


489-503: 🎯 Functional Correctness

请补充跨平台全量构建验证。

该条件编译会在 SUNSHINE_TRAY < 1 时移除全部托盘初始化代码。请确认 Linux 等非 Windows 目标在启用托盘时定义 SUNSHINE_TRAY=1,禁用时定义为 0。然后补充 Windows MSYS2 UCRT64 Debug 全量构建和 Linux 全量构建,并验证退出流程可以正常完成。

clang only warns about an unknown -Wno-*, but rejects an unknown -Wa, argument
outright, so the flag would hard-fail a clang-based MinGW build (MSYS2 CLANG64)
where the adjacent GCC-only warning flags survive. Gate it on the compiler ID.

Uses a plain if() rather than a COMPILE_LANG_AND_ID generator expression:
cmake/targets/common.cmake wraps every SUNSHINE_COMPILE_OPTIONS entry as
--compiler-options=<flag> when CUDA_INHERIT_COMPILE_OPTIONS is on (the default),
so a genex in that list would degrade to a bare --compiler-options= for CUDA
translation units.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@qiin2333

qiin2333 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

已按 review 门控 -Wa,-mbig-obj(cc3daf6c),但理由和建议的实现方式都与原意见不同,说明一下:

原意见的两条理由核实后都不成立

MSVC / clang-clwindows.cmake 已经是硬 MinGW-only —— windres-static、第 11 行未门控的 -Wno-misleading-indentation。MSVC 会在第 11 行就失败,走不到第 21 行。不是本 PR 引入的新风险。

CUDA 主机编译转发enable_language(CUDA) 只出现在 cmake/compile_definitions/linux.cmake:19SUNSHINE_ENABLE_CUDA 也只在 options.cmakeelseif(UNIX) 分支里定义。Windows 上没有 CUDA 语言,而 windows.cmake 在 Linux 上不被 include —— 这条路径不可达。

但门控确实该做,理由是另一个

实测 clang 对两类未知 flag 的处理是不对称的:

$ clang -Wa,-mbig-obj -c t.c
clang: error: unsupported argument '-mbig-obj' to option '-Wa,'

$ clang -Wno-template-body -c t.c
warning: unknown warning option '-Wno-template-body' [-Wunknown-warning-option]

所以相邻的 -Wno-* 在 clang 下只是告警、能活,而 -Wa,硬报错。MSYS2 CLANG64 环境下这行会直接挂。这个失败模式比邻居严厉,值得单独门控。

为什么没用 COMPILE_LANG_AND_ID 生成器表达式

CUDA_INHERIT_COMPILE_OPTIONS 默认 ON,cmake/targets/common.cmake:37SUNSHINE_COMPILE_OPTIONS 的每个元素包成 --compiler-options=${flag}。往这个列表里放 genex 会产生嵌套 genex,对 CUDA 编译单元求值成一个裸的 --compiler-options=。目前在 Windows 上不可达,但普通 if() 能彻底避开这个坑,也和本文件下方 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND ...) 的既有写法一致。

@qiin2333
qiin2333 merged commit 949bc04 into master Aug 6, 2026
3 checks passed
@qiin2333
qiin2333 deleted the fix/build-debug-link branch August 6, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant