windows-rs icon indicating copy to clipboard operation
windows-rs copied to clipboard

bindgen: Add mode to skip API that relies on things defined outside `--filter`

Open MarijnS95 opened this issue 1 year ago • 9 comments

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

MarijnS95 avatar Jul 10 '24 14:07 MarijnS95

If you skip over the APIs that don't satisfy --filter, the result would presumably be incomplete. Is that really desirable?

riverar avatar Jul 10 '24 15:07 riverar

@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?

MarijnS95 avatar Jul 10 '24 15:07 MarijnS95

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.

kennykerr avatar Jul 10 '24 15:07 kennykerr

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?)

MarijnS95 avatar Jul 10 '24 15:07 MarijnS95

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 avatar Jul 10 '24 18:07 riverar

@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.

MarijnS95 avatar Jul 23 '24 09:07 MarijnS95

I think I made some progress unraveling this one today. I hope to have something to share next week.

kennykerr avatar Aug 09 '24 20:08 kennykerr

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.

Alovchin91 avatar Sep 03 '24 14:09 Alovchin91

Yep, that's why this is not a simple fix. Both models are important but not very composable.

kennykerr avatar Sep 12 '24 14:09 kennykerr

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? 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.

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.

MarijnS95 avatar Dec 15 '24 17:12 MarijnS95