-
Notifications
You must be signed in to change notification settings - Fork 69
Description
Currently, to the best of my knowledge, cargo component generates a src/bindings.rs file using a version of wit-bindgen baked directly into the executable cargo-component itself. Running cargo component new generates a project that depends on wit-bindgen-rt at a matching version of what cargo-component has baked in to itself.
This is problematic to the development of wit-bindgen, unfortunately, because the generated code using wit-bindgen 0.A.0 generally requires wit-bindgen-rt 0.A.0 as well, and you can't mix and match versions. Mismatched versions can arise relatively easily with cargo-component in two situations:
- An older project might update to using a newer
cargo-componentexecutable, meaning that theCargo.tomldepends on an olderwit-bindgen-rtwhile the executable generates bindings with a newerwit-bindgenversion. - An older project might update
wit-bindgen-rtbut fail to updatecargo-component, producing the inverse problem where an olderwit-bindgenis used with a newerwit-bindgen-rt.
This is coming up as I'm doing refactoring in wit-bindgen and shuffling things around, and ideally I'd prefer to not break cargo component users because at this time if anything is added to wit-bindgen-rt then users will break.
As an alternative, what I might recommend is to instead have cargo component manage WIT, not generated source code. The basic idea is that cargo component would generate-and-manage src/bindings.wit instead of src/bindings.rs. The template for cargo component new would add a dependency on wit-bindgen but critically wouldn't actually generate any code. For example the generated file might look like:
wit_bindgen::generate!("./src/bindings.wit");
fn main() {
println!("hello!");
}This should be more idiomatic in terms of wit-bindgen usage where it's "just" a call to the generate! macro with various options. The key difference is that the input *.wit is completely managed by cargo component and handles things like dependencies and such which wit-bindgen otherwise doesn't do.
My hope is that this wouldn't break things like IDE integration workflows as they in theory already need to work with procedural macros. The upside though is that the cargo component executable wouldn't even need to depend on wit-bindgen itself because it doesn't generate any Rust code. Instead it only generates a reference to wit-bindgen and then a macro invocation. The WIT management all remains in cargo component, however.
This would additionally solve the problem of updating/changing wit-bindgen as, after inception, it's a per-project decision of when to update wit-bindgen which is orthogonal from using cargo component as a build tool.