
windows-rs 依赖管理全景从 Windows SDK、WDK 到 WebView2 的单一版本钉扎模型【免费下载链接】windows-rsRust for Windows项目地址: https://gitcode.com/GitHub_Trending/wi/windows-rs导读本文基于windows-rs仓库的 docs/dependencies.md系统剖析该项目如何钉扎pin并验证构建与工具链所依赖的全部外部资源——Windows SDK、Windows WDK、WinRT Contracts、libclang、Windows App SDK 与 WebView2。全文围绕“一个依赖、一个所有者、以运行来证明版本有效”的模型展开你不仅能看到每一份依赖钉在哪个版本、由哪个工具拥有、如何获取还能从源码层面理解read_str_const跨文件读取、tool_reactor守卫断言与gen.yml零差异回归等实现细节。读完本文你可以独立判断如何升级任一依赖、如何离线覆盖下载路径以及 CI 为何能在不安装 LLVM 的情况下始终使用固定的 libclang 解析头文件。依赖清单什么被钉住、由谁钉住docs/dependencies.md追踪的是构建/工具链与运行时层面的外部依赖Windows SDK、WDK、WinRT 合约、libclang、Windows App SDK、WebView2不包含Cargo.toml中以[workspace.dependencies]集中管理的 crates.io Rust 依赖。仓库没有一个集中的版本注册表。每一项外部依赖都有唯一的拥有工具owning tool该工具以const声明钉扎版本、按该精确版本下载/消费构件并在 CI.github/workflows/gen.yml中运行——运行工具本身就证明了钉扎版本仍然有效。验证方式分两类生成器Generatorstool_win32、tool_winrt、tool_webview、tool_reactor重新生成已提交的产物gen.yml运行后执行git diff --exit-code版本过期会产生 diff 并导致失败。验证器Validatorstool_clang以及生成器内部的内置守卫guard只做断言、不写任何文件违反断言会大声 panic使任务失败且保持工作树干净。一览表如下版本号以当前仓库实际内容为准依赖版本所有者pin获取方式验证方式libclang22.1.8LIBCLANG_VERSION- crates/libs/clang/src/provision.rs下载NuGetlibclang.runtime.win-archgit稀疏检出 LLVM 头文件tool_clang验证器 运行时断言Windows SDK10.0.28000.2270SDK_VERSION- crates/tools/win32/src/main.rs下载NuGettool_win32零差异重生成Windows WDK10.0.28000.1839WDK_VERSION- crates/tools/win32/src/km.rs下载NuGettool_win32零差异重生成SDK ContractsWinRT10.0.28000.2270CONTRACTS_VERSION- crates/tools/winrt/src/main.rs下载NuGettool_winrt零差异重生成WebView2 SDK 头文件1.0.4078.44WEBVIEW2_VERSION- crates/tools/webview/src/main.rs下载NuGettool_webview零差异重生成WinUI / Windows App SDK 元数据.winmd2.4.0WINDOWS_APP_SDK_VERSION- crates/tools/reactor/src/main.rs下载NuGettool_reactor对已提交元数据的零差异重生成Windows App SDK 运行时2.4.0RUNTIME_VER- crates/libs/reactor-setup/src/lib.rs下载NuGettool_reactor守卫 WINDOWS_APP_SDK_VERSION且reactor.yml一致WebView2 运行时投影1.0.4078.44WEBVIEW2_VER- crates/libs/reactor-setup/src/lib.rs下载NuGettool_reactor守卫 WEBVIEW2_VERSIONLLVM / libclangCI22.1.8LIBCLANG_VERSION- crates/libs/clang/src/provision.rs通过tool_clang path下载NuGettool_clang加载 pin 并断言其版本关键机制pin 永不复制只被读回当一个 crate 需要跟踪另一个 crate 拥有的 pin 时所有者会通过helpers::read_str_const直接从对方源码中读取常量并断言两者一致。该函数在源码中定位const NAME: str ...声明支持pub const与跨行字符串字面量若文件不可读或常量不存在会大声 panic。如 helpers/src/lib.rs 的单元测试所示它还会规避前缀碰撞——SDK_VERSION不会误匹配SDK_VERSION_EXTRA。值得强调的是windows-clang始终保持为纯粹的 libclang 库不是SDK/运行时版本的共享存放处跨文件读取全部经由read_str_const这一唯一机制。Toolchainlibclang 的单一常量钉扎头文件刮取器tool_win32、tool_webview用 libclang 解析 C/C。版本被钉扎的原因在于clang 的宏捕获行为在不同主版本间会发生漂移从而静默改变生成的元数据。钉在22.1.8是为了保证任何一次 CI 与全新检出都能得到完全相同的解析结果。所有者与获取方式crates/libs/clang/src/provision.rs 声明LIBCLANG_VERSION 22.1.8。libclang.dll来自dotnet/clangsharp.NET Foundation发布的libclang.runtime.win-archNuGet 包配套的 clang 内建资源头文件仅非 x64 通道需要用于调和 aarch64 的__prefetch内建则来自一次 blobless、浅层、稀疏的git检出clang/lib/Headersllvmorg-ver标签见 provision.rs。因此 DLL 与头文件共享同一个常量 pin永远不会漂移。获取逻辑在ensure_libclang中若环境变量LIBCLANG_PATH未设置则通过nuget_package与 SDK/WDK/WebView2 共享的 NuGet 全局缓存拉取钉扎的libclang.runtime.win-arch包并将LIBCLANG_PATH指向其runtimes/rid/native/目录非 x64 通道还会额外拉取钉扎的 LLVM 资源头文件。libclang_dir只解析/拉取目录而不修改环境变量clang_resource_dir则尊重CLANG_RESOURCE_DIR覆盖。LIBCLANG_PATH/CLANG_RESOURCE_DIR为离线机器提供覆盖手段。三个刮取器都会调用它因此它们的gen.yml任务无需安装 LLVM——无论 CI 还是全新检出始终用钉扎的22.1.8解析。下载细节与 CI 集成nuget_package先检查 NuGet 全局缓存NUGET_PACKAGES可覆盖支持全局缓存布局或扁平恢复布局缺失时用 Windows 自带的curl.exe/tar.exe优先System32避免被 PATH 上的同名工具遮蔽从https://www.nuget.org/api/v2/package/{id}/{version}下载并解压。CI 中的每个 workflow 都自行按需提供钉扎的 libclanggen.yml的刮取器调用ensure_libclangclippy.yml完全不加载 libclangcargo clippy不做解析test.yml的test_clang套件在运行时加载 libclang通过echo LIBCLANG_PATH$(cargo run -q -p tool_clang -- path) $GITHUB_ENV从同一 pin 导出LIBCLANG_PATH。tool_clang path打印windows_clang::libclang_dir()从而把unsafe set_var隔离在多线程测试运行器之外。Linux CI 任务只构建不需要 libclang 的代码。tool_clang验证拉取、加载并对 pin 做版本断言与刮取器相同的预置流程不写任何文件。升级方式只改LIBCLANG_VERSION一个常量——它同时驱动 NuGet DLL 与llvmorg-ver头文件 git 标签无需触碰其他任何位置。然后运行tool_clang必须通过并重新生成全部元数据。没有预构建资产上限DLL 来自 NuGet、头文件来自 git 标签两者都跟踪当前 LLVM。Windows SDK、WDK 与 WinRT Contracts三者分别喂给一个自研生成器产出提交在windows-default中的.winmd。元数据被内嵌以供 Rust 构建工具使用同时以文件形式供外部工具使用来源记录在 crates/libs/default/readme.md。windows-bindgen、windows-rdl、windows-clang都依赖windows-default因此其构建器无需文件系统路径即可选择元数据链接这些 crate 的二进制会同时包含两份元数据文件。包所有者pin产出Microsoft.Windows.SDK.CPP[.arch]SDK_VERSION-tool_win32Windows.Win32.winmd的 um 刮取半部Microsoft.Windows.WDK.x64WDK_VERSION-tool_win32Windows.Win32.winmd的 km 刮取半部Microsoft.Windows.SDK.ContractsCONTRACTS_VERSION-tool_winrtWindows.winmd获取windows_clang::nuget_package(id, version)从 NuGet 全局缓存恢复否则从 nuget.org 下载NUGET_PACKAGES覆盖缓存路径。tool_win32一次运行两个刮取WDK 的 km 刮取复用与 um 刮取相同的SDK_VERSION头文件二者共享同一 crateWDK_VERSION是 km.rs 中独立的 pin。每个包内嵌的“营销名”include/lib 目录如10.0.28000.0由版本派生而来helpers::marketing_dir取版本的前三个组件并补.0见 helpers/src/lib.rs 及其单元测试。因此版本是唯一需要编辑的常量不存在第二个需要同步的目录常量。升级方式修改所属常量运行cargo run -p tool_win32|winrt提交重新生成的.rdl快照与.winmd。注意CONTRACTS_VERSION恰好与SDK_VERSION共享10.0.28000构建号但它们是两个独立的 NuGet 包、各自独立的 pin互不耦合、可以各自演进。元数据生成管线源码佐证按 default/readme.mdWindows.Win32.winmd由tool_win32分三阶段生成A) 用windows-clang刮取 SDK C/C 头文件到提交的metadata/win32/*.rdl快照可人工评审的事实来源与 target 下未提交的 um winmdB) 刮取 WDK 内核态头文件到metadata/wdk/*.rdl在同一扁平命名空间内对 Win32 做叠加并生成 km winmdC) 用windows-metadata合并两个 winmd——同名字枚举取并集使 um 头文件中被截断的值类型如FILE_INFORMATION_CLASS在一个枚举里携带 km 定义的完整成员集。tool_roundtrip在无 SDK 的情况下重新验证往返一致性。Windows.winmd则由tool_winrt合并 SDK Contracts 包中逐合约的.winmd替换外部mdmerge工具反编译为提交的metadata/winrtRDL 快照后再编译回 winmd。WebView2头文件刮取与运行时投影分离WebView2 只提供 C/C SDK 头文件因此windows-webview从这些头文件刮取绑定WinRTCore元数据与运行时投影 DLL 是彼此独立的构件。构件所有者 / 位置使用者WebView2.h、WebView2Interop.hWEBVIEW2_VERSION-tool_webview下载而非 vendoredtool_webview- crates/libs/webview/src/bindings.rsMicrosoft.Web.WebView2.Core.winmd由tool_reactor按WEBVIEW2_VERSION重新生成到crates/tools/reactor/winmd/tool_webview、tool_reactor运行时投影Core.dllWEBVIEW2_VERcrates/libs/reactor-setup/src/lib.rs自包含应用Evergreen 运行时.github/workflows/webview.ymlCI 测试宿主头文件下载而非 vendoredtool_webview通过nuget_package拉取钉扎的 NuGet 包并解析其中头文件升级就是一行WEBVIEW2_VERSION编辑。libclang 钉扎与tool_win32相同tool_webview调用ensure_libclangassert_libclang_version确保用精确钉扎的22.1.8解析其gen.yml任务无需安装 LLVM只需WebView2.h引入的系统头文件对应的 SDK include 路径。运行时投影升级reactor-setup中的WEBVIEW2_VER它必须等于WEBVIEW2_VERSION——由tool_reactor断言。Core.winmd由tool_reactor按WEBVIEW2_VERSION刷新进 reactor 元数据。完整的管线与 COM-WinRT 桥接说明见 windows-webview。WinUI / Windows App SDK元数据与运行时是一枚硬币的两面windows-reactor由 WinUI / Windows App SDK 的.winmd生成windows-reactor-setup负责暂存匹配的运行时使 reactor 应用得以运行。元数据与运行时是同一发布的两个面绑定到同一个数字。元数据是重新生成的不是手工复制的。tool_reactor拥有WINDOWS_APP_SDK_VERSION 2.4.0。每次运行它都会下载对应版本的伞形Microsoft.WindowsAppSDK元包读取其 nuspec 中钉扎的各组件精确版本Foundation / InteractiveExperiences / WinUI分别下载各组件并把它们的.winmd——外加按WEBVIEW2_VERSION的Microsoft.Web.WebView2.Core.winmd——拷贝到提交的元数据目录crates/tools/reactor/winmd/。gen.yml重跑该工具并对任何 diff 报错因此元数据可证明与 pin 一致。该目录中的extras.winmd由tool_reactor从Windows.Win32.winmd生成并非来自某个包。元数据保持提交状态是因为tool_webview与tool_composition也要读取它。构件所有者 / 位置使用者WinUI / Windows App SDK.winmdWebView2.Core.winmd按WINDOWS_APP_SDK_VERSION重新生成到crates/tools/reactor/winmd/tool_reactor、tool_webview、tool_compositionMicrosoft.WindowsAppSDK.RuntimeRUNTIME_VERcrates/libs/reactor-setup/src/lib.rs应用运行时部署app.manifest、runtime.txtcrates/libs/reactor-setup/assets/已提交运行时暂存运行时安装器.github/workflows/reactor.ymlCI 测试宿主windows-reactor-setup是发布出去的运行时辅助 crate没有生成的构件因此其 pin 无法靠重生成来证明。作为替代tool_reactor在每次运行时守卫它们一旦漂移就大声失败断言三点WINDOWS_APP_SDK_VERSION元数据等于RUNTIME_VER运行时——一个数字同时驱动两者WEBVIEW2_VER等于WEBVIEW2_VERSION使暂存的 WebView2 运行时与绑定所面向的 ABI 匹配reactor.yml的安装器 URL 安装RUNTIME_VER.../windowsappsdk/major.minor/ver/使 CI 自测运行的应用与最终发布运行时一致。从源码看这些守卫正是通过helpers::read_str_const从reactor-setup读回RUNTIME_VER、WEBVIEW2_VER见 crates/tools/reactor/src/main.rs再与工具自身常量及tool_webview的WEBVIEW2_VERSION比对。升级元数据与运行时的完整步骤同步提升WINDOWS_APP_SDK_VERSIONtool_reactor与RUNTIME_VERreactor-setup更新reactor.yml的安装器 URL运行cargo run -p tool_reactor并提交刷新的元数据。守卫强制版本一致重生成强制元数据一致。两个补充事实assets/app.manifest是没有提交生成器的生成式激活资产——它把 App SDK 的package.appxfragment文件转换为 SxS fusion 格式源版本见其文件头且向前兼容只在 reactor 控件集需要新增迁移类时才刷新而非每次升级都动resources.pri仅在自包含部署as_self_contained时从 App SDK 运行时包暂存框架依赖式暂存不拷贝它。详见 windows-reactor 与 windows-reactor-setup。下载机制两条独立的 NuGet 路径两条路径都使用https://www.nuget.org/api/v2/package/{id}/{version}windows_clang::nuget_package——刮取/代码生成工具tool_win32、tool_winrt、tool_webview、tool_reactor使用。恢复到 NuGet 全局缓存NUGET_PACKAGES可覆盖否则用内置curl/tar下载。布局无关——每个调用方索引其需要的子树。reactor-setup的暂存——在每个消费应用的build.rs中运行用于暂存 App SDK 运行时与 WebView2 投影。零依赖仅 std Windows 自带的curl.exe/tar.exe这正是它不复用nuget_package的原因。tool_*与 pin 的配对总结工具证明的 pin方式tool_win32SDK_VERSION、WDK_VERSIONWindows.Win32.winmd的零差异重生成um km 刮取及合并tool_winrtCONTRACTS_VERSIONWindows.winmd的零差异重生成tool_webviewWEBVIEW2_VERSIONcrates/libs/webview/src/bindings.rs 的零差异重生成tool_clangLIBCLANG_VERSION驱动 NuGet DLL llvmorg-ver头文件标签纯检查断言tool_reactorWINDOWS_APP_SDK_VERSIONreactor-setup 同步winmd 文件 绑定的零差异重生成守卫读取 reactor-setup 常量所有跨文件读取都经由helpers::read_str_const因此每个 pin 只由其所有者声明一次其余任何地方都从源码读回。这构成了一个可审计、可自动验证、升级路径单一的依赖治理闭环改一个常量、跑一次工具、提交生成物CI 用git diff --exit-code把漂移拦截在合并之前。【免费下载链接】windows-rsRust for Windows项目地址: https://gitcode.com/GitHub_Trending/wi/windows-rs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考