-
Notifications
You must be signed in to change notification settings - Fork 13
Make cargo-gpu a library, usable from build scripts #71
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
a4d7b41
to
51eb0ac
Compare
09edda2
to
af18f7f
Compare
8fc529a
to
fb10e19
Compare
fb10e19
to
fd5da3c
Compare
9557a7e
to
0c0e40b
Compare
crates/cargo-gpu/src/install.rs
Outdated
/// Represents a functional backend installation, whether it was cached or just installed. | ||
#[derive(Clone, Debug)] | ||
#[expect( | ||
clippy::exhaustive_structs, |
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 lint always confuses me. So I could be wrong. But I don't think it's to do with whether new private members will be added. Ideally, if this code is being called by anything outside of the project (let's say from outside the workspace for sake of argument), then it's useful to add #[non_exhaustive]
which prevents external users from doing things that could unexpectedly break backwards compatibility, like struct construction, wildcard match
(for enums), etc.
If the struct is only ever used within the crate, then the better solution here is to use pub (crate)
(this will prevent the lint from triggering).
If the struct is only ever used by rust-gpu
, then we can handle the fallout from "unexpected" new fields. In which case we can change the current reason = ...
to something like, "this struct is only ever used by rust-gpu
".
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 would like people to be able to use the struct update syntax, but #[non_exhaustive]
prevents that, as you could add private fields in the future, which would prevent external crates from using it.
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.
Could you elaborate on the private fields thing? As far as I understand it's about any new fields being added.
I completely agree that struct construction is a nice thing to have. But I think it's important to consider the expectations of library versioning. Basically I think if we're not using #[non_exhaustive]
for public structs then we should take semantic versioning seriously, because of cargo
's flexibility around the patch version. I think it's easier to use #[non_exhaustive]
than to have to carefully consider minor/patch versions all the time.
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.
You can only use struct update syntax on structs where you have access to all members of said struct. For an external crate, that means all members must be public. But if the struct has #[non_exhaustive]
on it, you say that this struct may change in minor revisions, including you potentially adding private fields to it. So the rust devs decided that you cannot use struct update syntax on a struct that is non-exhaustive.
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.
Also we'd have to enforce it on SpirvBuilder as well
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.
Ohh, right that makes sense. Thanks.
So is the basic argument about whether we have a nice developer experience or whether we maintain good semantic versioning? I don't think we can have both, and in general we should lean towards being good crate ecosystem citizens. I don't know how much work it would be to support non_exhaustive
, if it's a lot then yeah that's a fine reason to not worry about it. If there's another reason not to use it then I'm not seeing it yet. Like I say, the lint always confuses me so I'd like to learn.
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.
You'd then have to write this instead: (which isn't a big deal, I just like struct update syntax)
let mut builder = backend.to_spirv_builder(shader_crate, "spirv-unknown-vulkan1.2");
builder.print_metadata = MetadataPrintout::DependencyOnly;
builder.spirv_metadata = SpirvMetadata::Full;
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.
Sure, I get that, and I agree it's much more ergonomic. But the other side is that we're neglecting Rust library conventions. In which case I don't see how developer aesthetics is a relevant point in the context of application maintenance. Here's an overly dramatic way to put it: nice code isn't a reason to unexpectedly break builds.
I don't want to stop you doing this! I just want to make sure I understand.
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 made it #[non_exhaustive]
, though it'd need SpirvBuilder
to also be. Let's do that in a followup
crates/cargo-gpu/src/install.rs
Outdated
impl InstalledBackend { | ||
/// Creates a new `SpirvBuilder` configured to use this installed backend. | ||
#[expect( | ||
clippy::missing_panics_doc, |
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.
Is InstalledBackend
truly completely public? Or just within the crate? If it's just public within the crate then pub (crate)
removes the missing_panic_docs
lint warning.
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.
From the example above, backend: InstalledBackend
.
// install the toolchain and build the `rustc_codegen_spirv` codegen backend with it
let backend = cargo_gpu::Install::from_shader_crate(shader_crate.clone()).run()?;
[...]
backend.to_spirv_builder(shader_crate, "spirv-unknown-vulkan1.2")
I like to give external crates access to the paths, in case they need to hack something. Though you could argue that we may want to #[non_exhaustive]
that one, as in theory external crates shouldn't be touching it, but just call this function on it to create a new SpirvBuilder
.
Oh, you wrote after #75 is merged. Hopefully the comments are relevant anyway. |
I just want to make sure you don't hit the merge button, as it's not required to even get an approved review to merge into non-master branches. |
Requires #75 (and base retarget)
Build script API example:
based on https://github.com/Firestar99/colorbubble/blob/eedd20ecc8155f9be15bc95b0fcd68b5002b94f3/build.rs
closes #67
closes #73