microsoft / windows-rs

Rust for Windows
https://kennykerr.ca/rust-getting-started/
Apache License 2.0
10.23k stars 476 forks source link

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

Open MarijnS95 opened 1 month ago

MarijnS95 commented 1 month ago

Suggestion

When creating a single bindings file within another crate, I'd like to use windows-bindgen with the default options, i.e.:

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
riverar commented 1 month ago

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

MarijnS95 commented 1 month ago

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

kennykerr commented 1 month ago

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.

MarijnS95 commented 1 month ago

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

riverar commented 1 month ago

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.

MarijnS95 commented 4 weeks ago

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

kennykerr commented 1 week ago

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