-
Notifications
You must be signed in to change notification settings - Fork 460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Regenerate windows sys bindings #1132
Conversation
cc @thomcc the newer version of windows-bindgen needs a new dependency windows-targets, it is very simple and just include a few |
https://kennykerr.ca/rust-getting-started/understanding-windows-targets.html There's also documentation for windows-targets |
Upon further investigation, windows-targets pull in one target-specific dependency https://docs.rs/crate/windows-targets/latest/source/Cargo.toml.orig which include a main() {
let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
println!(
"cargo:rustc-link-search=native={}",
std::path::Path::new(&dir).join("lib").display()
);
} It's unfortunate that a build-script is necessary for the windows linking to work, as it bundles a binary for that specific target 😂 |
Looks like windows-targets have a cfg
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unfortunate (the dependency seems kind of pointless) but if we have no choice then we have no choice.
I'd like to know how much this adds to our compile-time before landing this. It's not like the windows APIs that we use have changed so I'm wondering if we really need it. If the compile-time overhead is very small then it doesn't matter though. |
I checked our own CI for reference Before: https://github.com/rust-lang/cc-rs/actions/runs/9738532295 After: https://github.com/rust-lang/cc-rs/actions/runs/9817318956 There isn't much difference there in CI, mostly jitter due to GHA being overloaded |
On my (newly set up) windows machine this adds 0.2s-0.4s, around 30% on a crate with a build script that just runs cc::Build::new() and nothing else. That sucks but is not enough for me to really want to fight this. That said, given that our windows bindings have not changed and are unlikely to change soon, maybe we should just wait on this until we actually need to update it? |
What if you add (though tbh a fixed overhead of 0.2s-0.4s does not sound large to me compared to real-world usage of cc, especially as windows-targets is a foundational crate that is likely to be included by other deps in practice) |
I think setting it should reduce it to <0.1 as it removes the build-script and extra crate to compile. Though that can only be set by users of cc though, we can't enable it for users of cc via feature, and setting would affect the normal-dependencies as well. |
With that said, I'm also curious why windows-bindgen start depending on windows-targets, and why there is no flag to disable it. |
Btw, I just think of a way to workaround this problem. We could add this to the windows_sys.rs mod windows_targets {
macro_rules! link { ... }
} Then we won't need the extra dependencies |
That is more or less what the standard library does |
Sorry, are you referring to define of our own |
Yes |
Thanks I see, so it's a reasonable approach to this problem. Would update this PR to use it |
Sure. Though implementing it manually may be a greater maintenance burden as it's not a stable interface. Personally I'm not convinced it's worth it but I also wouldn't object to it. |
Yeah, looking at the previous generated windows_sys binding, I think it's relatively simple. |
To avoid the additional dependencies and build-script. Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
use `fs::read_to_string` Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
cc @ChrisDenton @thomcc I've updated the PR, can you review it please? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice.
Avoid text replacing Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
for dll_name in dll_names { | ||
write!(&mut f, r#"#[link(name = "{dll_name}")]"#).unwrap(); | ||
f.write_all("\n".as_bytes()).unwrap(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the import library is often named the same as the DLL, this isn't always true (e.g. there's a Synchronization.lib but not synchronization.dll). This doesn't affect cc-rs at the moment but it could do in the future. I wonder if it would be better to maintain a manual mapping, even if this is more verbose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this isn't always true (e.g. there's a Synchronization.lib but not synchronization.dll)
How many of these cases are there?
If there're only a few, then I could hard code it here, so that people don't have to modify the macro_rules!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Windows API is sprawling so it's hard to answer definitely but it seems like there are a lot. Complicating matters further are functions like GetFileVersionInfoExA
which is exported from version.dll and there is version.lib but the lib doesn't contain that function. I don't know how many of them there are but cases like that would need to be handled specially by matching on the function name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively we could bump the msrv up to 1.65 and just use raw-dylib. That would completely side-step any issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively we could bump the msrv up to 1.65 and just use raw-dylib. That would completely side-step any issues.
I'm ok with raw-dynlib, but the problem is that we can't enable it just cc-rs, it's not a feature but a cfg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Windows API is sprawling so it's hard to answer definitely but it seems like there are a lot.
Hmmm, I think it's fine for now, it's not like we add new windows sys binding very often.
Thank you so much, and I will merge it as now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with raw-dynlib, but the problem is that we can't enable it just cc-rs, it's not a feature but a cfg.
It's not a cfg if we implement in a macro ourselves. Then it just a #[link ... kind="raw-dylib"]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm I didn't know we could do that, would open another PR.
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( | ||
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't | ||
// have in this repo. So instead we always link kernel32.lib and add the rest of the import | ||
// libraries below by using an empty extern block. This works because extern blocks are not | ||
// connected to the library given in the #[link] attribute. | ||
#[link(name = "kernel32")] | ||
extern $abi { | ||
$(#[link_name=$link_name])? | ||
pub fn $($function)*; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example:
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( | |
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't | |
// have in this repo. So instead we always link kernel32.lib and add the rest of the import | |
// libraries below by using an empty extern block. This works because extern blocks are not | |
// connected to the library given in the #[link] attribute. | |
#[link(name = "kernel32")] | |
extern $abi { | |
$(#[link_name=$link_name])? | |
pub fn $($function)*; | |
} | |
("advapi32.dll" $($tt:tt)*) => (link_macro!{internal "AdvAPI32" $($tt)*}); | |
("kernel32.dll" $($tt:tt)*) => (link_macro!{internal "kernel32" $($tt)*}); | |
("ole32.dll" $($tt:tt)*) => (link_macro!{internal "Ole32" $($tt)*}); | |
("oleaut32.dll" $($tt:tt)*) => (link_macro!{internal "OleAut32" $($tt)*}); | |
($dll:literal $($tt:tt)*) => (compile_error!("unknown dll")); | |
(internal $library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( | |
#[link(name = $library)] | |
extern $abi { | |
$(#[link_name=$link_name])? | |
pub fn $($function)*; | |
} | |
) |
Thank you very much for reviewing! |
Automatically regenerated in CI