You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用LLVM/Clang+Ninja构建WinUI 3桌面应用?

可行性与实现方案

完全可以将WinUI项目从MSBuild切换为LLVM Clang-Cl + Ninja构建,核心是通过CMake自定义命令处理C++/WinRT头文件生成和XAML编译生成.g.h/.g.cpp文件两个关键环节,以下是具体实现步骤:

一、环境准备

确保已安装以下工具:

  • LLVM(包含clang-cl.exe,建议安装到默认路径或配置环境变量)
  • Ninja构建工具
  • CMake 3.25+
  • Windows SDK(需包含WinUI3相关组件,推荐最新稳定版)
  • C++/WinRT工具(cppwinrt.exe,随Windows SDK或Visual Studio默认安装,可在SDK路径下找到)

二、CMake配置核心要点

1. 指定编译器与生成器

在CMakeLists.txt开头设置Clang-Cl和Ninja:

cmake_minimum_required(VERSION 3.25)
project(WinUI3ClangNinjaDemo)

# 指定Clang-Cl编译器
set(CMAKE_CXX_COMPILER clang-cl)
set(CMAKE_C_COMPILER clang-cl)
# 指定Ninja生成器
set(CMAKE_GENERATOR Ninja)
# 设置Windows SDK版本(替换为你安装的实际版本)
set(CMAKE_SYSTEM_VERSION 10.0.22621.0)

2. 生成C++/WinRT头文件

通过add_custom_command调用cppwinrt.exe,生成WinUI3依赖的所有头文件:

# 定义WinUI3相关路径
set(WINDOWS_SDK_DIR "$ENV{WindowsSdkDir}")
set(WINDOWS_SDK_VERSION "$ENV{WindowsSDKVersion}")
set(WINUI_WINMD_PATH "${WINDOWS_SDK_DIR}References/${WINDOWS_SDK_VERSION}/Microsoft.UI.Xaml/Microsoft.UI.Xaml.winmd")

# 生成C++/WinRT头文件到指定目录
add_custom_command(
    OUTPUT Generated/CppWinRT
    COMMAND cppwinrt.exe -in "${WINUI_WINMD_PATH}" -out Generated/CppWinRT
    COMMENT "Generating C++/WinRT headers for WinUI3"
)

# 将生成目录加入包含路径
include_directories(Generated/CppWinRT)

如果项目包含自定义WinMD文件,需将其路径追加到-in参数中。

3. 生成XAML对应的.g.h/.g.cpp文件

WinUI的XAML文件需要通过xamlcompiler.exe生成C++代码,同样用add_custom_command批量处理:

# 列出项目中所有XAML文件
set(XAML_FILES MainWindow.xaml App.xaml)

foreach(XAML_FILE ${XAML_FILES})
    get_filename_component(XAML_NAME ${XAML_FILE} NAME_WE)
    # 定义生成的.g文件路径
    set(G_H_FILE Generated/Xaml/${XAML_NAME}.g.h)
    set(G_CPP_FILE Generated/Xaml/${XAML_NAME}.g.cpp)
    
    add_custom_command(
        OUTPUT ${G_H_FILE} ${G_CPP_FILE}
        COMMAND xamlcompiler.exe /generatecode 
                /in:${XAML_FILE} 
                /out:${G_H_FILE} 
                /outcpp:${G_CPP_FILE} 
                /namespace:WinUI3ClangNinjaDemo  # 替换为你的项目命名空间
                /winmdpath:"${WINUI_WINMD_PATH}"
        DEPENDS ${XAML_FILE}
        COMMENT "Generating code for ${XAML_FILE}"
    )
    # 将生成的.cpp文件加入源文件列表
    list(APPEND GENERATED_XAML_SOURCES ${G_CPP_FILE})
endforeach()

# 将XAML生成目录加入包含路径
include_directories(Generated/Xaml)

4. 配置编译与链接

最后添加可执行文件,链接WinUI3依赖库,并设置Clang-Cl兼容的编译选项:

add_executable(${PROJECT_NAME}
    App.xaml.cpp
    MainWindow.xaml.cpp
    ${GENERATED_XAML_SOURCES}
)

# 链接WinUI3及Windows Runtime库
target_link_libraries(${PROJECT_NAME}
    Microsoft.UI.Xaml.lib
    windowsapp.lib
)

# 设置Clang-Cl编译选项
target_compile_options(${PROJECT_NAME} PRIVATE
    /EHsc
    /DWIN32_LEAN_AND_MEAN
    /D_UNICODE
    /DUNICODE
    /permissive-  # 启用严格C++标准检查
)

三、常见问题解决

  • 头文件缺失:检查cppwinrt.exe的-in参数是否包含所有依赖的WinMD文件(包括项目自身生成的WinMD,如果有自定义控件);确认生成目录已正确加入include_directories。
  • Clang-Cl兼容性问题:部分MSBuild专属编译选项需替换为Clang-Cl支持的等价选项,比如/Zc:__cplusplus需保留以启用标准C++版本定义。
  • Ninja缓存异常:若生成文件未更新,需删除CMake缓存目录(build文件夹)后重新执行cmake ..生成构建文件。

四、关于第三方项目适配

你提到的cmake-cpp-winrt-winui3项目无法适配的问题,可基于它修改:替换编译器设置为Clang-Cl,调整XAML编译命令的参数,确保生成的代码符合Clang-Cl的语法要求即可。

内容的提问来源于stack exchange,提问作者Abhi_M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:40:24