FEATURED · 精选文章

windows-rs 构建工具链的核心元数据底座:windows-default 深入解析

发布时间 / 2026/9/15 10:50:03
来源 / 创域科博编辑部
栏目 / 资讯中心
windows-rs 构建工具链的核心元数据底座:windows-default 深入解析 windows-rs 构建工具链的核心元数据底座windows-default 深入解析【免费下载链接】windows-rsRust for Windows项目地址: https://gitcode.com/GitHub_Trending/wi/windows-rswindows-default是 Rust for Windowswindows-rs仓库中一个看似不起眼、却支撑起整套构建工具链的 crate它以两个内嵌字节切片的形式把 Windows RuntimeWinRT与 Win32/WDK 的权威元数据打包进构建工具。本文围绕 windows-default 文档 展开结合仓库源码与工具实现说明它解决了什么问题、如何被 bindgen/RDL/Clang 等构建 crate 消费、自定义元数据工具如何复用其工作流以及这些.winmd字节是如何被生成、打包与验证的。读完本文你将掌握在自定义元数据处理工具中直接使用WINRT/WIN32字节的方法并理解 windows-rs 全套代码生成流水线的元数据来源。一、windows-default 是什么windows-default是 windows-rs 仓库 crates/libs/default 目录下的一个零依赖 crate其唯一职责是将规范化的 Windows Runtime 与 Windows API 元数据以字节切片的形式内嵌进二进制。构建工具如windows-bindgen、windows-rdl、windows-clang在需要标准元数据时直接使用WINRT和WIN32两个静态常量而无需在磁盘上定位独立的.winmd文件也无需用户安装 Windows SDK。crate 的核心实现极为精简全部代码就是 src/lib.rs 中的两个include_bytes!#![doc include_str!(../readme.md)] /// Windows Runtime metadata. pub static WINRT: [u8] include_bytes!(../Windows.winmd); /// Windows API metadata. pub static WIN32: [u8] include_bytes!(../Windows.Win32.winmd);两个文件都随 crate 发布并以内嵌方式编译进二进制crate 自身不进行任何文件解压或磁盘 I/O。两个静态字节切片静态常量内嵌文件内容WINRTWindows.winmdWindows Runtime 契约WinRT contractsWIN32Windows.Win32.winmdWindows SDK 与 WDK 的 Win32 API需要注意WIN32是一个单一扁平的Windows.Win32元数据集。发布版windows与windows-syscrate 中的 feature 命名空间是后续由tool_package工具生成的并不存在于这份元数据之中。从 Cargo.toml 可以看到 crate 的基本事实当前版本0.100.0edition 2024rust-version 1.95许可证为MIT OR Apache-2.0没有任何运行时依赖——这保证了它作为构建期依赖足够轻量。二、什么时候应该直接使用 windows-default文档明确给出了分层使用的建议直接使用windows-default只是少数场景的选择应用程序应使用聚焦的 crate或使用windows-bindgen需要宽泛预生成 API 面的二进制程序应使用 windows 或 windows-sys大多数代码生成器应在自己已有的 builder 上调用input_default或reference_default只有实现一个接受内存中 winmd 字节的元数据工具时才需要直接依赖windows-default。简言之windows-default面向的是元数据工具的构建者而不是Windows API 的使用者。三、第一个工作流把标准元数据加入自定义索引如果正在编写一个自定义的元数据处理工具例如需要把组件特定的 winmd 与标准定义合并起来查询可以按以下四步完成全程不需要定位任何 SDK 安装从WINRT与WIN32构造windows_metadata::reader::File值加入组件特定的 winmd 文件基于合并后的文件集合构建一个windows_metadata::reader::Index直接查询或转换该索引。仓库测试给出了这一模式的直接证据例如 crates/tests/libs/metadata/tests/assembly_name.rs 中let reader reader::File::new(windows_default::WIN32.to_vec()).unwrap();以及在 crates/tests/libs/metadata/tests/reader.rs 中同时使用两个字节构造多个File并建立索引reader::File::new(windows_default::WINRT.to_vec()).unwrap(), reader::File::new(windows_default::WIN32.to_vec()).unwrap(),tool_reactor就是采用这一模式的真实案例它的元数据解析器在把 WinUI winmds 与标准定义合并时直接以字节形式引用windows_default::WIN32见 crates/tools/reactor/src/main.rs 的reference_bytes(windows_default::WIN32)。需要强调如果目标只是编译 RDL 或生成 Rust 代码应优先使用相邻构建 crate 的 builder 方法——它们已经替你完成了字节 → File的转换不必手工重复这套流程。四、与构建 crate 的集成方式构建 crate 均依赖windows-default并通过各自的 builder 暴露标准元数据。因此调用方不需要单独的依赖也不需要指向 Windows SDK 的路径。Crate默认行为windows-bindgen无输入时隐式使用显式通过input_default启用windows-rdlreference_default或 writer 的input_defaultwindows-clangreference_default以及仅针对 WinRT 的resolution_defaultwindows-metadata由调用方从切片构造reader::File值4.1 bindgen隐式默认与--in default在 crates/libs/bindgen/src/lib.rs 中可以看到默认输入的构造方式fn default_input() - VecFile { [windows_default::WINRT, windows_default::WIN32] .into_iter() .map(|bytes| File::new(bytes.to_vec()).unwrap()) .collect() }而expand_input同文件 L706 起的逻辑说明了显式输入会覆盖隐式默认这一关键规则当input_default为真时先用default_input()作为基底再逐个追加显式的路径或字节输入当其为假时则从空集合开始。一旦添加任何显式 bindgen 输入隐式默认输入即被禁用如果自定义元数据引用了标准类型就必须调用input_default补上标准定义。此外windows-bindgen的文本适配器接受--in default命令行参数而 bindgen、RDL、Clang 的 builder 走的是显式 default 方法它们的路径式输入方法会把字面量default当作普通路径处理二者语义不同不要混淆。字节输入 APIInput::Bytes见 crates/libs/bindgen/src/lib.rs则仍然保留供已经在内存中持有自定义元数据的场景使用。4.2 RDL 与 Clangreference_defaultwindows-rdl的 reader 在 crates/libs/rdl/src/reader/mod.rs 中提供reference_default方法把WINRT与WIN32转换为metadata::reader::File追加到引用集合writer 侧同样支持该选项见 crates/libs/rdl/src/writer/mod.rs。windows-clang在 crates/libs/clang/src/lib.rs 中以相同方式把两个切片加入 winmd 引用列表并提供 WinRT-only 的resolution_default。五、易踩的坑Pitfalls文档明确了五个必须注意的边界这里结合源码进一步展开WIN32是单一份扁平元数据。发布版windows/windows-sys的 feature 命名空间由tool_package在后续阶段切分不要期望在这份字节里看到按 feature 组织的结构。显式输入会关闭隐式默认。如前文expand_input所示bindgen 中加显式输入 失去默认输入需要时务必显式调用input_default。reference_default与resolution_default在windows-clang中不是同义词。前者可以抑制已经定义的声明后者只负责对 WinRT ABI 投影进行分类用途完全不同。链接即嵌入全部载荷。只要链接了windows-default即使工具只读取其中一个静态两个.winmd字节也都会被编进二进制这是include_bytes!的固有语义。字节只是构建输入。它们不提供任何 Windows DLL也不会让某个 API 在运行时的操作系统上可用windows-default面向构建期工具而非运行时依赖。六、内部实现这些 winmd 是如何生成的以下内容面向贡献者对普通使用者不是必需知识但有助于理解元数据的可信来源。6.1 构建方式crate 本身无依赖src/lib.rs用include_bytes!暴露每个已提交的.winmd。两份文件的生成工具与可审查源码对应如下文件生成器可审查源码Windows.winmdcargo run -p tool_winrtmetadata/winrtWindows.Win32.winmdcargo run -p tool_win32metadata/win32与metadata/wdktool_winrt的工作是合并 Windows SDK 的契约元数据 → 写出规范化的 RDL → 再把该 RDL 编译回Windows.winmd。其输入来自Microsoft.Windows.SDK.ContractsNuGet 包版本10.0.28000.2270固定在 crates/tools/winrt/src/main.rs 中。tool_win32的工作分三个阶段详见 crates/libs/default/readme.md(A)通过windows-clang抓取 Windows SDK 的 C/C 头文件产出已提交的metadata/win32/*.rdl快照人可审查的事实源与一个未提交的 um winmd(B)抓取 WDK 内核态头文件产出metadata/wdk/*.rdl在同一个扁平命名空间里对 Win32 做增量补充与未提交的 km winmd并针对阶段 A 的 um winmd 解析(C)用windows-metadata合并两个 winmd——对同名枚举做联合使被 um 头截断的值类型如FILE_INFORMATION_CLASS在一个枚举中携带 km 定义的完整成员集。SDK 头文件版本为10.0.28000.2270固定在 crates/tools/win32/src/main.rsWDK 头文件版本为10.0.28000.1839固定在 crates/tools/win32/src/km.rs。包版本与出处可进一步查看 Dependencies。6.2 可审查的事实源设计无论 WinRT 还是 Win32 路径RDL 快照才是可审查的真相来源一次 WinRT 元数据变更会体现为可读的 RDLgit diff而tool_roundtrip会在不依赖 SDK 的情况下重新校验 round-trip 的一致性。6.3 打包仓库的.gitignore通常排除.winmd文件但为本 crate 的两个已提交载荷开了例外。由于 Cargo 默认打包被跟踪的文件Cargo.toml无需单独的include列表只需保证cargo package -p windows-default同时包含两个.winmd文件即可。6.4 测试元数据本身通过它的消费者得到验证test_bindgen、test_rdl、test_clang覆盖默认输入与字节输入两条路径tool_winrt、tool_win32、tool_roundtrip验证元数据生成的确定性tool_yml生成的 CI 工作流像对待其他库 crate 一样构建并文档化windows-default。改动载荷或其生成器后应重新运行所属生成器并确认其他生成器保持输出中性output-neutral即不会因为这次改动产生意外差异。七、小结windows-default用两个include_bytes!静态常量把 Windows 平台最权威的两份元数据变成了构建工具的随身行李。理解它的存在与边界是深入 windows-rs 代码生成流水线的第一步无论是通过input_default/reference_default/resolution_default让构建 crate 自动获得标准定义还是在自己的元数据工具里直接消费WINRT/WIN32字节这套设计都让无 SDK 定位、纯内存元数据的构建体验成为可能。进一步阅读crates/libs/default/readme.md、windows-bindgen、windows-rdl、windows-clang、windows-metadata。【免费下载链接】windows-rsRust for Windows项目地址: https://gitcode.com/GitHub_Trending/wi/windows-rs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻