Skip to content

Commit 63e98c1

Browse files
authored
Add bindgen argument documentation (#3617)
1 parent bbe2bf3 commit 63e98c1

File tree

3 files changed

+205
-2
lines changed

3 files changed

+205
-2
lines changed

crates/libs/bindgen/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ windows-threading = { workspace = true }
1313
serde = { workspace = true, features = ["derive"] }
1414
serde_json = { workspace = true, features = ["std"] }
1515

16+
[dev-dependencies]
17+
windows-link = { workspace = true }
18+
1619
[lints]
1720
workspace = true
1821

crates/libs/bindgen/readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ fn main() {
2424
"--out",
2525
"src/bindings.rs",
2626
"--flat",
27+
"--sys",
2728
"--filter",
2829
"GetTickCount",
2930
];
3031
31-
windows_bindgen::bindgen(args);
32+
windows_bindgen::bindgen(args).unwrap();
3233
}
3334
```
3435

crates/libs/bindgen/src/lib.rs

Lines changed: 200 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,206 @@ use winmd::*;
5252
mod method_names;
5353
use method_names::*;
5454

55-
/// The Windows code generator.
55+
/// The conventional way of calling the `bindgen` function is as follows:
56+
///
57+
/// ```rust,no_run
58+
/// fn main() {
59+
/// let args = [
60+
/// "--out",
61+
/// "src/bindings.rs",
62+
/// "--filter",
63+
/// "GetTickCount",
64+
/// ];
65+
///
66+
/// windows_bindgen::bindgen(args).unwrap();
67+
/// }
68+
/// ```
69+
///
70+
/// Here is a list of supported arguments.
71+
///
72+
/// | Argument | Description |
73+
/// |----------|-------------|
74+
/// | `--in` | .winmd files or directories to include. |
75+
/// | `--out` | File name where the generated bindings will be saved. |
76+
/// | `--filter` | APIs to include or exclude in the generated bindings. |
77+
/// | `--rustfmt` | Overrides the default Rust formatting. |
78+
/// | `--derive` | Extra traits for types to derive. |
79+
/// | `--flat` | Avoids the default namespace-to-module conversion. |
80+
/// | `--no-allow` | Avoids generating the default `allow` attribute. |
81+
/// | `--no-comment` | Avoids generating the code generation comment. |
82+
/// | `--no-deps` | Avoids dependencies on the various `windows-*` crates. |
83+
/// | `--sys` | Generates raw or sys-style Rust bindings. |
84+
/// | `--implement` | Includes implementation traits for WinRT interfaces. |
85+
/// | `--link` | Overrides the default `windows-link` implementation for system calls. |
86+
///
87+
///
88+
/// # `--out`
89+
///
90+
/// Exactly one `--out` argument is required and instructs the `bindgen` function where to write the bindings.
91+
///
92+
/// # `--filter`
93+
///
94+
/// At least one `--filter` is required and indicates what APIs to include in the generated bindings.
95+
/// The following will, for example, also include the `Sleep` function:
96+
///
97+
/// ```rust
98+
/// let args = [
99+
/// "--out",
100+
/// "src/bindings.rs",
101+
/// "--filter",
102+
/// "GetTickCount",
103+
/// "Sleep",
104+
/// ];
105+
/// ```
106+
///
107+
/// The `--filter` argument can refer to the function or type name and nothing more. You can also refer
108+
/// to the namespace that the API metadata uses to group functions and types:
109+
///
110+
/// ```rust
111+
/// let args = [
112+
/// "--out",
113+
/// "src/bindings.rs",
114+
/// "--filter",
115+
/// "Windows.Foundation.Numerics",
116+
/// "!Windows.Foundation.Numerics.Matrix3x2",
117+
/// ];
118+
/// ```
119+
///
120+
/// In this example, all types from the `Windows.Foundation.Numerics` namepace are included with the
121+
/// exception of `Matrix3x2` which is excluded due to the `!` preamble.
122+
///
123+
/// # `--in`
124+
///
125+
/// `--in` can indicate a .winmd file or directory containing .winmd files. Alternatively, the special
126+
/// "default" input can be used to include the particular .winmd files that ship with the `windows-bindgen`
127+
/// crate. This may used to combine the default metadata with specific .winmd files.
128+
///
129+
/// ```rust
130+
/// let args = [
131+
/// "--in",
132+
/// "default",
133+
/// "Sample.winmd",
134+
/// "--out",
135+
/// "src/bindings.rs",
136+
/// "--filter",
137+
/// "Sample",
138+
/// ];
139+
/// ```
140+
///
141+
/// # `--flat`
142+
///
143+
/// By default, the bindings include a mapping of namespaces to modules. Consider this example again:
144+
///
145+
/// ```rust
146+
/// let args = [
147+
/// "--out",
148+
/// "src/bindings.rs",
149+
/// "--filter",
150+
/// "GetTickCount",
151+
/// "Sleep",
152+
/// ];
153+
/// ```
154+
///
155+
/// The resulting bindings might look something like this:
156+
///
157+
/// ```rust
158+
/// pub mod Windows {
159+
/// pub mod Win32 {
160+
/// pub mod System {
161+
/// pub mod SystemInformation {
162+
/// #[inline]
163+
/// pub unsafe fn GetTickCount() -> u32 {
164+
/// windows_link::link!("kernel32.dll" "system" fn GetTickCount() -> u32);
165+
/// unsafe { GetTickCount() }
166+
/// }
167+
/// }
168+
/// pub mod Threading {
169+
/// #[inline]
170+
/// pub unsafe fn Sleep(dwmilliseconds: u32) {
171+
/// windows_link::link!("kernel32.dll" "system" fn Sleep(dwmilliseconds : u32));
172+
/// unsafe { Sleep(dwmilliseconds) }
173+
/// }
174+
/// }
175+
/// }
176+
/// }
177+
/// }
178+
/// ```
179+
///
180+
/// That's because the default metadata defines `GetTickCount` in the `Windows.Win32.System.SystemInformation`
181+
/// namespace while `Sleep` is defined in the `Windows.Win32.System.Threading` namespace. Fortunately, it's
182+
/// easy to turn that off by using the `--flat` argument:
183+
///
184+
/// ```rust
185+
/// let args = [
186+
/// "--out",
187+
/// "src/bindings.rs",
188+
/// "--flat",
189+
/// "--filter",
190+
/// "GetTickCount",
191+
/// "Sleep",
192+
/// ];
193+
/// ```
194+
///
195+
/// The resulting bindings now look something like this:
196+
///
197+
/// ```rust
198+
/// #[inline]
199+
/// pub unsafe fn GetTickCount() -> u32 {
200+
/// windows_link::link!("kernel32.dll" "system" fn GetTickCount() -> u32);
201+
/// unsafe { GetTickCount() }
202+
/// }
203+
/// #[inline]
204+
/// pub unsafe fn Sleep(dwmilliseconds: u32) {
205+
/// windows_link::link!("kernel32.dll" "system" fn Sleep(dwmilliseconds : u32));
206+
/// unsafe { Sleep(dwmilliseconds) }
207+
/// }
208+
/// ```
209+
///
210+
/// # `--no-allow`
211+
///
212+
/// The bindings also include an allow attribute that covers various common warnings inherent in
213+
/// generated bindings.
214+
///
215+
/// ```rust
216+
/// #![allow(
217+
/// non_snake_case,
218+
/// non_upper_case_globals,
219+
/// non_camel_case_types,
220+
/// dead_code,
221+
/// clippy::all
222+
/// )]
223+
/// ```
224+
///
225+
/// You can prevent this from being generated if you prefer to manage this yourself with the `--no-allow`
226+
/// argument.
227+
///
228+
/// # `--sys`
229+
///
230+
/// The `--sys` argument instruct the `bindgen` function to generate raw, sometimes called sys-style Rust
231+
/// bindings.
232+
///
233+
/// ```rust
234+
/// let args = [
235+
/// "--out",
236+
/// "src/bindings.rs",
237+
/// "--flat",
238+
/// "--sys",
239+
/// "--filter",
240+
/// "GetTickCount",
241+
/// "Sleep",
242+
/// ];
243+
/// ```
244+
///
245+
/// The resulting bindings now look something like this:
246+
///
247+
/// ```rust
248+
/// windows_link::link!("kernel32.dll" "system" fn GetTickCount() -> u32);
249+
/// windows_link::link!("kernel32.dll" "system" fn Sleep(dwmilliseconds : u32));
250+
/// ```
251+
///
252+
/// You'll notice that the bindings are simpler as there's no wrapper functions and other
253+
/// conveniences. You just need to add a dependency on the tiny [windows-link](https://crates.io/crates/windows-link) crate and you're all set.
254+
///
56255
#[track_caller]
57256
#[must_use]
58257
pub fn bindgen<I, S>(args: I) -> Warnings

0 commit comments

Comments
 (0)