Skip to content

Feature request: 原生支持 Windows 资源编译(图标 + 版本信息)嵌入 exe #365

Description

@FarnaHerry

Environment

  • mcpp version: 2026.8.5.4
  • Toolchain: llvm@22.1.8(自带的 llvm-windres.exe / llvm-rc.exe
  • Platform: Windows x64,lld 链接

Background

Windows GUI 应用通常需要把 exe 图标VERSIONINFO(版本/公司/产品名等元数据) 编进可执行文件。mcpp 目前不能把 .rc 资源文件编译进 exe,我只能靠链接参数绕过去,且版本信息还卡在 llvm-rc 的兼容问题上。

Current state(现状)

项目 能否实现 说明
exe 图标 ✅ 能用 通过 workaround 嵌入,Explorer 可见
版本元数据 ⚠️ 嵌进去了但 Windows 读不到 llvm-rc 生成的 VERSIONINFO 结构不被 GetFileVersionInfo 解析

Reproduction / 我当前的 workaround

  1. 项目根写 resources.rc
    1 ICON "assets/icon.ico"
    
    VS_VERSION_INFO VERSIONINFO
     FILEVERSION     0,2,0,0
     PRODUCTVERSION  0,2,0,0
     FILEFLAGSMASK   0x3fL
     FILEFLAGS       0x0L
     FILEOS          0x00040004L   // VOS_NT_WINDOWS32(llvm-rc 不认常量,需写数值)
     FILETYPE        0x1L          // VFT_APP
    BEGIN
      BLOCK "StringFileInfo"
      BEGIN
        BLOCK "080404b0"
        BEGIN
          VALUE "ProductVersion",   "0.2.0"
          ...
        END
      END
      BLOCK "VarFileInfo"
      BEGIN
        VALUE "Translation", 0x0804, 1200
      END
    END
    
  2. 用工具链自带的 llvm-windres.exe 手动编译成 COFF:
    llvm-windres resources.rc -O coff -o resources.res
  3. 把 resources.res 塞进 mcpp.toml:
    [target.'cfg(windows)'.build]
    ldflags = ["-Wl,-subsystem:windows", "-Wl,-entry:mainCRTStartup", "-lws2_32", "-ldwmapi", "../../../resources.res"]
  4. mcpp 把 ldflags 透传给 lld,lld 接受 .res 输入并把 .rsrc 资源节嵌入 exe。

Workaround 的脆弱性:

  • .res 是预编译的,mcpp 不跟踪它;改了图标/版本要手动重编,且不会触发增量重链接(ninja: no work to do)。
  • 链接工作目录是 target/<ha
  1. 资源文件可作为构建输入被正确跟踪(改动触发重编译/重链接)。
  2. 降级:资源文件缺失时跳过,不应导致构建/打包失败(图标是可选资产)。

Additional finding(需作者注意)

即便加上原生 .rc 编译,底层走 llvm-windres / llvm-rc 时,生成的 VERSIONINFO 存在兼容 bug:

  • llvm-readobj --coff-resources 能看到 exe 里有 Type: VERSIONINFO (ID 16) 资源。
  • 但 [System.Diagnostics.FileVersionInfo]::GetVersionInfo(exe) 读出的 FileDescription / FileVersion / ProductName 全为空。
  • 即:图标能正常嵌入,版本元数据 Windows 解析不了。这会影响 mcpp 原生支持后的实际效果,可能需要 mcpp 侧对版本资源做专门处理(或换用能生成合法 VS_VERSION_INFO 的编译器)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions