能否使用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
相关产品推荐
相关产品推荐

