-
Notifications
You must be signed in to change notification settings - Fork 555
Generate proper function impl when cross-compiling #830
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
Conversation
90f769e
to
f74af29
Compare
It looks like you have force-pushed my approach, do note that this has already been rejected. |
Interesting. I really hope this can be reconsidered however. The change here is extremely simple: it only consists of moving the platform selection from codegen-time to compile-time. Without it, the code as it exists is simply wrong. Rust is inherently capable of cross-compilation, and doing so is very important. At current $WORKPLACE, we use linux-based CI to build our windows codebase, as the linux CI machines are much faster than the equivalent windows machine. On github actions, the windows machines can be much, much slower than the equivalent linux machines too, and are additionally more expensive. Having windows-rs unable to cross-compile to windows correctly would make it a non-starter as a |
Exactly. I would have submitted my approach if it wasn't outright rejected. It's a trivial fix at the expense of larger generated code.
For me it's not only about CI, but also about being able to use the vtables and helpers for COM when interfacing with cross-platform libraries like DXC.
Let's hope this extra use-case helps push the topic of |
Yes, my PR aims at making the code cross-compilable (specifically, I'm interested in compiling from a linux host to a windows target), not making the code cross-platform. This PR does help toward fixing #638. Of course, until we have |
In its current form this PR goes out of its way to finalize cross platform support by adding many more lines to the generated output, when all that is necessary for cross-compilation is to remove this cfg check altogether. After all it seems you're cross-compiling and running fine without regenerating |
I kept the check because it was already there. If it's unnecessary, why yes I could remove it entirely. But I assume it's here for a reason 🤷 . |
The |
|
The compiler testing was for the windows-docs-rs repo's bindings crate for stress testing - hence the need for the |
I'm a little rusty 😉 on how rlibs work. I found that the linker complains even when the imports aren't actually used. Unlike in C++. |
I'm curious how that works. If any of those crates link against the
https://doc.rust-lang.org/reference/linkage.html: rlibs are just an intermediate for Rust, linking only happens when an actual binary consumed by the system is generated (executable, cdylib). It indeed seems like linker directives are followed even if the functions could have been omitted from the binary entirely. Maybe that's a |
That is the key. There are now a few things that don't quite work under the proc macro that I have to workaround. This is another one of those. The solution here seems reasonable. You just have to regenerate the bindings crate to satisfy the CI build:
Hopefully we can get some cross-compiling CI builds going some time soon to ensure this keeps working. |
@kennykerr It would indeed be great to have the current solution (akin to the proposed fix for #770) as it allows me to run I can submit master...MarijnS95:unix-bindings-cfg if that makes things easier/quicker, too. |
Sure I don't mind, but let's give @roblabla a chance to chime in. |
When cross-compiling, using cfg!() in a build script or proc macro will not have the intended behavior: It will check the cfg against the build host instead of the build target. The easiest way to avoid this issue is to use CARGO_CFG_* environment variables, but those are only present for build scripts, not for proc macros. So to work around the issue, we fold the #[cfg] *inside* the generated code so that it is checked when compiling the generated code.
fd91a05
to
1287e15
Compare
Regenerated the bindings.rs file and rebased on master. This should be good to go I think? |
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.
Thanks!
When testing
cfg!(windows)
within a proc macro/build script, it will resolve to true if the build host is windows, and false otherwise.Here, what we want is to check if the target is windows or not.
In order to achieve this, the environment variables.CARGO_CFG_*
should be used. See https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scriptsIt turns out checking the environment does not work for proc macros. So instead, we delegate the selection from codegen-time to build-time, by moving the cfg inside the
quote!
call.I have a setup that cross-compiles windows-rs using an LLVM toolchain and the Windows SDK libraries. Because of this check, the resulting binaries all panic with "Unsupported target os".