bindgen: Add mode to skip API that relies on things defined outside `--filter`
Suggestion
When creating a single bindings file within another crate, I'd like to use windows-bindgen with the default options, i.e.:
- Without
cfg, because the fact that this file is part of the crate shouldn't leak to users of the crate; - Without
package, because it's not a new package but a single file containing bindings to a subset of the Windows API specified via--filter; - Without
flatten, so that namespaces are preserved.
Would it be possible to create a mode like that? Right now the default with this example bindings.txt:
--out src/platform/windows_wgi/Windows.rs
--filter
Windows.Gaming.Input
Generates non-compiling code because some functions depend on types outside of the Windows.Gaming.Input namespace.
A workaround would be to include namespaces for the missing types, but they have dependencies as well and this quickly spirals out of control (as in: I end up listing most of the Windows API under --filter) to the point where using the windows crate directly makes more sense, both from a size as well as maintenance standpoint.
Perhaps this should go into a separate issue, but when running with flatten (which seems to automatically pull in all dependencies), a bunch of definitions are duplicated, causing a failed compile as well:
--out src/platform/windows_wgi/Windows.rs
--filter
Windows.Gaming.Input
--config flatten
If you skip over the APIs that don't satisfy --filter, the result would presumably be incomplete. Is that really desirable?
@riverar if that portion of the API is needed, I'd add it to --filter. In the described case, concerning private bindings that are generated specifically to implement a crate, the code wouldn't compile if necessary things are missing.
As a reminder we could also generate commented-out function signatures to indicate what "could have been" there if a list of missing types is also provided? gir does a very similar thing and it's been super useful to me when searching for "apparently missing" function signatures that I expected on a type.
In any case this idea might be problematic when missing types are used in structs or type-definitions for vtables?
In any case this idea might be problematic when missing types are used in structs or type-definitions for vtables?
Yes, this is a very difficult problem. I'd like filtering to be more intelligent though and it's something that I've been wanting to work on, so I'll noodle on this some more.
Thanks @kennykerr! I wasn't exactly sure if the vtable definitions relied on (mostly) untyped *mut c_void in function arguments or not; that's likely the biggest source of these types.
I thought since the cfg generator should already understand exactly the hierarchy and dependendencies, code for this should already be in place?
(i.e. cfg disables the high-level function taking/returning the missing type, but doesn't affect the vtable layout?)
We already include bindings for Windows.Gaming.Input, so I'm a bit confused.
Can you provide a use case here? Am struggling to think of a reason why you'd want to emit types/APIs from Windows.Gaming.Input but only those that are self-contained to that namespace.
If the goal is to generate the smallest set of bindings possible, for a specific set of APIs/types, maybe it makes more sense to accept an explicit list of APIs/types.
@riverar you self-answered it:
If the goal is to generate the smallest set of bindings possible, for a specific set of APIs/types, maybe it makes more sense to accept an explicit list of APIs/types.
Specifically this is what I want, with bindgen hiding/disabling (recursively) any types, and functions that use types, that are not enabled.
The use-case is no longer having to upgrade versions throughout a growing number of crates whenever yet another breaking windows release is published. And to lighten dependencies in crates that only access a few types internally, and don't expose anything publicly.
I think I made some progress unraveling this one today. I hope to have something to share next week.
I don't know if this is related to this issue, or if there's a separate issue for this request, but I'd also like a reverse functionality: specifying a single filter to include all the dependencies. E.g. for the use case in #3242 I'd rather have specified --filter Microsoft.UI.Xaml.Data.INotifyPropertyChanged, and the types it depends on were automatically included.
Yep, that's why this is not a simple fix. Both models are important but not very composable.
Thanks @kennykerr, this works awesome! Looking forward to seeing it in a future release (and hope someone can help me resolve my remaining win32metadata PRs before such a release is cut)!
I'd like to remind you of this suggestion above:
As a reminder we could also generate commented-out function signatures to indicate what "could have been" there if a list of missing types is also provided?
girdoes a very similar thing and it's been super useful to me when searching for "apparently missing" function signatures that I expected on a type.
Right now an external source like ILSpy or the windows-rs codebase / docs are needed to figure out what additional types (and from which namespaces) to enable to get access to a specific function. It'd be awesome if those could be generated in a "commented-out" style to address the above.